java - 数组编程 - 检查井字游戏中有 n 个玩家的 nxn 棋盘的赢家

标签 java arrays debugging

我正在为 nxn 板上的 n 名玩家制作井字游戏,但获胜条件是连续 3 场比赛。到目前为止,我对该问题的解决方案是:进行移动时,程序将连续检查以下方 block 是否有 3 个。

(x-1,y+1) (x,y+1) (x+1,y+1)

 (x-1,y)   (x,y)   (x+1,y)

(x-1,y-1) (x,y-1) (x+1,y-1)

它将检查顶部 (x-1,y+1) (x,y+1) (x+1,y+1) 底部(x-1,y-1) (x,y-1) (x+1,y-1) sides(x+1,y+1) (x+1,y) (x+1,y-1) , (x-1,y+1) (x-1,y) (x-1,y- 1) 、对角线和穿过中间的对角线(x,y)。

到目前为止我的代码是:

   public int checkWinning() {
     for(int a = 1; a < size-1; a++){
        for(int b = 1; b < size-1; b++){
            if (board[a][b] == board[a+1][b] && board[a][b] == board[a-1][b]){
                return board[a][b];
            }else if(board[a][b] == board[a][b+1] && board[a][b] == board[a][b-1]){
                return board[a][b];
            }else if(board[a][b] == board[a+1][b-1] && board[a][b] == board[a-1][b+1]){
                return board[a][b];
            }else if(board[a][b] == board[a+1][b+1] && board[a][b] == board[a-1][b-1]){
                return board[a][b];
            }
        }
    }
    for(int d = 1; d < size-1; d++){
        if (board[0][d] == board[0][d-1] && board[0][d] == board[0][d+1]){
            return board[0][d];
        } else if (board[size-1][d] == board[size-1][d-1] && board[size-1][d] == board[size-1][d+1]){
            return board[size-1][d];
        }
    }

    for(int c = 1; c < size-1; c++){
        if (board[c][0] == board[c-1][0] && board[c][0] == board[c+1][0]){
            return board[c][0];
        }else if(board[c][size-1] == board[c-1][size-1] && board[c][size-1] == board[c+1][size-1]){
            return board[c][size-1];
            }
        }   
    return 0;
}

第一部分是我检查中间部分和对角线部分的地方。第二部分我检查顶部、底部和顶部,第三部分检查侧面。

当它返回 0 时,表示还没有获胜者。

@override
public void checkResult() {
    int winner = this.board.checkWinning();
    if (winner > 0) {
        this.ui.showResult("Player "+winner+" wins!");
    }
    if (this.board.checkFull()) {
        this.ui.showResult("This is a DRAW!");
    }
}

Board[x][y] -> 代表棋盘的二维数组,坐标从左上(0,0)到右下(size-1,size-1),board[x ][y] == 0 表示在位置 (x,y) 处空闲,board[x][y] == i 因为 i > 0 表示玩家 i 在 (x,y) 上移动了,所以你知道.

我的问题是,当我将电路板扩展到大于 3x3 的尺寸时,程序会以某种方式自行覆盖它,或者不会每次都检查顶部和底部的所有东西,我似乎不太明白为什么。

p>

最佳答案

编辑:

玩了几分钟应用……有趣的结果

java -jar tic-tac-toe.jar 5 20

It was a cats game!!

|1|1|5|5|1|3|5|3|1|5|2|5|1|1|2|
|2|3|2|3|1|5|3|5|3|2|3|1|5|2|2|
|5|4|5|4|1|5|5|4|2|1|4|5|4|2|2|
|3|2|1|5|5|5|2|4|5|3|4|1|2|4|2|
|3|4|1|2|5|4|1|1|4|5|1|3|3|4|1|
|1|5|4|4|3|2|5|1|3|5|1|3|5|3|4|
|2|5|1|4|3|3|3|5|3|1|1|4|3|4|4|
|1|4|5|1|1|5|4|5|2|4|1|1|5|4|3|
|1|3|2|1|4|2|4|3|3|4|5|2|4|3|3|
|5|1|1|3|3|4|4|4|2|2|1|4|3|2|5|
|2|2|3|1|5|5|4|1|3|5|3|2|3|3|2|
|2|4|2|4|4|1|3|1|1|3|1|2|1|2|2|
|2|5|5|1|4|3|4|5|5|4|5|3|3|5|2| 
|4|5|2|1|5|3|2|1|3|2|2|2|2|4|4|
|4|1|1|4|5|4|5|4|2|2|3|3|2|2|3|

