2013-03-14 129 views
6

我一直在和我的一位朋友一起玩棋盤遊戲。我們已經設法使其大部分工作。這場比賽被稱爲'jeu de barricade'。也許你知道。棋盤遊戲典當運動算法

使用鏈接列表創建整個董事會,所以每個字段都有一個'LinkNorth','LinkEast','LinkSouth'和'LinkWest'變量。

這是董事會給你一個它的樣子。

Board Screen
現在,有一件事我們似乎無法弄清楚如何去做。目前,可以選擇一個棋子,並將其移動到棋盤上的任何區域。這當然不好。 我們現在需要做的是編寫一種方法,用某種算法返回一個數組或列表中的棋子能夠移動到的字段。這樣,我們可以檢查選中的棋子是否實際上能夠移動到你點擊的區域,擲出的骰子號碼。 (從1到6的隨機數生成)
但還有一件事。每個'Field'類都有一個barricadePawn變量。當這個變量包含一個barricadePawn對象時。 (barricadePawn!= null)典當不應該移動它。棋子應該被允許移動到該場地上,但不能進一步。我們已經實現了,所以不用擔心)

因此,簡而言之,
- 我想在我們的'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)); 
      } 
     } 
    } 

這是我們的「現場」類:

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

一個迭代函數應該這樣做。我需要澄清模具周圍的規則,你可以移動領域的任何數字到模值,或僅由模具指定的字段數量,除非你遇到路障棋子? – Jodrell 2013-03-14 17:27:47

回答

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是一個有效位置時,您需要更加全面,但這是您的基本想法。

上述方法不允許用戶在一次移動中兩次移動到同一地點,但不尋找路障或其他障礙物。它也不處理任何停止移動或在特定方向上不可能移動的點。

但是,它應該讓你知道它應該如何去。

+0

我用你的方法更新了我的getPossibleMoves()方法。 (請參閱主文章)我對它有很好的感覺,但編譯器給我一個錯誤,並不是所有可能的路徑都會返回值。任何想法如何我可以解決這個問題? – Snowy007 2013-03-14 20:32:19

+0

是的。並非所有的代碼路徑都返回一個值。 'else'塊中沒有返回,是嗎?應該在該塊的結尾處返回一些東西。嘗試返回else塊中的retMoves,或者在方法的最後。 – Jeff 2013-03-14 20:38:02

+0

@ Snowy007另外請注意,沒有什麼能夠像在目前的情況下一樣停止多次返回集。你可能想要對列表做些什麼來獲得不同的對象。 – Jeff 2013-03-14 20:40:19

0

像這樣的東西應該這樣做,

它recusively列舉每一個環節,並增加了Field s到一個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; 
    } 
} 

它可以通過省略的向後移動這樣可以防止大量的Add■從HashSet被丟棄的計算來優化。