首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Reversi移动跳棋

Reversi移动跳棋
EN

Code Review用户
提问于 2020-02-06 01:45:30
回答 1查看 813关注 0票数 9

我有这个方法来检查在Reversi中是否可以移动。这个方法可以正常工作,但由于某些原因,它感觉不太正确。感觉很重复。我试图通过其他方法来减少重复,但这并没有让它变得更好。

代码语言:javascript
复制
public bool MovePossible(int y, int x)
{
    //check if position is in field
    if (y > 7 || x > 7 || y < 0 || x < 0) 
    { 
        return false; 
    }

    //check if spot is not occupied
    if(Bord[y, x] != Color.None)
    {
        return false;
    }

    //get color of current turn
    Color color = InTurn;

    //set oppesite color
    Color oppositeColor = Color.Black;
    if (color == Color.Black) oppositeColor = Color.White;

    //check: X, Y + 1
    if (y + 1 <= 7)
    {
        if(Bord[y + 1, x] == oppositeColor)
        {
            for (int i = y + 2; i <= 7; i++)
            {
                if(Bord[i, x] == color)
                {
                    return true;
                }
            }
        }
    }

    //check: X, Y - 1
    if (y - 1 >= 0)
    {
        if (Bord[y - 1, x] == oppositeColor)
        {
            for (int i = y - 2; i >= 0; i--)
            {
                if (Bord[i, x] == color)
                {
                    return true;
                }
            }
        }
    }

    //check: X + 1, Y
    if (x + 1 <= 7)
    {
        if (Bord[y, x + 1] == oppositeColor)
        {
            for (int i = x + 2; i <= 7; i++)
            {
                if (Bord[y, i] == color)
                {
                    return true;
                }
            }
        }
    }

    //check: X - 1, Y
    if (x - 1 >= 0)
    {
        if (Bord[y, x - 1] == oppositeColor)
        {
            for (int i = x - 2; i >= 0; i--)
            {
                if (Bord[y, i] == color)
                {
                    return true;
                }
            }
        }
    }

    //check: X + 1, Y + 1
    if (y + 1 <= 7 && x + 1 <= 7)
    {
        if (Bord[y + 1, x + 1] == oppositeColor)
        {
            var i = y + 2;
            var j = x + 2;

            while (i <= 7 && j <= 7)
            {
                if (Bord[i, j] == color)
                {
                    return true;
                }

                i++;
                j++;
            }
        }
    }

    //check: X - 1, Y - 1
    if (y - 1 >= 0 && x - 1 >= 0)
    {
        if (Bord[y - 1, x - 1] == oppositeColor)
        {
            var i = y - 2;
            var j = x - 2;

            while (i >= 0 && j >= 0)
            {
                if (Bord[i, j] == color)
                {
                    return true;
                }

                i--;
                j--;
            }
        }
    }

    //check: X - 1, Y + 1
    if (y + 1 <= 7 && x - 1 >= 0)
    {
        if (Bord[y + 1, x - 1] == oppositeColor)
        {
            var i = y + 2;
            var j = x - 2;

            while(i <= 7 && j >= 0)
            {
                if (Bord[i, j] == color)
                {
                    return true;
                }

                i++;
                j--;
            }
        }
    }

    //check: X + 1, Y - 1
    if (x + 1 <= 7 && y - 1 >= 0)
    {
        if (Bord[y - 1, x + 1] == oppositeColor)
        {
            var i = y - 2;
            var j = x + 2;

            while (i >= 0 && j <= 7)
            {
                if (Bord[i, j] == color)
                {
                    return true;
                }

                i--;
                j++;
            }
        }
    }

    return false;
}

我想得到一些关于我的代码的反馈,以及如何改进它,减少重复。

编辑:

代码应该做什么?

