为我的Java格仔型棋盘游戏优化我的“捕获”算法

时间:2012-07-05 02:02:35

标签: java algorithm optimization matrix

  • 方格棋盘游戏是11x11矩阵。
  • 件白色,黑色,(1)白化
  • 可以通过夹住对手来“捕获”一块
    • ex)黑色棋子左右两侧或顶部和底部有白色/白色王
  • 也可以使用板的边缘或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;
            }
        }

3 个答案:

答案 0 :(得分:1)

考虑到一件作品只能作为另一件作品的移动而被拍摄。假设你有一块白色的东西移动到与黑色物品相邻的某个位置(8个“我旁边有黑色片段”的检查?);在那一点上,检查沿着同一条线是否有一块白色的碎片(如果黑色碎片在第一块白色碎片下面,检查第一块黑色碎片正下方的另一块白色碎片;如果黑色碎片是斜向上的,在右边,检查另一块白色和黑色的右边;等等。此外,你需要检查一个部件移动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

答案 1 :(得分:1)

您的问题与“Go”游戏非常相似。

你可以做的是检查go“liberties”中的内容。 自由是一组自由的地方。如果一个团体没有更多的自由(被对手包围),那么该团体就会死亡。

以下是有关如何实现这一点的一些提示。

移动一块时,检查其邻居。如果其中一个邻居是对手,

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的提案

答案 2 :(得分:0)

在我尝试解决此问题时,一些自定义项有助于清理代码:

struct Point 采用'x'和'y'。方便绘制二维数组的内容。
Operations可以包含添加,减去等,分别对'x'和'y'值进行操作。
isValid 检查可用于确定该点是否是数组的有效索引(给定数组作为参数)。覆盖 ToString() 也很不错。

从源点(dir4dir8等)保存所有所需方向的点数组非常适合检查周围的内容。迭代提供的指示:[foreach( Point dir in dir4 ){ testPoint = sourcePoint + dir; ... }]。在尝试检查位置内容以避免isValid之前,使用IndexOutOfBoundsException确定Point是否在数组外部。