Connect 4 Java Win 条件检查

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21146940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:55:07  来源:igfitidea点击:

Connect 4 Java Win Conditions check

javagame-engine

提问by user3199712

I have programming assignment where a 2D board game needs to made. The game I am trying to make is a connect 4 game. The problem I have is that I can't seem to get the win conditions to work. Does anybody have any recommendations. I am still relatively new in programming so I am sorry if it is a simple fix. Here is my Code:

我有一个需要制作 2D 棋盘游戏的编程任务。我正在尝试制作的游戏是连接 4 游戏。我的问题是我似乎无法让获胜条件起作用。有没有人有什么建议。我在编程方面仍然相对较新,所以如果这是一个简单的修复,我很抱歉。这是我的代码:

import java.io.*;
import java.net.*;

class C4GameSession implements C4Constants {

private Socket player1;
private Socket player2;


// Create and initialize cells
private char[][] cell =  new char[6][7];

private DataInputStream fromPlayer1;
private DataOutputStream toPlayer1;
private DataInputStream fromPlayer2;
private DataOutputStream toPlayer2;

// Continue to play
private boolean continueToPlay = true;

/** Construct a thread */

public C4GameSession(Socket player1, Socket player2) {

this.player1 = player1;
this.player2 = player2;

// Initialize cells with a blank character

for (int i = 0; i < 42; i++)
  for (int j = 0; j < 42; j++)
    cell[i][j] = ' ';
}

public void runGame() {

try {

  // Create data input and output streams

  DataInputStream fromPlayer1 = new DataInputStream(player1.getInputStream());
  DataOutputStream toPlayer1 = new DataOutputStream(player1.getOutputStream());
  DataInputStream fromPlayer2 = new DataInputStream(player2.getInputStream());
  DataOutputStream toPlayer2 = new DataOutputStream(player2.getOutputStream());

  // Write anything to notify player 1 to start
  // This is just to let player 1 know to start

  // in other words, don't let the client start until the server is ready

  toPlayer1.writeInt(CONTINUE);

  // Continuously serve the players and determine and report
  // the game status to the players

  while (true) {

    // Receive a move from player 1

    int row = fromPlayer1.readInt();
    int column = fromPlayer1.readInt();

    cell[row][column] = 'X';

    // Check if Player 1 wins

    if (isWon('X')) {
      toPlayer1.writeInt(PLAYER1_WON);
      toPlayer2.writeInt(PLAYER1_WON);
      sendMove(toPlayer2, row, column);
      break; // Break the loop
    }
    else if (isFull()) { // Check if all cells are filled
      toPlayer1.writeInt(DRAW);
      toPlayer2.writeInt(DRAW);
      sendMove(toPlayer2, row, column);
      break;
    }
    else {

      // Notify player 2 to take the turn - as this message is not '1' then
      // this will swicth to the relevant player at the client side

      toPlayer2.writeInt(CONTINUE);

      // Send player 1's selected row and column to player 2
      sendMove(toPlayer2, row, column);
   }

    // Receive a move from Player 2
    row = fromPlayer2.readInt();
    column = fromPlayer2.readInt();

    cell[row][column] = 'O';

    // Check if Player 2 wins
    if (isWon('O')) {
      toPlayer1.writeInt(PLAYER2_WON);
      toPlayer2.writeInt(PLAYER2_WON);
      sendMove(toPlayer1, row, column);
      break;
    }
    else {
      // Notify player 1 to take the turn
      toPlayer1.writeInt(CONTINUE);

      // Send player 2's selected row and column to player 1
      sendMove(toPlayer1, row, column);
    }
    }
  }
  catch(IOException ex) {
  System.err.println(ex);
  }
 }

 /** Send the move to other player */
 private void sendMove(DataOutputStream out, int row, int column) throws IOException {

out.writeInt(row); // Send row index
out.writeInt(column); // Send column index
}

/** Determine if the cells are all occupied */

private boolean isFull() {

for (int i = 0; i < 43; i++)
  for (int j = 0; j < 43; j++)
    if (cell[i][j] == ' ')
      return false; // At least one cell is not filled

// All cells are filled
return true;
}

/** Determine if the player with the specified token wins */

private boolean isWon(char token) {

/*
int count = 0;
for (int i = 0; i < 6; ++i) 
for (int j = 0; j < 7; ++j) 
  if (cell[i][j] == token) 
     ++count;
    if (count == 4) 
        return true;  // found
  /* else 
     count = 0; // reset and count again if not consecutive
  */

int count_piece = 0;

    //Checking Horizontal Win
    for (int i = 0; i < 6; i++) {
        count_piece = 0;
        for (int j = 0; j < 7; j++) {

            if (cell[i][j] == 'X') {
                count_piece++;
                if (count_piece == 4) {
                    System.out.println("you win");
                    return true;
                }

            } else {
                count_piece = 0;
            }
          }
        }

     return false;  // no 4-in-a-line found

    }
 }

回答by watery

(I'll write in pseudocode)

(我会用伪代码写)

Start with a simple approach: you need to check for vertical, horizontal and diagonal win, then do three separate check code blocks (you do not need to solve all the problem at once).

从一个简单的方法开始:你需要检查垂直、水平和对角线赢,然后做三个单独的检查代码块(你不需要一次解决所有的问题)。

One for the horizontal direction:

一种用于水平方向:

for(every row)
    count = 0;
    for(each column)
        if(cell value = token)
            then count++;
        else // reset the counting, the eventual sequence has been interrupted
            count = 0;

    if(count >= 4) then win = 1; // you can break out here, when improving you can break out directly in the inner for loop if count is => 4

If no win detected, go for the vertical direction:

如果未检测到获胜,则转到垂直方向:

// similar comments for the previous block apply here
for(every column)
    count = 0;
    for(each row)
        if(cell value = token)
            then count++;
        else
            count = 0;

    if(count >= 4) then win = 1 and break;

If no win detected, go for the diagonal direction:

如果没有检测到胜利,请朝对角线方向走:

// a bit harder, you have to move diagonally from each cell
for(every column from the left)
    for(each row from the top)
        count = 0
            for(delta starting from 0 to 5)
                // add more checks to avoid checking outside the cell matrix bounds
                // when improving the code, you can compute a better end for the delta
                if(cell[row+delta][column+delta] = token)
                    then count++;
                else
                    count = 0;

When you have written and tested all there three pieces, if you want you can gradually improve the algorithm, i.e. starting from the bottom instead of the top row (as most superior cells will be empty for the most part of the game); next, as 4 consecutive cells with the same element must be found, if you, e.g. haven't found enough consecutive tokens when checking a row you may stop earlier instead of going through all the 7 cells in that row.

当您编写并测试了所有三个部分后,如果您愿意,您可以逐渐改进算法,即从底部而不是顶部开始(因为在游戏的大部分时间里,最高级的单元格将是空的);接下来,由于必须找到具有相同元素的 4 个连续单元格,如果您例如在检查一行时没有找到足够的连续标记,您可以提前停止而不是遍历该行中的所有 7 个单元格。

While I'm not giving you the complete solution with working code, I hope my answer will put you on the right track.

虽然我没有为您提供包含工作代码的完整解决方案,但我希望我的回答能让您走上正轨。