在3x3数组中查找元素

时间:2019-01-30 07:19:12

标签: java arrays tic-tac-toe

我是编程新手,并且创建了一个井字游戏。游戏完全可以运行,但是我想在计算机上添加一些“智能”。

传统的3 x 3井字游戏板(看起来像“#”)由一个数组表示,其中所有元素(所有值)最初都设置为零。当玩家选择自己的位置时,该值将更改为1。例如,如果玩家在右上角放置X,则array [0] [2]变为1。如果玩家在底部放置X左上角,array [2] [0]变为1。

我正在尝试创建两种方法,一种方法返回行(用r()表示),另一种方法返回玩家必须将决赛放置在哪一坐标的列(用c()表示) X这样他们就赢了()。基本上,我试图使方法返回玩家需要放置最终X才能赢得比赛的位置,以便计算机可以阻止它。

我尝试使用循环搜索数组以寻找2的总和,但是我完全迷失了。任何帮助表示赞赏。此外,任何有关“情报”的建议都将有所帮助。

import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
public class TicTacToe {

    //-------------------------------------------------------------------------
    private static int[][] grid;
    private static final int XPOS = 1;
    private static final int OPOS = -1;
    private static final int EMPTY = 0;


    //-------------------------------------------------------------------------
    public static void main(String[] args) {

//game


        do {
            initBoard();

            do {
                moveX();

                if (isTicTacToe()) {
                    JOptionPane.showMessageDialog(null, "X wins");
                } else if (isCatsGame()) {
                    JOptionPane.showMessageDialog(null, "Cats Game");
                } else {
                    moveO();
                    if (isTicTacToe()) {
                        JOptionPane.showMessageDialog(null, "O wins");
                    }
                }

            } while (!isCatsGame() && !isTicTacToe());
        } while (JOptionPane.showConfirmDialog(null, "Playagain?") == JOptionPane.YES_OPTION);
    }

 //-------------------------------------------------------------------------

//Methods

    public static void moveX() {
        // PRECONDITION: The grid is initialized and not full
        // POSTCONDITION: XPOS is assigned to the location in grid chosen by the user

        // Algorithm: Ask the user for a location from 1-9, convert it to (r,c), 
        // make sure it is valid and empty, assign XPOS to that locaion

        int move;
        do {
            move = Integer.parseInt(JOptionPane.showInputDialog(displayBoard()
                    + "\n\n Enter your move for X"));
        } while ((move < 1) || (move > 9)
                || grid[getRow(move)][getCol(move)] != EMPTY);
        grid[getRow(move)][getCol(move)] = XPOS;

    }
    //-------------------------------------------------------------------------

    public static void moveO() {
        // PRECONDITION: The grid is initialized and not full
        // POSTCONDITION: a random available location has been assigned OPOS

        int move = (int) (Math.random() * 9 + 1);

        if (check(move, move) == true)  {
            grid[getRow(move)][getCol(move)] = OPOS;
        }
    }

    //-------------------------------------------------------------------------
    public static boolean isTicTacToe() {
        // PRECONDITION:  grid is initialized
        // POSTCONDITION: Returns TRUE if there is a winner, FALSE otherwise

        for (int i = 0; i <= 2; i++) {
            if (Math.abs(grid[i][0] + grid[i][1] + grid[i][2]) == 3) {
                return true;
            } else if (Math.abs(grid[0][i] + grid[1][i] + grid[2][i]) == 3) {
                return true;
            } else if (Math.abs(grid[0][0] + grid[1][1] + grid[2][2]) == 3) {
                return true;
            } else if (Math.abs(grid[0][2] + grid[1][1] + grid[2][0]) == 3) {
                return true;
            }
        }
        return false;
    }

    //-------------------------------------------------------------------------
    public static void initBoard() {
        // PRECONDITION: 
        // POSTCONDITION: The grid has been initialize and all values set to EMPTY//initilize the board by creating a 3 by 3 array of integers

        grid = new int[3][3];
        // Make all the vakues empty
        for (int i = 0; i > grid.length; i++) {
            for (int j = 0; j > grid.length; j++) {
                grid[i][j] = EMPTY;
            }
        }
    }

    //-------------------------------------------------------------------------
    public static boolean isCatsGame() {
        // PRECONDITION: The grid is initialized
        // POSTCONDITION: returns TRUE if there are no EMPTY spots, FALSE otherwise

        for (int r = 0; r >= 2; r++) {
            for (int c = 0; c >= 2; c++) {
                if (grid[r][c] == EMPTY) {
                    return true;
                }
            }

        }

        return false;
    }

    //-------------------------------------------------------------------------
    private static int getRow(int n) {
        // PRECONDITION: 1 <= n <= 9
        // POSTCONDITION: returns the correct row - 0, 1, or 2
        return ((n - 1) / 3);
    }

    private static int getCol(int n) {
        // PRECONDITION: 1 <= n <= 9
        // POSTCONDITION: returns the correct col - 0, 1, or 2
        return ((n - 1) % 3);
    }

    //-------------------------------------------------------------------------
    public static String displayBoard() {
        // PRECONDITION: The grid is initialized
        // POSTCONDITION: returns a string representatin of the grid to be used
        //                in a JOPTIONPANE (\n's but no \t's).
        //                XPOS is replaced with X, OPOS with O, 
        //                EMPTY with the correct number 1 - 9

        String s = "";
        for (int i = 1; i <= 9; i++) {
            int r = getRow(i);
            int c = getCol(i);
            if (grid[r][c] == EMPTY) {
                s += " " + i;
            } else if (grid[r][c] == XPOS) {
                s += " X";
            } else {
                s += " O";
            }
            if (i % 3 == 0) {
                s += "\n";
            }
        }
        return s;
    }

    private static boolean check(int x, int y) {
        //PRECONDITION: CHECKS IF A COORDINATE ON THE TABLE IS OCCUPIED
        //POSTCONDITION: RETURNS TRUE IF ITS NOT BEING USED
        if (grid[getRow(x)][getCol(y)] != EMPTY) {
            return false;
        }
        return true;
    }

    //need a method to see if there is two in a row, and one to find where the 
    // winning x,y coordinate is 
    private static boolean matchPoint() {
        for (int i = 0; i <= 2; i++) {
            if (Math.abs(grid[i][0] + grid[i][1] + grid[i][2]) == 2) {
                return true;
            } else if (Math.abs(grid[0][i] + grid[1][i] + grid[2][i]) == 2) {
                return true;
            } else if (Math.abs(grid[0][0] + grid[1][1] + grid[2][2]) == 2) {
                return true;
            } else if (Math.abs(grid[0][2] + grid[1][1] + grid[2][0]) == 2) {
                return true;
            }
        }
        return false;
    }

    private static int r() {

    }

    private static int c() {

}

2 个答案:

答案 0 :(得分:0)

对于具有完善信息和交替动作的更复杂的游戏,存在大量的游戏理论。象棋,围棋,井字游戏,米尔斯和德这样的游戏都具有相同的基本规则集。但是TicTacToe被简化了,因为选项非常有限,您基本上可以“解决”复杂的求解方式,并且可以通过做出非常直接的放置决策来实现直接方式。

通常,此类游戏可以通过创建一个树来解决。这是一棵搜索树,所有可能的展示位置都在其中搜索。但是,(大多数)这些游戏无法通过这种方式解决,因为树木过大(您尝试向前看的每一层,它们都会成倍增长)。但是对于TicTacToe来说,它是如此的小巧和简单,您实际上可以解决树,而不会耗费时间或内存。

在像这样的树中搜索时,通常不将函数分为x和y,而是将它们一起处理(例如,使用PointCoordinate类)。使用递归算法遍历所有选项,然后根据AI播放器可用的最佳选项放置您的棋子。

(也就是说,我个人建议您从迭代的编码方式中脱颖而出,并进一步进行面向对象的编程。这样,代码将更具可读性,并且可以更好地隔离问题)

提示: 由于木板是正方形的,而零件是“平坦的”,因此可以通过“合并”木板的位置来简化树。例如,以下两种情况(有效)是相同的:

X|  |
------
 |O |
------
 |  |

 |  |X
------
 |O | 
------
 |  |

因此,当您“搜索”正确的举动时,您可以按照相同的步骤进行踩踏,只要稍后您仍可以弄清楚您以哪种方式翻转和/或翻转木板,以找出正确的位置。 但是即使没有这种简化,您也应该能够很容易地解决树。

完成TicTacToe的实现后,看看棋盘游戏“ Tak”。 已经编写了多个开源AI,从长远来看,该游戏比TicTacToe更有趣;) https://www.playtak.com/(在“帮助”下找到规则。那里有多个有趣的链接)。

答案 1 :(得分:0)

我将使用与您的isTicTacToe()方法相同的逻辑,并在您的grid表中查找可能的位置并返回它;如果找不到该位置,则返回null 。例如:

import java.awt.Point;
// ...
Point getPointToWin() {
    // look for wc (win condition) and return it if found, otherwise null
    for(int r=0; r<grid.length; r++) {
        for(int c=0; c<grid[0].length; c++) {
            // skip if not X
            if(grid[r][c]!=XPOS)
                continue;
            // lookup wc in top row
            if(r==0)
                if(c==0) {
                    if(grid[r][c+1]==XPOS)
                        return new Point(r,c+2)
                    if(grid[r+1][c+1]==XPOS)
                        return new Point(r+2,c+2)
                    if(grid[r+1][c]==XPOS)
                        return new Point(r+2,c)
                }
                elseif(c==1) {
                    // ... top row, center column
                }
                elseif(c==2) {
                    // ... top row, right column
                }
            elseif(r==1) {
                // ... center row, left/center/right column
            }
            elseif(r==2) {
                // ... bottom row, left/center/right column
            }
        }
    }
    return null;
}

为使它尽可能短,我只写了wc查找逻辑(如果在右行,顶列中找到了X)。然后,您将不得不为X的其余8个可能位置编写逻辑。