首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有坚实原理的Tic脚趾

具有坚实原理的Tic脚趾
EN

Code Review用户
提问于 2017-10-08 16:08:57
回答 2查看 655关注 0票数 4

我正在制作一个Tic脚趾游戏,可以在控制台上玩,或者对抗另一个人,或者简单的人工智能。虽然有点粗糙,但很管用。我所关心的是它对坚实和其他设计原则的坚持程度,因为这是我第一次在实践中使用它们。我希望能回顾一下我的课程的结构和任何建议。我共享一个从GitHub链接,因为这里有太多的代码来发布所有的东西。

这些是一些最大的课程,给我一种不安的感觉。

GameBoard.class -拥有棋盘并保存玩家的标志

代码语言:javascript
运行
复制
package board;

import java.util.ArrayList;


public class GameBoard {

    private Cell[] board;

    private ArrayList<Integer> availableSpots;

    public GameBoard(int n) {
        availableSpots = new ArrayList<Integer>();

        //the game board
        board = new Cell[n];
        for (int i = 0; i < n; i++) {
            board[i] = new Cell();
        }

        //list of initial open cells
        for (int i = 0; i < 9; i++) {
            availableSpots.add(i);
        }
    }


    public Cell[] getBoard() {
        return board;
    }

    public void addMarker(int n, String s) {
        if (availableSpots.contains(n)) {
            board[n].setMarker(s);
            removeSpotFromList(n);
            //System.out.println(availableSpots.size());
        }
        else {
                System.out.println("Cell not available");

            }
    }

    public String getCellValue(int n) {
        return board[n].getMarker();
    }

    public ArrayList<Integer> getAvailableSpots() {
        return availableSpots;
    }

    //remove number from arraylist
    public void removeSpotFromList(int n) {
        availableSpots.set(n, null);
        availableSpots.trimToSize();
        for (int i=0; i<availableSpots.size(); i++) {
            //System.out.println(availableSpots.get(i) + ", ");
        }
    }

}

Game.class -玩家之间的切换和每个回合的呼叫

代码语言:javascript
运行
复制
import board.GameBoard;
import board.PrintBoard;
import consuleInput.InputReader;
import import players.Playable;
import players.PlayerGroup;


public class Game {

    public static void play() {
        Modes modes =  new Modes();
        InputReader ir = new InputReader();
        GameBoard bg = new GameBoard(9);
        PrintBoard pb = new PrintBoard();
        PlayerGroup pg = new PlayerGroup();
        GameStateChecker gsc = new GameStateChecker();
        System.out.println("choose a mode:");
        System.out.println("1. Player vs player");
        System.out.println("2. player v computer");
        System.out.println("3. computer vs computer");

        int mode =  ir.toIntegerReader("type below");

        modes.chooseMode(mode, pg);

        pb.print(bg);

        int counter = 9;
        Playable currentPlayer;
        boolean hasWinner = false;
        int player = 0;
        //int choice;
        do{
            currentPlayer = pg.getPlayer(player);
            //int choice = ir.toIntegerReader("pick a square (0-8):");
            bg.addMarker(currentPlayer.playerMove(bg.getAvailableSpots()), currentPlayer.getMarker());
            pb.print(bg);
            hasWinner = gsc.checkPatterns(bg, currentPlayer);
            //System.out.println("is there a winner " + hasWinner);
            counter--;
            if (player == 0) {
                player = 1;
            }
            else {
                player = 0;
            }
            /*
            currentPlayer = pg.getPlayer(1);
            choice = ir.toIntegerReader("pick a square (0-8):");
            bg.addMarker(choice, currentPlayer.getMarker());
            pb.print(bg);
            hasWinner = gsc.checkPatterns(bg, currentPlayer);
            counter--;
            */
        }
        while (!hasWinner);


    }
}
EN

回答 2

Code Review用户

发布于 2017-10-09 09:59:28

除了RobAu的评论外,我认为addMarker方法可以简化为:

代码语言:javascript
运行
复制
board[n].setMarker(s);

通过将单元格的可用性检查委托给Cell类。我认为最好从IllegalArgumentException定义自己的异常。

代码语言:javascript
运行
复制
public void setMarker(String marker) {
    if(!marker.equals(" "))
        throw new CellIsNotAvailableException();
    this.marker = marker;
}

我要指出的另一件事是命名方法和变量的方式。人们应该始终正确地命名它们的方法和变量,这样就不需要添加注释来解释这些事情做了什么(写注释解释它们存在的原因是很好的)。尽可能地用代码来表达自己!以addMarker为例。我认为addMarker最好写成markCellWithMarker(int cellNumber, String marker) (我认为X和O是游戏中使用的令牌),getCellValue则是getMarkerAt(int cellNumber)

