棋盘棋子运动算法

时间:2013-03-14 17:19:54

标签: c# wpf algorithm

我和我的一个朋友一直在玩棋盘游戏。我们已经成功地完成了大部分工作。这场比赛被称为'jeu de barricade'。也许你知道。

整个电路板使用链接列表创建,因此每个字段都有一个'LinkNorth','LinkEast','LinkSouth'和'LinkWest'变量。

以下是让您了解其外观的主板。

Board Screen
现在,有一件事我们似乎无法弄清楚该怎么做。目前,可以选择一个pawn,它可以移动到板上的任何字段。这当然不好。 我们现在需要做的是编写一种方法,使用某种算法返回一个数组或pawn能够移动到的字段列表。通过这种方式,我们可以检查所选的pawn是否实际上能够移动到您单击的字段,并使用抛出的骰子编号。 (产生从1到6的随机数)
还有一件事。每个'Field'类都有一个barricadePawn变量。当此变量包含barricadePawn对象时。 (barricadePawn!= null)pawn不应该在它上面移动。应该允许棋子移动到那个领域,但不能再进一步。 (当玩家完全落在路障上时,他可以移动它。但我们已经实现了这一点,所以不要担心)

所以,简而言之 - 我想在我们的'Pawn'类中创建一个方法,它返回一个数组或列表,其中包含pawn应该能够移动到的所有字段。
- 典当应该能够在路障上移动但不能在路障上移动。
- 棋子必须完全移动骰子投掷的数量。所以,要完成任务或在路障上,你必须投入恰当的数量。

我们在'Pawn'课程中有这些:
'currentLocation'包含所选pawn当前所在的字段。

private Model.Field startLocation;
private Model.Field currentLocation; 

public List<Model.Field> getPossibleMoves(Model.Field curSpot, int remainingMoves, List<Model.Field> moveHistory)
    {
        List<Model.Field> retMoves = new List<Model.Field>();
        if( remainingMoves == 0 )
        {
            retMoves.Add(curSpot);
            return retMoves;
        }
        else
        {
            moveHistory.Add(curSpot);
            if( curSpot.LinkNorth != null && !moveHistory.Contains(curSpot.LinkNorth) )
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkNorth, remainingMoves - 1, moveHistory ));
            }

            if (curSpot.LinkEast != null && !moveHistory.Contains(curSpot.LinkEast))
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkEast, remainingMoves - 1, moveHistory ));
            }

            if (curSpot.LinkSouth != null && !moveHistory.Contains(curSpot.LinkSouth))
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkSouth, remainingMoves - 1, moveHistory ));
            }

            if (curSpot.LinkWest != null && !moveHistory.Contains(curSpot.LinkWest))
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkWest, remainingMoves - 1, moveHistory ));
            }
        }
    }

这是我们的'Field'课程:

public class Field
    {
        protected Field linkNorth, linkEast, linkSouth, linkWest;
        protected Controller.Pawn pawn;
        protected Model.BarricadePawn barricadePawn;
        protected int x, y;

        //Properties:
        public Field LinkNorth
        {
            get { return linkNorth; }
            set { linkNorth = value; }
        }
        public Field LinkEast
        {
            get { return linkEast; }
            set { linkEast = value; }
        }
        public Field LinkSouth
        {
            get { return linkSouth; }
            set { linkSouth = value; }
        }
        public Field LinkWest
        {
            get { return linkWest; }
            set { linkWest = value; }
        }
        public Controller.Pawn Pawn
        {
            get { return pawn; }
            set { pawn = value; }
        }
        public BarricadePawn Barricade
        {
            get { return barricadePawn; }
            set { barricadePawn = value; }
        }
        public int X
        {
            get { return x; }
            set { x = value; }
        }
        public int Y
        {
            get { return y; }
            set { y = value; }
        }
    }

如果有人可以帮助我们,我们将不胜感激。我们无法想出任何东西。

2 个答案:

答案 0 :(得分:4)

尝试创建递归方法。

List<Spot> CheckMoves(Spot curSpot, int remainingMoves, List<Spot> moveHistory)
{
    List<Spot> retMoves = new List<Spot>();
    if( remainingMoves == 0 )
    {
        retMoves.Add(curSpot);
        return retMoves;
    }
    else
    {
        moveHistory.Add(curSpot);
        if( !moveHistory.Contains(Spot.North) )
        {

            retMoves.AddRange( CheckMoves( Spot.North, remainingMoves - 1, moveHistory );
        }
        /* Repeat for E, W, S */
    }
}

这将返回一个List(其中spot是表示板上位置的类),其中包含所有潜在的最终位置。当然,你需要更加彻底地确保Spot.North是一个有效的位置,但这对你来说是一个基本的想法。

上述方法不允许用户在一次移动中两次移动到同一地点,但不会寻找路障或其他障碍物。它也不处理任何停止运动或在特定方向上无法移动的点。

但是,它应该让你知道它应该如何发展。

答案 1 :(得分:0)

这样的事情应该这样做,

它会重复枚举每个链接并将Field添加到HashSet以防止重复。当worp倒计时到0,链接为nullbarrier pawn时,递归会停止。

public IList<Field> GetPossibleMoves(int worp)
{
    var valid = new HashSet<Field>();

    foreach (var f in GetPossibleMoves(current.LinkNorth, worp))
    {
        valid.Add(f);
    }

    foreach (var f in GetPossibleMoves(current.LinkEast, worp))
    {
        valid.Add(f);
    }

    foreach (var f in GetPossibleMoves(current.LinkSouth, worp))
    {
        valid.Add(f);
    }

    foreach (var f in GetPossibleMoves(current.LinkWest, worp))
    {
        valid.Add(f);
    }

    return valid.ToList();
}

private static IEnumerable<Field> GetPossibleMoves(Field current, int worp)
{
    if (current == null)
    {
        yield break;
    }

    yield return current;

    if (worp == 0 || current.BarricadePawn) // is that a bool?
    {
        yield break;
    } 

    foreach (var f in GetPossibleMoves(current.LinkNorth, nextWorp))
    {
        yield return f;
    }

    foreach (var f in GetPossibleMoves(current.LinkEast, nextWorp))
    {
        yield return f;
    }

    foreach (var f in GetPossibleMoves(current.LinkSouth, nextWorp))
    {
        yield return f;
    }

    foreach (var f in GetPossibleMoves(current.LinkWest, nextWorp))
    {
        yield return f;
    }
}

可以通过省略向后移动的计算来优化它,这会阻止大量AddHashSet丢弃。