You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Nim游戏项目咨询:玩家参与与战绩记录及类设计疑问

解答你的Nim游戏项目疑问 & 代码优化建议

Hey there! Let's tackle your questions step by step and help you polish your Nim game implementation.

问题1:玩家操作的合理性与得分存储位置

关于NimPlayer类的职责

目前你把玩家列表(playerList)和创建玩家的逻辑放在NimPlayer类里,其实这有点违背单一职责原则——NimPlayer应该只负责封装玩家自身的属性和行为(比如用户名、姓名、游戏次数、胜场数),而玩家的管理(添加、删除、查找)应该交给Nimsys来处理,这样代码的职责划分更清晰,也更容易维护。

游戏次数与得分的存储位置

游戏次数和得分是每个玩家的专属属性,所以完全应该放在NimPlayer类里,而不是Nimsys。你可以在NimPlayer中添加两个私有字段:int playedGames(游戏次数)和int wonGames(获胜次数),再提供对应的getter方法,以及用于更新这些数据的方法(比如incrementPlayedGames()、incrementWonGames())。

问题2:如何在NimGame类中引入玩家

NimGame作为游戏逻辑的载体,需要明确知道参与游戏的两名玩家。最合理的方式是通过构造方法将玩家对象传入,同时还可以传入游戏的初始石头数、最大移除石头数,这样游戏初始化时就能拿到所有必要的参数。

具体来说:

  • 在NimGame类中定义两个私有成员变量:NimPlayer player1和NimPlayer player2
  • 编写构造方法:public NimGame(NimPlayer player1, NimPlayer player2, int initialStones, int maxRemoval)
  • 这样在Nimsys的startgame命令处理逻辑中,找到对应的玩家对象后,就可以创建NimGame实例并启动游戏。

代码优化后的关键片段示例

1. 重构后的NimPlayer类

public class NimPlayer {
    private String userName;
    private String familyName;
    private String givenName;
    // 新增游戏统计属性
    private int playedGames;
    private int wonGames;

    public NimPlayer(String userName, String familyName, String givenName) {
        this.userName = userName;
        this.familyName = familyName;
        this.givenName = givenName;
        this.playedGames = 0;
        this.wonGames = 0;
    }

    // 更新游戏统计的方法
    public void incrementPlayedGames() {
        this.playedGames++;
    }

    public void incrementWonGames() {
        this.wonGames++;
    }

    // Getter和Setter方法
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getFamilyName() {
        return familyName;
    }

    public void setFamilyName(String familyName) {
        this.familyName = familyName;
    }

    public String getGivenName() {
        return givenName;
    }

    public void setGivenName(String givenName) {
        this.givenName = givenName;
    }

    public int getPlayedGames() {
        return playedGames;
    }

    public int getWonGames() {
        return wonGames;
    }
}

2. 重构Nimsys的玩家管理逻辑

把玩家列表移到Nimsys中,用List代替数组,更灵活:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Nimsys {
    // 用List存储玩家,替代原来的static数组
    private static List<NimPlayer> playerList = new ArrayList<>();

    // 查找玩家的工具方法
    private static NimPlayer findPlayer(String userName) {
        for (NimPlayer player : playerList) {
            if (player.getUserName().equals(userName.trim())) {
                return player;
            }
        }
        return null;
    }

    public static String[] splitName(String inName) {
        String[] splittedLine = inName.split(",");
        if (splittedLine.length == 3) {
            String userName = splittedLine[0].trim();
            String familyName = splittedLine[1].trim();
            String givenName = splittedLine[2].trim();
            return new String[]{userName, familyName, givenName};
        }
        return null;
    }

    public static String[] splitData(String dataIn) {
        String[] splittedLine = dataIn.split(",");
        if (splittedLine.length == 4) {
            String initialStone = splittedLine[0].trim();
            String stoneRemoval = splittedLine[1].trim();
            String player1 = splittedLine[2].trim();
            String player2 = splittedLine[3].trim();
            return new String[]{initialStone, stoneRemoval, player1, player2};
        }
        return null;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (true) {
            System.out.print('$');
            String commandin = in.next().trim();

            switch (commandin) {
                case "addplayer":
                    String inName = in.nextLine().trim();
                    String[] name = splitName(inName);
                    if (name != null) {
                        String userName = name[0];
                        // 先检查玩家是否存在
                        if (findPlayer(userName) != null) {
                            System.out.println("The player already exists");
                            break;
                        }
                        playerList.add(new NimPlayer(userName, name[1], name[2]));
                        System.out.println("The player has been created.");
                    } else {
                        System.out.println("Not Valid! Please enter again!");
                    }
                    break;

                case "removeplayer":
                    String removeUserName = in.nextLine().trim();
                    if (removeUserName.isEmpty()) {
                        // 处理删除所有玩家的逻辑
                        System.out.println("Are you sure you want to remove all players? (y/n)");
                        String confirm = in.next().trim();
                        if (confirm.equalsIgnoreCase("y")) {
                            playerList.clear();
                            System.out.println("Remove all the players");
                        }
                    } else {
                        NimPlayer playerToRemove = findPlayer(removeUserName);
                        if (playerToRemove != null) {
                            playerList.remove(playerToRemove);
                            System.out.println("Remove successfully!");
                        } else {
                            System.out.println("The player does not exist");
                        }
                    }
                    break;

                case "editplayer":
                    String editInput = in.nextLine().trim();
                    String[] editData = editInput.split(",");
                    if (editData.length == 3) {
                        String userName = editData[0].trim();
                        NimPlayer playerToEdit = findPlayer(userName);
                        if (playerToEdit != null) {
                            playerToEdit.setFamilyName(editData[1].trim());
                            playerToEdit.setGivenName(editData[2].trim());
                            System.out.println("Edit successfully");
                        } else {
                            System.out.println("The player does not exist.");
                        }
                    } else {
                        System.out.println("Invalid input! Please enter again.");
                    }
                    break;

                case "displayplayer":
                    for (NimPlayer player : playerList) {
                        System.out.printf("%s,%s,%s\n", player.getUserName(), player.getFamilyName(), player.getGivenName());
                    }
                    break;

                case "startgame":
                    String gameData = in.nextLine().trim();
                    String[] data = splitData(gameData);
                    if (data != null) {
                        int initialStones = Integer.parseInt(data[0]);
                        int maxRemoval = Integer.parseInt(data[1]);
                        NimPlayer p1 = findPlayer(data[2]);
                        NimPlayer p2 = findPlayer(data[3]);

                        if (p1 == null || p2 == null) {
                            System.out.println("One of the players does not exist. Please enter again");
                            break;
                        }

                        // 创建NimGame实例并启动游戏
                        NimGame game = new NimGame(p1, p2, initialStones, maxRemoval);
                        game.start();
                    } else {
                        System.out.println("Invalid game data! Please enter again.");
                    }
                    break;

                case "exit":
                    in.close();
                    return;

                default:
                    System.out.println("Unknown command! Please try again.");
            }
        }
    }
}

