首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java hangman游戏

Java hangman游戏
EN

Code Review用户
提问于 2021-06-25 10:15:43
回答 1查看 166关注 0票数 2

这是我实现的经典的“汉曼”猜字游戏。

LePendu类:

代码语言:javascript
复制
public class LePendu {


    // Variable

    public static int NB_ERREURS_MAX=10;
    static ArrayList<Character> playerGuess = new ArrayList<Character>();
    static ArrayList <String> wrongGuess = new ArrayList<String>();
    static ArrayList <String> playerWord = new ArrayList<String>();
    static String penduDessin [][] = new String[10][10];

    // Le Main :

    public static void main(String args[]) throws FileNotFoundException {
        Scanner sc = new Scanner (new File("C:/Users/admin/pendu.txt"));
        Scanner charP = new Scanner (System.in);
        while(sc.hasNext()) {
            playerWord.add(sc.nextLine());
        }
        
        // Intitialisation Hangman :
        initialize2dArray();

        // Wordchoice :
        Random motAleatoire = new Random(); 
        String word = playerWord.get(motAleatoire.nextInt(playerWord.size()));

        // Loop for the game :
        int chance = 0;
        while(true) {              
            penduEntier();
            drawPendu(chance);
                    
            if (chance>word.length()) {
                System.out.println("Perdu!!!!");
                break;
            }
                            
            displayWord(word, playerGuess);
            if (!getPlayerChar(charP, word, playerGuess)) {
                chance ++;
            };
            if(displayWord(word, playerGuess)) {
                System.out.println("Victoire");
                break;
            } 
            System.out.println("Tentez votre chance pour le mot");
            if(charP.nextLine().equals(word)) {
                System.out.println("Victoire");
                break;
            } else {
                System.out.println("Mot incorrect, veuillez réessayer");
            }
        }        
    }


    // Méthode getPlayerChar :
    private static boolean getPlayerChar(Scanner charP, String word, ArrayList<Character> playerGuess) {
        System.out.println("Entrez une lettre svp");        
        String charPlayer = charP.nextLine();
        playerGuess.add(charPlayer.charAt(0));
        
        return word.contains(charPlayer);
    }

    // Méthode displayWord :
    private static boolean displayWord(String word, ArrayList<Character> playerGuess) {
        int count = 0;
        for (int i = 0;i<word.length();i++) {
            if(playerGuess.contains(word.charAt(i))) {
                System.out.print(word.charAt(i));
                count++;
            }
            else {
                System.out.print("-");
            }
        }
        System.out.println("");
        return (word.length() == count);
    }

    // Draw Hangman Methode :
    public static void penduEntier(){       
        // Loop through the entire 2D array to display Hangman image
        for (int row = 0; row < 10; row++) {
            for (int column = 0; column < 10; column++) {
                System.out.print(penduDessin[row][column]);
            }
            System.out.println();
        }
    }


    // Tableau 2D Hangman :
    public static void drawPendu(int chance) {      
        // The hangman will be erected from bottom to top, that is first gallos
        // base will be made and then step by step hangman will be generated.       
        switch(chance) {            
            // we do not need add break in the cases because when players misses
            // word after 8 chances then complete image of hangman is created.
            case 8:
                // Create legs of man
                penduDessin[6][6] = "/";
                penduDessin[7][5] = "/";
                penduDessin[6][8] = "\\";
                penduDessin[7][9] = "\\";
                
            case 6:
                // Create hands of man
                penduDessin[4][6] = "/";
                penduDessin[5][5] = "/";
                penduDessin[4][8] = "\\";
                penduDessin[5][9] = "\\";
                
            case 5:
                // Create tummy of man
                for(int i = 3; i <= 5; i++)             
                    penduDessin[i][7] = "|";
                
            case 4:
                // Create eyes and nose of man
                penduDessin[2][6] = "*";
                penduDessin[2][7] = "!";
                penduDessin[2][8] = "*";
                
            case 3:             
                // Create face of man
                penduDessin[2][5] = "(";
                penduDessin[2][9] = ")";                
                
            case 2:             
                // Create gallos
                for(int i = 3; i <= 7; i++)             
                    penduDessin[0][i] = "#";
                penduDessin[1][7] = "#";
                
            case 1:
                // Create gallos 
                for(int i = 0; i <= 9; i++)             
                    penduDessin[i][3] = "|";            
                                
            case 0:
                // Create base of gallos
                for(int i = 0; i <= 8; i++)             
                    penduDessin[8][i] = "_";            
            break;
            
            default:
                break;
                
        }
    }


