0
  • 棋盘游戏是一个 11x11 矩阵。
  • 件是白色,黑色,(1)whiteking
  • 可以通过夹住对手来“捕获”一块
    • 例如)黑色棋子的左右或上下有一个白色棋子/白色国王
  • 也可以使用板的边缘或 4 个角件中的任何一个夹住和捕获
    • ex) 白棋子在棋盘的左边缘,然后黑棋子直接移动到白棋子的右侧,这将是一个捕获

到目前为止,我有一个

  • 11 x 11 矩阵
  • (int) 0 = 空,1 = 白色,2 = 黑色,3 = 白化

所以到目前为止我的算法是基本的,检查上/下/左/右,如果是反对,然后再次检查旁边的棋子是否是友好的棋子,如果是,然后捕获。

但是我不能简单地这样做,因为如果这块在 2 个外边缘行或列上,使用上面的算法我会得到一个 ArrayOutofBoundsException 错误。

那么我有一个巨大的if语句来判断这件作品是白色还是黑色。

我只是觉得有一种更简单的方法来优化它.. 作为一个初级程序员,我看不到它。有人可以提出一些建议吗?

如果您查看下面的代码..您可以看到这仅在移动位于外边缘时...如果它位于“1”列/行中,我几乎必须重新复制并粘贴所有内容.. . 然后我终于可以检查 2 个空格上/左/右/下,而不必担心 ArrayOutofBoundsException。

然后我必须再次为 Black Pieces 做所有这些。我的代码看起来真的很草率,我觉得有一种更简单的方法可以做到这一点。有什么建议么?