3. 完善后的NimGame类

import java.util.Scanner;

public class NimGame {
    private NimPlayer player1;
    private NimPlayer player2;
    private int stoneBalance;
    private int maxRemoval;
    private Scanner scanner = new Scanner(System.in);

    public NimGame(NimPlayer player1, NimPlayer player2, int initialStones, int maxRemoval) {
        this.player1 = player1;
        this.player2 = player2;
        this.stoneBalance = initialStones;
        this.maxRemoval = maxRemoval;
    }

    public void start() {
        do {
            System.out.println("Initial stone count: " + stoneBalance);
            System.out.println("Maximum stone removal: " + maxRemoval);
            System.out.println("Player 1: " + player1.getUserName());
            System.out.println("Player 2: " + player2.getUserName());

            // 标记当前回合的玩家
            NimPlayer currentPlayer = player1;
            boolean gameOver = false;

            // 更新两位玩家的游戏次数
            player1.incrementPlayedGames();
            player2.incrementPlayedGames();

            while (stoneBalance > 0) {
                printStones();
                System.out.println(currentPlayer.getUserName() + "'s turn - remove how many?");
                int takeStone = scanner.nextInt();

                // 验证输入合法性
                while (takeStone <= 0 || takeStone > maxRemoval || takeStone > stoneBalance) {
                    System.out.println("Invalid, you need to remove between 1 and " + maxRemoval + " stones, or no more than remaining stones. Please enter again.");
                    takeStone = scanner.nextInt();
                }

                stoneBalance -= takeStone;

                if (stoneBalance <= 0) {
                    // 当前玩家拿了最后一颗石头,输掉游戏,另一方获胜
                    NimPlayer winner = currentPlayer == player1 ? player2 : player1;
                    winner.incrementWonGames();
                    System.out.println("Game Over\n" + winner.getUserName() + " wins!\n");
                    gameOver = true;
                    break;
                }

                // 切换玩家
                currentPlayer = currentPlayer == player1 ? player2 : player1;
            }

            // 询问是否继续游戏
            scanner.nextLine(); // 读取换行符
            System.out.println("Do you want to play again (Y/N):");
            String playAgain = scanner.nextLine().trim();
            if (!playAgain.equalsIgnoreCase("Y")) {
                break;
            }

            // 重置石头数量为初始值
            stoneBalance = Integer.parseInt(Nimsys.splitData(scanner.nextLine())[0]);

        } while (true);
    }

    private void printStones() {
        System.out.print(stoneBalance + " stones left:");
        for (int i = 0; i < stoneBalance; i++) {
            System.out.print(" *");
        }
        System.out.println();
    }
}

一些额外的小提示

  • 使用switch-case替代多个if判断命令,代码会更整洁易读
  • 用ArrayList替代固定大小的数组存储玩家,避免容量限制问题
  • 提取findPlayer工具方法,减少重复代码
  • 游戏结束后记得更新玩家的游戏次数和胜场数

内容的提问来源于stack exchange,提问作者Woden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:47:38