이 코드가 중복이 아닌 표준 규칙을 따르나요? 다른 사람들이 더 이해하기 쉽게 만들 수있는 방법은 무엇입니까?
Java 소개 책의 연습 문제입니다.
무작위로 단어를 생성하고 사용자에게 한 번에 한 글자를 추측하도록하는 행맨 게임입니다. 단어의 각 글자는 별표로 표시됩니다. 사용자가 정확한 추측을하면 실제 글자가 표시됩니다. 단어, 누락 수를 표시합니다.
내 프로그램 :
import java.util.Arrays; import java.util.Scanner; public class Hangman{ public static void main(String[] args) { String[] words = {"writer", "that", "program"}; // Pick random index of words array int randomWordNumber = (int) (Math.random() * words.length); // Create an array to store already entered letters char[] enteredLetters = new char[words[randomWordNumber].length()]; int triesCount = 0; boolean wordIsGuessed = false; do { // infinitely iterate through cycle as long as enterLetter returns true // if enterLetter returns false that means user guessed all the letters // in the word e. g. no asterisks were printed by printWord switch (enterLetter(words[randomWordNumber], enteredLetters)) { case 0: triesCount++; break; case 1: triesCount++; break; case 2: break; case 3: wordIsGuessed = true; break; } } while (! wordIsGuessed); System.out.println("\nThe word is " + words[randomWordNumber] + " You missed " + (triesCount -findEmptyPosition(enteredLetters)) + " time(s)"); } /* Hint user to enter a guess letter, returns 0 if letter entered is not in the word (counts as try), returns 1 if letter were entered 1st time (counts as try), returns 2 if already guessed letter was REentered, returns 3 if all letters were guessed */ public static int enterLetter(String word, char[] enteredLetters) { System.out.print("(Guess) Enter a letter in word "); // If-clause is true if no asterisks were printed so // word is successfully guessed if (! printWord(word, enteredLetters)) return 3; System.out.print(" > "); Scanner input = new Scanner(System.in); int emptyPosition = findEmptyPosition(enteredLetters); char userInput = input.nextLine().charAt(0); if (inEnteredLetters(userInput, enteredLetters)) { System.out.println(userInput + " is already in the word"); return 2; } else if (word.contains(String.valueOf(userInput))) { enteredLetters[emptyPosition] = userInput; return 1; } else { System.out.println(userInput + " is not in the word"); return 0; } } /* Print word with asterisks for hidden letters, returns true if asterisks were printed, otherwise return false */ public static boolean printWord(String word, char[] enteredLetters) { // Iterate through all letters in word boolean asteriskPrinted = false; for (int i = 0; i < word.length(); i++) { char letter = word.charAt(i); // Check if letter already have been entered bu user before if (inEnteredLetters(letter, enteredLetters)) System.out.print(letter); // If yes - print it else { System.out.print("*"); asteriskPrinted = true; } } return asteriskPrinted; } /* Check if letter is in enteredLetters array */ public static boolean inEnteredLetters(char letter, char[] enteredLetters) { return new String(enteredLetters).contains(String.valueOf(letter)); } /* Find first empty position in array of entered letters (one with code \u0000) */ public static int findEmptyPosition(char[] enteredLetters) { int i = 0; while (enteredLetters[i] != "\u0000") i++; return i; } }
로그 작업 :
(Guess) Enter a letter in word **** > a (Guess) Enter a letter in word **a* > t (Guess) Enter a letter in word t*at > q q is not in the word (Guess) Enter a letter in word t*at > t t is already in the word (Guess) Enter a letter in word t*at > b b is not in the word (Guess) Enter a letter in word t*at > h (Guess) Enter a letter in word that The word is that You missed 2 time(s)
댓글
- 블록 스키마 일러스트레이션 이미지와 함께 무료 이미지 호스팅에 링크를 첨부하면 좋을까요? 내 프로그램의 논리. ' 작동 방식이 명확하지 않거나 ' 필요하지 않기 때문입니까?
- 순서도 등은 일을 증가시킬 것입니다 당신이하고있는 일에 대한 ' 이해. '는 항상 좋은 일입니다.
- '이 (가) 중복을 제거하고 더 간결하게 만드는 방법. 그래도 따라하기가 조금 어렵습니다. 더 설명적인 메소드 이름이 도움이 될 수 있습니다 (가장 좋은 문서는 읽기 쉬운 코드입니다!)
- 코드가 너무 복잡해서 학생이 무엇을 읽고 정확히 알기 어렵 기 때문에 무슨 일이 일어나고 있는지 설명 할 필요가 없습니다. '가 진행 중입니다. 감사합니다.
답변
매직 넘버 : 0,1에 대한 정의를 옮기는 것이 좋습니다. 2,3을 enum
또는 final
필드에 추가하여 의미있는 이름으로 참조 할 수 있습니다. 예 : final int LETTER_NOT_IN_WORD = 0
또는 enum HangmanGuess { LETTER_NOT_IN_WORD }
중복 : findEmptyLetters
및 inEmptyLetters
는 동일합니다. char[]
에서 char
를 찾고 있습니다. . 다음과 같이 리팩터링 할 수 있습니다.
/* Check if letter is in enteredLetters array */ public static boolean inEnteredLetters(char letter, char[] enteredLetters) { return indexOf(letter, enteredLetters) >= 0; } /* Find first empty position in array of entered letters (one with code \u0000) */ public static int findEmptyPosition(char[] enteredLetters) { return indexOf("\u0000", enteredLetters) } /* Determine the index in {@code vals} where {@code ch} exists. Returns -1 if {@code ch} is not in {@code vals}. */ public static int indexOf(char ch, char[] vals) { return Arrays.asList(vals).indexOf(Character.valueOf(ch)); }
또한 현재 구현에서는 findEmptyPosition
를 지적해야합니다. 빈 위치가없는 경우 n
를 반환합니다. 여기서 n
는 enteredLetters.length + 1
입니다. 이것이 원하는 기능인지 잘 모르겠습니다.
답변
첫 번째 (작은) : Math.random()
보다 Random
를 사용하세요. 이 모범 사례 게시물을 참조하세요.
do {} while () 내부의 첫 번째 댓글과 스위치는 개인적으로 매우 혼란 스럽습니다. enterLetter()
는 true
또는 false
및 대부분의 새로운 프로그래머조차도 조건이 충족 될 때까지 반복하는 동안해야 할 일을 알고 있습니다. 0-3이 무엇을 나타내는 지 설명하는 것이 더 도움이됩니다. 프로덕션 코드이거나 더 복잡한 경우 Enum을 사용하면 훨씬 더 쉽게 이해할 수 있습니다.
enterLetter()
내부에서 int emptyPosition = findEmptyPosition(enteredLetters);
가 사용되는 else if
에 대한 호출입니다. 사용할 때까지 메모리 할당을 방지 할뿐만 아니라 더 읽기 쉽습니다 (원하는 경우 emptyPosition
변수를 제거하고 참조 내에서 함수를 호출 할 수 있습니다. , 그러나 그것은 의미 론적입니다).