首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检查4行(用Java连接4)

检查4行(用Java连接4)
EN

Stack Overflow用户
提问于 2018-01-29 17:20:41
回答 2查看 3.9K关注 0票数 0

我正在用Java做一个Connect 4克隆,我遇到了一些问题。我已经完成了大部分代码,但是我不知道如何检查获胜条件。这是我的代码:

代码语言:javascript
运行
复制
import java.util.Scanner;

public class ConnectFour
{
    private static char board[][];
    private static final int BOARD_WIDTH = 7;
    private static final int BOARD_HEIGHT = 6;
    private static boolean gameEnd = false;
public static void main(String[] args)
{
    // Element #0 in the two-dimensional 'board' array is not used
    // so that the column numbers selected by the players match
    // with the actual internal element numbers of the array

    board = new char[BOARD_HEIGHT + 1][BOARD_WIDTH + 1];
    Scanner input = new Scanner(System.in);
    char turn = 'x';
    int dropColumn = 0;

    System.out.println("TWO PLAYER CONNECT FOUR GAME!");
    InitializeBoard();
    while (gameEnd == false)
    {
        DisplayBoard();
        dropColumn = GetDropColumn(turn, input) - 1;

        if (DropChecker(turn, dropColumn) == true)
        {
            turn = 'x' == turn ? 'o' : 'x'; //ternary operator
        }
        else {
            System.out.println("Column full. Please input again.");
        }
    }
}

// Set all elements of the two-dimensional 'board' array to spaces
private static void InitializeBoard()
{
    char a = ' ';
    for (int i = 0; i < board.length; i++)
    {
        for (int e = 0; e < board[i].length; e++)
            board[i][e] = a;
    }
}

// Display the game board (the board itself, along with the elements of
// the two-dimensional 'board' array); note that the lines of the game
// board are NOT stored in the two-dimensional 'board' array
private static void DisplayBoard()
{
    for (int row = 0; row < board.length; row++)
    {
        for (int col = 0; col < board.length; col++)
        {
            System.out.print("|");
            System.out.printf("%2c", board[row][col]);
        }
        System.out.println();
    }
}

// Get (from the appropriate player) the number (1 – 'BOARD_WIDTH') of
// the column in which a checker should be dropped, and then return that
// number; if the player does not enter an integer, report the error and
// keep asking for a column number until an integer is entered; note that
// the check for an invalid column number (< 1 or > 'BOARD_WIDTH') can be
// performed in this method or in 'main', from where this method is called
private static int GetDropColumn(char turn, Scanner input)
{
    int numInput = 0;
    int realInput = 0;
    while (realInput == 0)
    {
        try
        {
            System.out.println("Player " + turn + "'s turn: In which column would you like to place a checker? (1-7)");
            numInput = input.nextInt();
            if (numInput < 1 || numInput > BOARD_WIDTH)
            {
                numInput = 0;
                System.out.println("The number was out of bounds. Please try again.");
            }
        }
        catch (NumberFormatException e)
        {
            System.out.println("Invalid input. Please try again.");
        }
        realInput = numInput;
    }
    return realInput;
}

// "Drop" a checker into the designated column by setting the
// appropriate element of the two-dimensional 'board' array to
// either an 'x' or an 'o'; if the "drop" was successful, this
// method returns "true"; an attempt to "drop" the checker into
// a full column results in "false" being returned
private static boolean DropChecker(char turn, int dropColumn)
{
    int indexToPaceChecker = BOARD_HEIGHT;
    while (indexToPaceChecker >= 0)
    {
        if (board[indexToPaceChecker][dropColumn] == ' ')
        {
            //drop the checker
            board[indexToPaceChecker][dropColumn] = turn;
            return true;
        }
        indexToPaceChecker--;
    }
    return false;
}

// Check for a (horizontal, vertical, or diagonal) line of four
// consecutive checkers in the game board; if found, "true" is
// returned; if not found, "false" is returned
private static boolean CheckForLineOfFour()
{

}
}