    // Initialize the hangman with space :
    public static void initialize2dArray()
    {
        // Initialize the 2d array with blank spaces before printing the 
        // actual image of hangman.
        for (int row = 0; row < 10; row++)
        {
            for (int column = 0; column < 10; column++)
            {
                penduDessin[row][column] = " ";
            }           
        }
    }
    
}

谢谢你的帮助

EN

回答 1

Code Review用户

发布于 2021-06-28 05:53:23

次要问题:语言

源代码是用英语写的。我不会说英语,其他很多人也不会说英语。这可能是这次审查尚未得到答案的原因之一。

  • NB_ERREURS_MAX
  • String penduDessin
  • Random motAleatoire
  • penduEntier()

次要问题:硬编码字符串

如前所述,源代码是英文的,同样适用于所编写的文本。要处理这样的问题,您应该使用提供英文名称的常量(但是具有外国内容)。

而不是

System.out.println("Victoire");

你定义了一个常数

代码语言:javascript
复制
static final String VICTORY_MESSAGE = "Victoire";
static final String FAIL_MESSAGE = "Perdu!!!!";

...

if (chance>word.length()) {
    System.out.println(FAIL_MESSAGE);
    break;
}

比每个人都能理解外文。

另一个重要的问题是,这将是一个更“可维护”的代码,因为您将拥有所有的字符串在一个地方,并可以轻松地翻译它们。(open for enhancements是固体的一部分)

次要问题:C样式数组初始化

在java中,我们直接在数组类型上声明数组,而不是String penduDessin [][],而是使用String[][] penduDessin

问题:单一责任

您的方法displayWord()返回一个布尔值,因为它做两件事而不是一件事。它

  • 显示单词
  • 检查这个词是否已被破解

把他们分开!

同样适用于getPlayerChar(),此方法

  • 处理用户输入
  • 验证它是否与秘密单词匹配。

主要问题:对象和方法

您正在使用java,但是您的代码不是面向对象的,而是面向过程的。这导致了很多难以读懂的代码。

使用对象:这是我首先想到的,但你可以做出不同的决定:

  • HangmanGame (游戏逻辑)
  • HangmanWord
  • HangmanDisplay
  • 字典
  • 字典阅读器
  • InputReader

如果以这种方式拆分代码,您的代码就会更加可读性(可维护性)。

代码语言:javascript
复制
public static void main(String args[]){
    Dictionary dic = new Dictionary(new FileDictReader().read(DICT_FILENAME));
    HangmanGame game = new HangmanGame(dict, new PlayerInputReader(), new HangmanDisplay());
    game.start();
}

这样做,您可以清楚地定位要对象的任务,例如,从给定的列表中获取一个单词:

代码语言:javascript
复制
HangmanWord wordToGuess = new HangManWord(dictionary.getRandom());

因此,我们对字典有一个单一的责任:提供单词!

另一个例子是字典阅读器:

从一个源(文件)读取字典,它的异常处理将由DictionaryReader完成。您还可以添加另一个允许您读取URL或任何其他源的读取器。这样做的好处是,你不必为新读者而修改词典。

专业:从显示

中分离数据

您应该为您的游戏状态提供数据对象:HangmanWord。每当您向HangmanWord添加信函时,此状态将发生更改。

HangmanWord是一个数据对象,可以提供玩游戏所需的所有相关信息。

  • HangmanWord.isSolved()
  • HangmanWord.isFailed()
  • HangmanWord.getAmountFailures()
  • HangmanWord.addCharacter()
  • HangmanWord.getHiddenWord()
  • HangmanWord.getGuesses()

这样你的时间循环看起来就更容易了

after-Thoughts

你应该尽量避免硬耦合,但是绞刑是一个挑战。要避免HangmanWordHangmanPrinter之间的直接依赖是不容易实现的,因为它们很难通过HangmanWord的大量故障(因此也就是机库的形状)来连接。您已经通过使用NB_ERREURS_MAX检测到了该依赖关系--我非常希望看到一个解决方案,在该解决方案中,您(任何人)解决了此依赖关系^_^。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/263448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档