应用这些更改,下面是GameBoard类的重构版本:

代码语言:javascript
运行
复制
public class GameBoard {

    private Cell[] board;

    public GameBoard(int numberOfCells) {
        board = new Cell[numberOfCells];
        for (int i = 0; i < numberOfCells; i++) {
            board[i] = new Cell();
        }
    }

    public void markCellWithMarker(int cellNumber, String token) {
        board[cellNumber].setMarker(token);
    }

    public String getMarkerAt(int cellNumber) {
        return board[cellNumber].getMarker();
    }
}

至于游戏类,它并没有真正证明它的存在就像现在这样。它只包含一个应该运行游戏的方法(如果我正确地阅读了您的代码)。将它重构成这样可能证明它的存在是有道理的:

代码语言:javascript
运行
复制
public class Game {
    private GameBoard gameBoard;
    private Player[] players;
    private int turnNumber;

    //In case you want a two player game.
    public Game(int numberOfCells, Player player1, player player2){
        gameBoard = new GameBoard(numberOfCells);
        setFirstTurnPlayer(player1, player2);
    }

    //In case you want a single player game against the computer. 
    public Game(int numberOfCells, Player player){
        gameBoard = new GameBoard(numberOfCells);
        Player computer = new Player("computer");
        setFirstTurnPlayer(player1, computer);
    }

    private void setFirstTurnPlayer(Player player1, Player player2){
        //It's up to you how you decide the turnorder: die roll, coin toss or something.
        //The first one in the player array is considered as the turn player.
    }

    public String getTurnPlayer(){
        return players[turnNumber%2].getName();
    }

    public void markCellWithMarker(int cellNumber){
        String markerToPlace = players[turnNumber%2].getPlayerMarker()
        gameBoard.markCellWithMarker(cellNumber, markerToPlace)
        checkIfTurnPlayerWinsTheGame()
        turnNumber++;
    }

    //GameStateChecker code moved here. I think this one can be made shorter and more readable.
    public void checkIfTurnPlayerWinsTheGame(){
        //Rename currentPlayer as turnPlayer
        Player currentPlayer = players[turnNumber%2]
        if ((board[0].getMarker().equals(currentPlayer.getMarker()) && board[1].getMarker().equals(currentPlayer.getMarker()) && board[2].getMarker().equals(currentPlayer.getMarker())) ||
            (board[3].getMarker().equals(currentPlayer.getMarker()) && board[4].getMarker().equals(currentPlayer.getMarker()) && board[5].getMarker().equals(currentPlayer.getMarker())) ||
            (board[6].getMarker().equals(currentPlayer.getMarker()) && board[7].getMarker().equals(currentPlayer.getMarker()) && board[8].getMarker().equals(currentPlayer.getMarker())) ||
            (board[0].getMarker().equals(currentPlayer.getMarker()) && board[3].getMarker().equals(currentPlayer.getMarker()) && board[6].getMarker().equals(currentPlayer.getMarker())) ||
            (board[1].getMarker().equals(currentPlayer.getMarker()) && board[4].getMarker().equals(currentPlayer.getMarker()) && board[5].getMarker().equals(currentPlayer.getMarker())) ||
            (board[2].getMarker().equals(currentPlayer.getMarker()) && board[5].getMarker().equals(currentPlayer.getMarker()) && board[8].getMarker().equals(currentPlayer.getMarker())) ||
            (board[0].getMarker().equals(currentPlayer.getMarker()) && board[4].getMarker().equals(currentPlayer.getMarker()) && board[8].getMarker().equals(currentPlayer.getMarker())) ||
            (board[2].getMarker().equals(currentPlayer.getMarker()) && board[4].getMarker().equals(currentPlayer.getMarker()) && board[6].getMarker().equals(currentPlayer.getMarker()))) 
        throw new GameIsOverException(currentPlayer.getName() + " wins!")
}

这是我为一款名为代码的游戏编写的ConnectFour,我认为它有点类似于toe。这可能会帮助你看到我在这里提到的一些关于正确命名和其他东西的东西。

票数 1
EN

Code Review用户

发布于 2017-10-09 10:46:13

多余的类和接口

没有大的意义有一个Movable接口和类ComputerMoveHumanMove。它们可能包含在相应的Playable类中。即使您希望将它们作为单独的类,用户也不应该直接创建它们,让Playable类在它们的构造函数中这样做。

奇异方法在ConsoleInput

中的命名

toIntegerReader方法返回一个int的事实是违反直觉的。该方法的更好名称是readIntreader方法- readString也是如此。已分配但未使用的input字段。

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

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

复制
相关文章

相似问题

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