检查一行四(Java中连接四)

时间:2018-01-29 17:20:41

标签: java

我用Java制作Connect Four克隆,我遇到了一些问题。我已经完成了大部分代码,但我对如何检查胜出条件感到茫然。这是我的代码:

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()
{

}
}

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

2 个答案:

答案 0 :(得分:0)

将有四个验证来检查四行。

  1. 水平
  2. 垂直
  3. 对角线(从左下角到右上角)
  4. 对角线(从右下角到左上角)
  5. 所有四种验证的方法都是相同的;扫描所有可能的起点,并查看特定方向上的4个连续部分。理解的关键是:

    1. 起始行和col计数器的界限是什么?例如,检查水平获胜对您检查的行没有限制(您必须检查所有行),但是在查找一行中的4个连续片段时,您必须小心,不要超出阵列的范围。
    2. 搜索的方向决定了在寻找4个连续作品时使用的偏移
    3. 因此寻找对角线胜利与垂直或水平方法非常相似。这是检查上面验证#3的强力方法;其他是小变化,留给你练习。

      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;
      }
      

      然后改变你的计划以检查每回合的胜利:

      if (DropChecker(turn, dropColumn) == true) {
          if (checkForLineOfFour(turn)) {
              DisplayBoard();
              System.out.println("Winner="+turn);
              gameEnd = true;
          }
          turn = 'x' == turn ? 'o' : 'x'; // ternary operator
      }
      

答案 1 :(得分:0)

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

VideoView

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

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

您还可以通过将其限制为最大行程4来节省一些执行时间,因为您不需要知道更长的行。虽然Connect 4的性质意味着不可能获得超过7的行(当你的作品加入两条现有的3行时)。

一条线可能从(x,y)开始,或者可能在两个方向上延伸。您可以通过以下方式获得全文:

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;
}

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

您需要尝试四种xStep / yStep组合:上/下,左/右和两个对角线。

int lengthOfLineContaining(int x, int y, int xStep, int yStep) {
    return lengthOfLineStartingAt(x,y,xStep,yStep)
         + lengthOfLineStartingAt(x,y,-xStep,-yStep)
         - 1;
}

(左边作为练习 - 在循环中执行此操作。想出一个方法,将表示8个方向的数字0-7转换为x和y值0或-1)