我和我的一个朋友一直在玩棋盘游戏。我们已经成功地完成了大部分工作。这场比赛被称为'jeu de barricade'。也许你知道。
整个电路板使用链接列表创建,因此每个字段都有一个'LinkNorth','LinkEast','LinkSouth'和'LinkWest'变量。
以下是让您了解其外观的主板。
现在,有一件事我们似乎无法弄清楚该怎么做。目前,可以选择一个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; }
}
}
如果有人可以帮助我们,我们将不胜感激。我们无法想出任何东西。
答案 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
,链接为null
或barrier 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;
}
}
可以通过省略向后移动的计算来优化它,这会阻止大量Add
被HashSet
丢弃。