该方法必须检查磁盘是否可以放置在网格上。这是奥赛罗(或Reversi)比赛的一部分。当以下情况下,该方法必须返回true:

  • Y和x在字段内(所以在0到7之间)
  • 这个地方不能被占用
  • Y和x有一个颜色相反的邻居。例如:我想在3, 3上放置一个黑色磁盘,下面的一个或多个坐标必须是白色的:2, 22, 32, 43, 23, 44, 24, 34, 4
  • 相反颜色的磁盘必须被包围。

举个例子:

代码语言:javascript
复制
         0 1 2 3 4 5 6 7

     0   0 0 0 0 0 0 0 0  
     1   0 0 0 0 0 0 0 0
     2   0 0 0 0 0 0 0 0
     3   0 0 0 2 1 0 0 0
     4   0 0 0 1 2 0 0 0
     5   0 0 0 0 0 0 0 0
     6   0 0 0 0 0 0 0 0
     7   0 0 0 0 0 0 0 0

我想把一个白色的磁盘放在Y: 2,X: 3。这是有效的,因为光点是空的,它在黑色(2)磁盘旁边,黑色磁盘现在被包围了。当磁盘被放置时,网格如下所示:

代码语言:javascript
复制
         0 1 2 3 4 5 6 7

     0   0 0 0 0 0 0 0 0  
     1   0 0 0 0 0 0 0 0
     2   0 0 0 1 0 0 0 0
     3   0 0 0 2 1 0 0 0
     4   0 0 0 1 2 0 0 0
     5   0 0 0 0 0 0 0 0
     6   0 0 0 0 0 0 0 0
     7   0 0 0 0 0 0 0 0

由于黑色磁盘现在被白色磁盘包围,所以磁盘变成了一个白色磁盘(3, 3上的那个),但是更改磁盘发生在另一个函数中,对这个问题并不重要。

另一个例子是:

代码语言:javascript
复制
         0 1 2 3 4 5 6 7

     0   0 0 0 0 0 0 0 0  
     1   0 0 0 0 0 0 0 0
     2   0 0 0 0 0 0 0 0
     3   0 0 0 2 2 2 0 0
     4   0 0 0 1 1 0 0 0
     5   0 0 0 0 1 0 0 0
     6   0 0 0 0 0 0 0 0
     7   0 0 0 0 0 0 0 0

在Y: 4,X: 5放置白色(1)磁盘无效。它在黑色(2)磁盘旁边,但是黑色磁盘不会被包围,因此它是无效的。Y: 2,X: 2将是一个有效的移动,因为在Y: 3,X: 3处的黑盘被Y: 2,X: 2和Y: 4包围。

EN

回答 1

Code Review用户

回答已采纳

发布于 2020-02-06 15:54:58

我还没有检查您在//check: X, Y + 1注释后面的逻辑是否正确,但可以如下所示进行重构。你基本上是在检查8个方向(N,NE,E,SE,S,SW,W,NW),每个方向都是由一个dx和一个dy在-1和1之间唯一识别的。你需要排除dxdy都是0的情况。

代码语言:javascript
复制
dx    -1 0 +1
dy -1 NW N NE
    0  W .  E
   +1 SW S SE

这会给出这样的代码:

代码语言:javascript
复制
for (int dx = -1; dx <= 1; dx++) {
    for (int dy = -1; dy <= 1; dy++) {
        if (dx == 0 && dy == 0)
            continue;

        if (x + dx < 0 || x + dx > 7 || y + dy < 0 || y + dy > 7)
            continue;

        if (Bord[y + dy, x + dx] != oppositeColor)
            continue;

        int i = 2;
        while (i <= 7)
        {
            if (x + i * dx < 0 || x + i * dx > 7 || y + i * dy < 0 || y + i * dy > 7)
                break;
            if (Bord[y + i * dy, x + i * dx] == Color.None)
                break;
            if (Bord[y + i * dy, x + i * dx] == color)
            {
                return true;            
            }
            i++;
        }
    }
}
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/236759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档