Played 100 games:
Number wins by Player1: 0
Number wins by Player2: 0
Number wins by Player3: 0
Number wins by Player4: 0
Number wins by Player5: 0
Number of ties: 100

没有滚动所有 100 场比赛来找到获胜的棋盘,但我认为这很有趣:

java -jar tic-tac-toe.jar 2 10

Player2 won the game!

|1|1|2|1|2|2| |2|1|2|
|2|2|2|2|2|2|2|2|2|2|
|2|1|2|2|2|1|1|1|1|1|
|1|1|1|1|2|1|2|1|1|1|
|2|2| |1|2|1|1|1|1|2|
|2|2|2|1|1|1| |1|2|2|
|2|2|1|2|2|2|2|2|1|1|
| | |2|2|2|2| |1|1|1|
|1|1|2|2|2|1|1|1|1| |
| | |1|1|1|1|1|2|1| |

Played 100 games:
Number wins by Player1: 0
Number wins by Player2: 1
Number of ties: 99

这确实回答了您的问题……但我想得太远了……决定实现该解决方案。 而不是计算比赛...我只是从最后一名球员比赛的点开始检查,如果行列和对角线中的所有标记都与球员匹配,他就赢了。

package com.clinkworks.example;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TicTacToe {

    private static final String TIE = "TIE";

    private static final Map<String, Integer> gamesToWinsMap = new HashMap<String, Integer>();


    /**
     * accepts input in the following format:
     * 
     * playerCount rowCount columnCount (sets the game with the n players, n columns, and n rows)
     *      - java -jar tic-tac-toe.jar 2 3 3
     * PlayerCount squareSize (defaults to a game with rows and cols the same as squareSize and the player count given)
     *       - java -jar tic-tac-toe.jar 2 3
     * PlayerCount (defaults to a 3 by 3 game)
     *       - java -jar tic-tac-toe.jar 2
     * no input (defaults to a 3 by 3 game with 2 players)
     *       - java -jar tic-tac-toe.jar
     * @param args
     */
    public static void main(String[] args) {

        int playerCount = 2;
        int rows = 3;
        int cols = 3;

        if(args.length == 3){
            playerCount = Integer.valueOf(args[0]);
            rows = Integer.valueOf(args[1]);
            cols = Integer.valueOf(args[2]);
        }

        if(args.length == 2){
            playerCount = Integer.valueOf(args[0]);
            rows = Integer.valueOf(args[1]);
            cols = rows;
        }

            if(args.length == 1){
                    playerCount = Integer.valueOf(args[0]);
            }


        for(int i = 1; i <= playerCount; i++){
            gamesToWinsMap.put("Player" + i, 0);
        }

        //lets play 100 games and see the wins and ties
        playGames(100, playerCount, rows, cols);

        for(int i = 1; i <= playerCount; i++){
            System.out.println("Number wins by Player" + i + ": " + gamesToWinsMap.get("Player" + i));
        }

        System.out.println("Number of ties: " + gamesToWinsMap.get(TIE));
    }

    public static void playGames(int gamesToPlay, int playerCount, int rows, int cols) {
        //play a new game each iteration, in our example, count = 100;
        for (int i = 0; i < gamesToPlay; i++) {
            playGame(playerCount, rows, cols);
        }
    }

    public static void playGame(int playerCount, int rows, int cols) {
        //create a new game board. this initalizes our 2d array and lets the complexity of handling that
        // array be deligated to the board object.


        Board board = new Board(playerCount, rows, cols);

        //we are going to generate a random list of moves. Heres where we are goign to store it
        List<Move> moves = new ArrayList<Move>();

        //we are creating moves for each space on the board.
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                moves.add(new Move(row, col));
            }
        }

        //randomize the move list
        Collections.shuffle(moves);

        //do each move
        for (Move move : moves) {
            board.play(move);

            if(gameOver(board)){
                break;
            }
        }
    }

    public static boolean gameOver(Board board){
        if (board.whoWon() != null) {
            System.out.println(board.whoWon() + " won the game!");
            System.out.println(board);

            Integer winCount = gamesToWinsMap.get(board.whoWon());
            winCount = winCount == null ? 1 : winCount + 1;

            gamesToWinsMap.put(board.whoWon(), winCount);

            return true;

        } else if (board.movesLeft() == 0) {
            System.out.println("It was a cats game!!");
            System.out.println(board);

            Integer tieCount = gamesToWinsMap.get(TIE);
            tieCount = tieCount == null ? 1 : tieCount + 1;
            gamesToWinsMap.put(TIE, tieCount);

            return true;
        }

        return false;
    }

    public static class Move {
        private int row;
        private int column;

        public Move(int row, int column) {
            this.row = row;
            this.column = column;
        }

        public int getRow() {
            return row;
        }

        public int getColumn() {
            return column;
        }

    }

    public static class Board {

        private final int rowSize;
        private final int columnSize;
        private final Integer[][] gameBoard;
        private int playerCount;
        private int currentPlayer;
        private String winningPlayer;

        public Board() {
            gameBoard = new Integer[3][3];
            currentPlayer = 1;
            winningPlayer = null;
            this.rowSize = 3;
            this.columnSize = 3;
            playerCount = 2;
        }


        public Board(int players) {
            gameBoard = new Integer[3][3];
            currentPlayer = 1;
            winningPlayer = null;
            this.rowSize = 3;
            this.columnSize = 3;
            playerCount = players;
        }

        public Board(int rowSize, int columnSize) {
            gameBoard = new Integer[rowSize][columnSize];
            currentPlayer = 1;
            winningPlayer = null;
            playerCount = 2;
            this.rowSize = rowSize;
            this.columnSize = columnSize;
        }            

        public Board(int players, int rowSize, int columnSize) {
            gameBoard = new Integer[rowSize][columnSize];
            currentPlayer = 1;
            winningPlayer = null;
            playerCount = players;
            this.rowSize = rowSize;
            this.columnSize = columnSize;
        }



        /**
        * 
        * @return the amount of empty spaces remaining on the game board, or if theres a winning player, zero.
        */
        public int movesLeft() {

            if(whoWon() != null){
                return 0;
            }

            int moveCount = 0;
            for (int x = 0; x < getRowSize(); x++) {
                for (int y = 0; y < getColumnSize(); y++) {
                    moveCount += getMoveAt(x, y) == null ? 1 : 0;
                }
            }
            return moveCount;
        }

        /**
        * If someone won, this will return the winning player.
        * 
        * @return the winning player
        */
        public String whoWon() {
            return winningPlayer;
        }

        /**
        * This move allows the next player to choose where to place their mark.
        * 
        * @param row
        * @param column
        * @return if the game is over, play will return true, otherwise false.
        */
        public boolean play(Move move) {

            if (!validMove(move)) {
                // always fail early
                throw new IllegalStateException("Player " + getCurrentPlayer() + " cannot play at " + move.getRow() + ", " + move.getColumn() + "\n" + toString());
            }

            doMove(move);

            boolean playerWon = isWinningMove(move);

            if (playerWon) {
                winningPlayer = "Player" + getCurrentPlayer();
                return true;
            }

            shiftPlayer();

            boolean outOfMoves = movesLeft() <= 0;

            return outOfMoves;
        }

        public int getRowSize() {
            return rowSize;
        }

        public int getColumnSize() {
            return columnSize;
        }

        public int getCurrentPlayer() {
            return currentPlayer;
        }

        public Integer getMoveAt(int row, int column) {
            return gameBoard[row][column];
        }

        private void doMove(Move move) {
            gameBoard[move.getRow()][move.getColumn()] = getCurrentPlayer();
        }

        private void shiftPlayer() {
            if(getCurrentPlayer() == getPlayerCount()){
                currentPlayer = 1;
            }else{
                currentPlayer++;
            }
        }

        private int getPlayerCount() {
            return playerCount;
        }


        private boolean validMove(Move move) {
            boolean noMoveAtIndex = false;
            boolean indexesAreOk = move.getRow() >= 0 || move.getRow() < getRowSize();
            indexesAreOk = indexesAreOk && move.getColumn() >= 0 || move.getColumn() < getColumnSize();
            if (indexesAreOk) {
                noMoveAtIndex = getMoveAt(move.getRow(), move.getColumn()) == null;
            }
            return indexesAreOk && noMoveAtIndex;
        }

        private boolean isWinningMove(Move move) {
            // since we check to see if the player won on each move
            // we are safe to simply check the last move
            return winsDown(move) || winsAcross(move) || winsDiagnally(move);
        }

        private boolean winsDown(Move move) {
            boolean matchesColumn = true;

            for (int i = 0; i < getColumnSize(); i++) {
                Integer moveOnCol = getMoveAt(move.getRow(), i);
                if (moveOnCol == null || getCurrentPlayer() != moveOnCol) {
                    matchesColumn = false;
                    break;
                }
            }

            return matchesColumn;
        }

        private boolean winsAcross(Move move) {
            boolean matchesRow = true;
            for (int i = 0; i < getRowSize(); i++) {
                Integer moveOnRow = getMoveAt(i, move.getColumn());
                if (moveOnRow == null || getCurrentPlayer() != moveOnRow) {
                    matchesRow = false;
                    break;
                }
            }
            return matchesRow;
        }

        private boolean winsDiagnally(Move move) {
            // diagnals we only care about x and y being teh same...
            // only perfect squares can have diagnals
            // so we check (0,0)(1,1)(2,2) .. etc
            boolean matchesDiagnal = false;
            if (isOnDiagnal(move.getRow(), move.getColumn())) {
                matchesDiagnal = true;
                for (int i = 0; i < getRowSize(); i++) {
                    Integer moveOnDiagnal = getMoveAt(i, i);
                    if (moveOnDiagnal == null || moveOnDiagnal != getCurrentPlayer()) {
                        matchesDiagnal = false;
                        break;
                    }
                }
            }

            return matchesDiagnal;
        }

        private boolean isOnDiagnal(int x, int y) {
            if (boardIsAMagicSquare()) {
                return x == y;
            } else {
                return false;
            }
        }

        private boolean boardIsAMagicSquare() {
            return getRowSize() == getColumnSize();
        }

        public String toString() {
            StringBuffer stringBuffer = new StringBuffer();
            for(int y = 0; y < getColumnSize(); y++) {
                for(int x = 0; x < getRowSize(); x++) {
                    Integer move = getMoveAt(x, y);
                        String moveToPrint = "";
                    if (move == null) {
                        moveToPrint = " ";
                    } else {
                        moveToPrint = move.toString();
                    }
                    stringBuffer.append("|").append(moveToPrint);
                }
                stringBuffer.append("|\n");
            }
            return stringBuffer.toString();
        }
    }
}

关于java - 数组编程 - 检查井字游戏中有 n 个玩家的 nxn 棋盘的赢家,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20399904/

相关文章:

java - 如何在 Java 程序中执行斯坦福 CoreNLP 情感分析?

Java:抽象类的对象

javascript - 我对这个数组做错了什么?

android - 是否可以 Proguard 一个 Android 库模块,而不是应用程序模块?

javascript - 如何使用 VS Code 调试 Node.js 中的私有(private)类字段?

function - 如何在Conky中实现一个基本的Lua功能?

java - 获取音乐播放器Android的专辑封面(错误)

java - 如何在 Java 10 或更高版本的 Java 11 中运行现有的 JAVA Web 启动应用程序

javascript - 在 Javascript 中向嵌套数组添加元素

javascript - 使用 lodash 将对象数组转换为对象