当前位置: 首页 > 知识库问答 >
问题:

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

仇正豪
2023-03-14
  • 棋盘游戏是一个11x11矩阵
  • ex)白板左边的白板,然后黑板直接移动到白板的右边,这将是一个捕获

到目前为止,我有一个

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

到目前为止,我的算法是基本的,检查上/下/左/右,如果是对立面,然后检查旁边的那块是否是友好的,如果是,那么抓取。

但我不能简单地这么做,因为如果工件位于两个边缘外的行或列上,使用上述算法,我会得到一个ArrayOutofBoundsException错误。

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

我只是觉得有一个更简单的方法来优化这个。。作为一名初级程序员,我看不到这一点。有人能给点建议吗?

如果你看我下面的代码。。你可以看到这是只有当移动是在外边缘。。。然后我几乎要重新复制和粘贴所有这些,如果它在“1”列/行中。。。然后我终于可以检查上/左/右/下两个空格,而不必担心BoundsException的排列。

我的代码看起来真的很草率,我觉得有一个更简单的方法来做到这一点。有什么建议吗?

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个答案

杜良骏
2023-03-14

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

struct取“x”和“y”。方便绘制二维数组的内容
操作可以包括对“x”和“y”值分别进行的加、减等操作
检查isValid有助于确定点是否是数组的有效索引(给定数组,作为参数)。重写ToString()也很好。

一个点数组包含了来自源代码点的所有期望方向,(dir 4dir 8等)非常适合检查它周围的内容。遍历提供的方向:[Foreach(Dir4中的Point dir){testPoint=Source cePoint dir;...}]。使用isValid在尝试检查位置的内容以避免出现IndexOutOfBoundsExc0019之前,确定Point是否在数组之外。

长孙文栋
2023-03-14

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

你能做的是检查什么是所谓的“自由”。自由是一组碎片旁边的自由之地。如果一个团体没有更多的自由(被对手包围),那么这个团体就会死亡。

下面是一些关于如何实现的提示。

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

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

长孙兴德
2023-03-14

考虑到一块只能作为另一块运动的结果而被捕获。假设你有一块白色的棋子,它会移动到一块黑色棋子旁边的某个位置(八次检查“我旁边有一块黑色棋子吗?”);在这一点上,检查在同一条线上是否有一块白色的碎片(如果黑色碎片在第一块白色碎片下面,检查第一块黑色碎片正下方是否有另一块白色碎片;如果黑色碎片呈对角向上并向右,检查黑色碎片右上方是否有另一块白色碎片;等等)。此外,每次移动一个棋子时,你都需要检查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
 类似资料:
  • null ex)白条在板子的左边缘,然后黑条直接移动到白条的右边,这将是一个捕获 到目前为止我有一个 11 x 11矩阵 (int)0=空,1=白,2=黑,3=白 但是我不能这么简单地做,因为如果这个片段在两个外边的行或列上,使用上面的算法,我会得到一个ArrayOutofBoundsException错误。 然后,我有一个巨大的if语句,用于判断这件作品是白的还是黑的。 我只是觉得有一个更简单的

  • 我对java完全陌生,我想在Java中创建一个单人棋盘游戏。 我已经有很多定义游戏的类,但是对于我的问题,我将把问题限制在为我的棋盘游戏创建GUI板 我非常具体的问题是,基于以下代码: 如何在棋盘游戏中移动玩家?(类播放器存在) 提前感谢您的得体回答。因为我对java非常陌生,请清楚地解释您的答案。 这是以下代码的输出:

  • 我试图为一个棋盘游戏找到一个更好的启发式函数,我将在代码后指定其规则。我的评估功能是: 初始板持有绿色和红色令牌,如图所示。人工智能先移动,使用与你相反的颜色,攻击你的代币。在黑色单元上,令牌可以正交(左、右、上、下)或对角移动。如果是在白血球上,你只能正交移动。 当您将令牌移动到对手令牌旁边时,您将删除该方向上所有对手的令牌。例如,如果我将绿色令牌从 C4 移动到 C5,我将杀死 C-6 到 C

  • 我需要使用JavaSlick库创建一个固定大小的2D网格,例如20x20。目前我有一个包含符号(文本)的数组[]。这些符号代表棋盘上的不同瓷砖(正方形)。 我知道如何在屏幕上渲染/绘制单个图像,但不确定如何在网格上执行相同的操作(循环?对游戏来说渲染不是太多吗?)。我应该研究精灵表的概念吗? 理想情况下,我想创造 平铺对象:平铺、平铺、大小、图像(基于类型) 我不知道如何在屏幕上绘制/渲染它。我应

  • 我只知道大学里的基本java技能,但我想编写一个棋盘游戏(基本上就像垄断游戏),我完全不知道如何开始一些东西,这会产生一些不同的东西(在这种情况下是棋盘游戏),而不仅仅是控制台的东西。我不想要超高的图形,但更多的是在控制台中创建一个带有许多“-”符号的矩形。它应该是2d的,从顶部看。 你有什么建议?你建议我怎么开始?

  • 我刚刚学习了Android和Java编程(里面非常noob),我想问一些关于Android编程和Socket服务器的问题。 我得到一个任务,创建一个简单的国际象棋应用程序(不包括AI),棋子的位置将从TCP套接字中检索: 服务器:xinuc.org 端口:7387 我被告知使用Socket Persistent,因为服务器会在每秒更新典当的位置,典当的位置将以这种格式发送 [卒典][横位][竖位]