去棋盘游戏 - 递归棋盘组检查

时间:2014-03-20 20:56:14

标签: c# arrays recursion

创建一个Go棋盘游戏,但我一直在检查董事会是否已被包围的石头组。为此,我认为我需要提出一些递归功能:

(更新)

public List<Point> FindSurrounded(Board board, Point p, Player player, List<Point> group)
{
    int[,] b = board.board;
    for (int dx = -1; dx <= 1; dx++){
        for (int dy = -1; dy <= 1; dy++)
        { 
            //check if group allready contain this spot
            if (p.X + dx < board.width && p.Y + dy < board.height && p.X + dx > 0 && p.Y + dy > 0 && (dy == 0 || dx == 0) && !(dy == 0 && dx == 0) && !group.Contains(new Point(p.X + dx, p.Y + dy))) 
            {
                // is the spot empty 
                if (b[p.X + dx, p.Y + dy] == 0)
                    return null;

                //check the suroundings of this spot and add them to the group
                //if(b[p.X + dx, p.Y + dy] != player.Identifier)// is there an enemy on this spot
                //    return new List<Point>();

                if (b[p.X + dx, p.Y + dy] != player.Identifier)
                {
                    group.Add(new Point(p.X + dx, p.Y + dy));
                    List<Point> temp = FindSurrounded(board, new Point(p.X + dx, p.Y + dy), player, new List<Point>());
                    if (temp == null)
                        return null;
                    //group.AddRange(temp);
                }
            }
        }
    }
    return group;
}

但是当我放置围绕对手石头的石头时,此代码会给我一个 System.StackOverFlowException 错误。错误将涉及以下行:

            if (p.X + dx < board.width && p.Y + dy < board.height && p.X + dx > 0 && p.Y + dy > 0 && (dy == 0 || dx == 0) && !(dy == 0 && dx == 0) && !group.Contains(new Point(p.X + dx, p.Y + dy))) 

但我不知道为什么。

有谁知道我可以检查电路板上的一组石头是否被包围的方式?

提前致谢!

祝你好运, Skyfe。

编辑:忘记提及我仍然需要创建一个数组来临时存储所有找到的组合在一起的石头,以便在它们被包围时将它们从板上移除。

3 个答案:

答案 0 :(得分:1)

回答具体问题:

  

有谁知道我可以检查板上的一组石头是否被包围的方式?

尝试这种方法:

    Board b;

    int N, M; // dimensions
    int timer;
    int[,] mark; // assign each group of stones a different number

    int[,] mov = // constant to look around
    {
        { 0, -1 }, { 0, +1 },
        { -1, 0 }, { +1, 0 }
    };

    // Checks for a group of stones surrounded by enemy stones
    // Returns the first group found or null if there is no such group.
    public List<Point> CheckForSurrounded()
    {
        mark = new int[N,M];

        for (int i = 0; i < b.SizeX; ++i)
            for (int j = 0; j < b.SizeX; ++j)
                if (mark[i, j] == 0) // not visited
                {                        
                    var l = Fill(i, j);
                    if (l != null)
                        return l;
                }

        return null;
    }

    // Marks all neighboring stones of the same player in cell [x,y]
    // Returns the list of stones if they are surrounded
    private List<Point> Fill(int x, int y)
    {
        int head = 0;
        int tail = 0;
        var L = new List<Point>();

        mark[x, y] = ++timer;
        L.Add(new Point(x,y));

        while (head < tail)
        {
            x = L[head].X;
            y = L[head].Y;
            ++head;

            for (int k = 0; k < 4; ++k)
            {
                // new coords
                int xx = x + mov[k,0];
                int yy = y + mov[k,1];

                if (xx >= 0 && xx < N && yy >= 0 && yy < M) // inside board
                {
                    if (mark[xx, yy] == 0) // not visited
                    {
                        if (b[xx, yy].IsEmpty) // if empty square => not surrounded
                            return null;
                        if (b[xx, yy].IsMine)
                        {
                            L.Add(new Point(xx,yy)); // add to queue
                            mark[xx, yy] = timer; // visited
                            ++tail;
                        }
                    }
                }
            }
        }

        // the group is surrouneded
        return L;
    }

此方法不使用递归,因此您不必处理堆栈溢出(不是站点的例外)。

答案 1 :(得分:0)

您可以使用执行此类操作的代码来执行此操作。

伪代码

    isSurrounded(stone){
          //mark that you have seen the stone before
          stone.seen = true;
          //check if all the surrounding spots are surrounded
          for(spot in surrounded.getSpotsAround){
              //An empty spot means the stone is not surrounded
              if(spot = empty){
                 return false;
              }
              else{
                 //don't recheck stones you have seen before or opponents stones
                 if(spot.stone.seen != true || !stone.belongsToOpponent){
                     //recursively call this method, if it returns false your stone is not surrounded
                     if(!isSurrounded(spot.stone){
                        return false;
                     }
                 }
              }
          }
          //if all of the surrounding stones are surrounded,seen already, or belong to other players, this stone is surrounded
          return true;
}

然后你必须移除所有看到=或在所有石头上看到的重置的石头。

答案 2 :(得分:0)

我想出了这个

<强>(更新)

public List<Point> FindSurrounded(int[,] b, Point p, Player player, List<Point> group)
{
    for (int dx = -1; dx <= 1; dx++){
        for (int dy = -1; dy <= 1; dy++)
        { 
            //check if group allready contain this spot
            if ((dy == 0 || dx == 0) && !(dy == 0 && dx == 0) && !group.Contains(new Point(p.X + dx, p.Y + dy)) 
            {
                // is the spot empty 
                if( b[p.X + dx, p.Y + dy] == 0) 
                    return null;

                if(b[p.X + dx, p.Y + dy] == player.Identifier)// is this your own stone
                {
                    //If this is my stone add it to the list and check for it
                    group.Add( new Point( p.X + dx, p.Y + dy ) );
                    List<Point> temp = removeSurrounded(b, new Point(p.X + dx, p.Y + dy), player, group);
                    if(temp == null)
                        return null;
                }
            }
        }
    }
    return group;
}

如果您的组附近有空位,则返回null,否则它将返回代表您的组的Points列表。

之后你可以像那样删除它们

List<Point> group = FindSurrounded(b, p, player, new List<Point>());
if(group != null)
    foreach(Point point in group)
        b[point.x, point.y] = 0;