void makeMove(int typePiece, int fromRow, int fromCol, int toRow, int toCol) {
    board[toRow][toCol] = board[fromRow][fromCol];
    board[fromRow][fromCol] = EMPTY;        

    //CAPTURE
    if(typePiece == WHITE) {
        if(toRow==0) { //top row
            //check right
            if(toCol!=9 && board[toRow][toCol+1]==BLACK && 
                    (toCol==10 || board[toRow][toCol+2]==WHITE || board[toRow][toCol+2]==WHITEKING)) {
                board[toRow][toCol+1]=EMPTY;
            }
            //check left
            if(toCol!=1 && board[toRow][toCol-1]==BLACK && 
                    (toCol==0 || board[toRow][toCol-2]==WHITE || board[toRow][toCol-2]==WHITEKING)) {
                board[toRow][toCol-1]=EMPTY;
            }
            //check bottom
            if(board[toRow-1][toCol]==BLACK && (board[toRow-2][toCol]==WHITE || board[toRow-2][toCol]==WHITEKING)) {
                board[toRow-1][toCol]=EMPTY;
            }
        }
        else if(toRow == 10) { //bottom row
            //check right
            if(toCol!=9 && board[toRow][toCol+1]==BLACK && (toCol==10 || board[toRow][toCol+2]==WHITE || board[toRow][toCol+2]==WHITEKING)) {
                board[toRow][toCol+1]=EMPTY;
            }
            //check left
            if(toCol!=1 && board[toRow][toCol-1]==BLACK && (toCol==0 || board[toRow][toCol-2]==WHITE || board[toRow][toCol-2]==WHITEKING)) {
                board[toRow][toCol-1]=EMPTY;
            }
            //check top
            if(board[toRow+1][toCol]==BLACK && (board[toRow+2][toCol]==WHITE || board[toRow+2][toCol]==WHITEKING)) {
                board[toRow+1][toCol]=EMPTY;
            }
        }
        else if(toCol == 0) { //left column
            //check right
            if(board[toRow][toCol+1]==BLACK && (board[toRow][toCol+2]==WHITE || board[toRow][toCol+2]==WHITEKING)) {
                board[toRow][toCol+1]=EMPTY;
            }
            //check top
            if(toRow!=1 && board[toRow+1][toCol]==BLACK && (board[toRow+2][toCol]==WHITE || board[toRow+2][toCol]==WHITEKING)) {
                board[toRow+1][toCol]=EMPTY;
            }
            //check bottom
            if(toRow != 9 && board[toRow-1][toCol]==BLACK && (board[toRow-2][toCol]==WHITE || board[toRow-2][toCol]==WHITEKING)) {
                board[toRow-1][toCol]=EMPTY;
            }
        }
        else if(toCol == 10) { //right column
            //check left
            if(board[toRow][toCol-1]==BLACK && (toCol==0 || board[toRow][toCol-2]==WHITE || board[toRow][toCol-2]==WHITEKING)) {
                board[toRow][toCol-1]=EMPTY;
            //check top
            if(toRow!=1 && board[toRow+1][toCol]==BLACK && (board[toRow+2][toCol]==WHITE || board[toRow+2][toCol]==WHITEKING)) {
                board[toRow+1][toCol]=EMPTY;
            }
            //check bottom
            if(toRow != 9 && board[toRow-1][toCol]==BLACK && (board[toRow-2][toCol]==WHITE || board[toRow-2][toCol]==WHITEKING)) {
                board[toRow-1][toCol]=EMPTY;
            }
        }
4

3 回答 3

1

您的问题似乎与“围棋”游戏非常相似。

您可以做的是检查“自由”中所谓的内容。自由是一组棋子旁边的一个自由位置。如果一个群体没有更多的自由(被对手包围),那么这个群体就会死亡。

这里有一些关于如何实现它的提示。

当一块被移动时,你检查它的邻居。如果其中一个邻居是对手,

function: hasPieceLiberty(Position piece): return true if one of the neighbours is empty

function: hasGroupLiberty(Position currentPiece):
   add current piece to visited pieces for this group
   if currentPiece.hasPieceLiberty -> return true
   else 
       if currentPiece has no more non visited neighbours for this group -> return false
       else call hasGroupLiberty for non visited neighbours in the group

function: move(Position piece)
   if piece has neighbours that are opponents, check if opponent group has liberties

我希望这会有所帮助

编辑:我注意到你的问题实际上比我最初想的要简单。我认为您必须将对手包围在任何地方,而不仅仅是在一条线的两侧。然后你应该检查 CosmicComputer 的建议

于 2012-07-05T03:47:50.750 回答
1

考虑到一块只能作为另一块移动的结果来捕获。假设您有一个白色棋子移动到与黑色棋子相邻的某个位置(八次检查“我旁边有一个黑色棋子吗?”);此时,检查是否有沿同一条线穿过它的白色棋子(如果黑色棋子在第一个白色棋子下方,则检查第一个黑色棋子正下方是否有另一个白色棋子;如果黑色棋子斜向上并且在右侧,检查黑色块的右侧和上方是否有另一个白色块;等等)。此外,每次移动棋子时,您都需要检查 a) 我周围是否有敌方棋子,如果有,则 b) 它是否在另一侧被另一个敌方棋子镜像?

尝试以下方式:

for all eight directions (up, down, left, right, and the four diagonals):
    is there an enemy piece in that direction adjacent to me?
    if so:
        is there a friendly piece in that direction that is also adjacent to that enemy piece?
        if so:
             remove that piece

for all eight directions:
    is there an enemy piece in that direction adjacent to me?
    if so:
         is there another enemy piece in the opposite direction that is also adjacent to me?
    if so:
         remove me
于 2012-07-05T03:37:33.747 回答
0

当我试图解决这个问题时,一些自定义项有助于清理代码:

structPoint需要一个“x”和一个“y”。方便映射出二维数组的内容。
Operations可以包括分别对“x”和“y”值进行操作的加法、减法等。检查可能有助于确定该点是否是数组的有效索引(给定数组,作为参数)
isValid覆盖ToString()也很好。

包含来自源点的所有所需方向dir4的点数组 ( ,dir8等) 非常适合检查它周围的情况。遍历提供的方向:[ foreach( Point dir in dir4 ){ testPoint = sourcePoint + dir; ... }]。在isValid尝试检查位置的内容以避免出现IndexOutOfBoundsException.

于 2012-07-18T14:28:46.983 回答