我已经尝试过多种思路,但我无法让它发挥作用。如何正确地检查这一点?它需要检查垂直(这是有意义的),水平(这也有意义),但对角线检查似乎不必要的困难。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-30 13:35:21

请注意,如果您总是在转弯后立即检查,您知道行必须包括您刚刚放置的部分。很容易编写一种方法来计算从特定位置开始的直线长度,并沿着特定的方向进行:

代码语言:javascript
运行
复制
int lengthOfLineStartingAt(int x, int y, int xStep, int yStep) {
     char colour = grid[x][y];
     int i = 0;
     while(grid[x][y] == colour) { 
        x = x + xStep;
        y = y + yStep;
        i++;
     }
     return i;
}

这假设单元格在(x,y)处设置为期望值,因此总是至少返回1。您也可以将所需的值作为参数传递。

虽然这说明了基本算法,但您需要对其进行增强,以避免数组索引超出界限的错误。

您还可以通过限制它的最大步行数4来节省一些执行时间,因为您不需要知道更长的行数。尽管Connect 4的本质意味着不可能得到一条大于7的线(当你的作品连接到现有的两行3)。

一条线可以从(x,y)开始,也可以向两个方向延伸。您可以通过以下方式获得完整的长度:

代码语言:javascript
运行
复制
int lengthOfLineContaining(int x, int y, int xStep, int yStep) {
    return lengthOfLineStartingAt(x,y,xStep,yStep)
         + lengthOfLineStartingAt(x,y,-xStep,-yStep)
         - 1;
}

用纸和铅笔试一试,看看为什么会这样。

有四个xStep/yStep组合,您需要使用以下四个组合:上/下、左/右和对角。

代码语言:javascript
运行
复制
boolean isFourInARow(int x, int y) {
    return 
       lengthOfLineContaining(int x, int y, 0, 1) >= 4 ||
       lengthOfLineContaining(int x, int y, 1, 1) >= 4 ||
       lengthOfLineContaining(int x, int y, 1, 0) >= 4 ||
       lengthOfLineContaining(int x, int y, 1, -1) >= 4;
}

(左作为一个练习-在一个循环中这样做。提出一个方法,将表示8个方向的数字0-7转换为0或-1的x和y值)

票数 0
EN

Stack Overflow用户

发布于 2018-01-29 19:09:42

将有四种验证来检查四条线。

  1. 水平
  2. 垂直
  3. 对角线(左下角至右上角)
  4. 对角线(右下角至左上角)

对所有四个验证的方法都是相同的;扫描所有可能的起点,并在特定的方向上查看4个连续的部分。理解的关键是:

  1. 第一行和第二行计数器的界限是多少?例如,检查水平win对您检查的行没有限制(必须检查所有行),但是在寻找一行中的4个连续段时必须小心,以免超出数组的界限。
  2. 搜索的方向指示了在查找4个连续的片段时要使用的偏移量。

因此,寻找对角线胜利是非常类似的垂直或横向的方法。这里有一种强力的方法来检查上面的验证#3;其他的都是小的变化,作为练习留给您。

代码语言:javascript
运行
复制
private static boolean checkForLineOfFour(char turn) {
    // Diagonal (bottom left to top right)
    for (int row = board.length-1; row >= 3; row--) {
        for (int col = 0; col <= board.length-4; col++) {
            boolean isLine = true;
            for (int i = 0; i<4 && isLine; i++) {
                if (board[row-i][col+i] != turn)
                    isLine = false;
            }
            if (isLine)
                return true;
        }
    }

    // TODO:  Diagonal (bottom right to top left)
    // TODO:  Vertical
    // TODO:  Horizontal

    return false;
}

然后修改您的程序,以检查每回合是否有一场胜利:

代码语言:javascript
运行
复制
if (DropChecker(turn, dropColumn) == true) {
    if (checkForLineOfFour(turn)) {
        DisplayBoard();
        System.out.println("Winner="+turn);
        gameEnd = true;
    }
    turn = 'x' == turn ? 'o' : 'x'; // ternary operator
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48506672

复制
相关文章

相似问题

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