我用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()
{
}
}
我尝试了多种思路,但我无法让它发挥作用。如何正确检查?它需要垂直(有意义)水平检查(这也是有意义的),但对角线检查似乎不必要的强硬。
答案 0 :(得分:0)
将有四个验证来检查四行。
所有四种验证的方法都是相同的;扫描所有可能的起点,并查看特定方向上的4个连续部分。理解的关键是:
因此寻找对角线胜利与垂直或水平方法非常相似。这是检查上面验证#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)