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
相关产品推荐
相关产品推荐

