2013-03-14 4 views
6

मैं अपने एक दोस्त के साथ बोर्ड गेम पर काम कर रहा हूं। हमने इसे अधिकतर काम करने में कामयाब रहा है। खेल को 'जेयू डी बैरिकेड' कहा जाता है। शायद आप इसे जानते हैं।बोर्ड गेम पॉन आंदोलन एल्गोरिदम

पूरा बोर्ड एक लिंक्ड लिस्ट का उपयोग करके बनाया जाता है, इसलिए प्रत्येक फ़ील्ड में 'लिंकनर्थ', 'लिंकएस्ट', 'लिंकसाउथ' और 'लिंकवेस्ट' चर होता है।

बोर्ड आपको यह बताने के लिए बोर्ड है कि यह कैसा दिखता है।

Board Screen
अब, वहाँ एक बात हम सिर्फ कैसे करना है यह पता लगाने नहीं कर पा रहे है। वर्तमान में, एक पंख का चयन किया जा सकता है, और इसे बोर्ड पर किसी भी क्षेत्र में ले जाया जा सकता है। यह निश्चित रूप से अच्छा नहीं है। हमें अब क्या करने की ज़रूरत है, कुछ प्रकार के एल्गोरिदम के साथ एक विधि लिखती है जो कि एक सरणी या फ़ील्ड की सूची देता है जो पंख आगे बढ़ने में सक्षम होता है। इस तरह, हम जांच सकते हैं कि चयनित पॉन वास्तव में उस क्षेत्र में जाने में सक्षम है, जिस पर आपने डाला नंबर डाला था। (1 से 6 तक एक यादृच्छिक संख्या उत्पन्न होती है)
हालांकि एक और बात। प्रत्येक 'फील्ड' कक्षा में एक barricadePawn चर है। जब इस चर में एक barricadePawn वस्तु होती है। (barricadePawn! = शून्य) पंख इसे आगे बढ़ने में सक्षम नहीं होना चाहिए। पंख को उस क्षेत्र में जाने की अनुमति दी जानी चाहिए, लेकिन आगे नहीं। (जब खिलाड़ी बिल्कुल बार्केड पर उतरता है, तो वह इसे स्थानांतरित कर सकता है। लेकिन हमने इसे पहले ही कार्यान्वित किया है, इसलिए इसके बारे में चिंता न करें)

तो, संक्षेप में।
- मैं अपने 'Pawn' वर्ग में एक विधि बनाना चाहता हूं, जो कि उन सभी क्षेत्रों की एक सरणी या सूची देता है जो पंख को स्थानांतरित करने में सक्षम होना चाहिए।
- पंख बार्केड पर जाने में सक्षम होना चाहिए लेकिन उन पर नहीं।
- पंजा को पासा द्वारा फेंकने वाली राशि को ठीक से स्थानांतरित करना होता है। तो, खत्म होने या बार्केड पर पहुंचने के लिए, आपको बिल्कुल सही राशि फेंकनी होगी।

हमारे पास इन्हें हमारे 'Pawn' वर्ग में है:
'वर्तमान स्थान' में वह फ़ील्ड शामिल है जो चयनित पॉन वर्तमान में खड़ा है।

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; } 
     } 
    } 

किसी को भी इस के साथ हमें मदद कर सकता है, यह बहुत सराहना की जाएगी:

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)); 
      } 
     } 
    } 

और यह हमारी 'फील्ड' वर्ग है। हम कुछ भी करने में सक्षम नहीं हैं।

+0

एक पुनरावृत्त कार्य इसे करना चाहिए। मुझे मरने के नियमों को स्पष्ट करने की आवश्यकता होगी, क्या आप किसी भी संख्या में खेतों को मरने के मूल्य तक ले जा सकते हैं, या केवल मरने द्वारा निर्दिष्ट फ़ील्ड की संख्या को तब तक ले जा सकते हैं, जब तक कि आपको बार्केड पॉन न मिले? – Jodrell

उत्तर

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 */ 
    } 
} 

यह एक सूची लौटाएगा (जहां स्पॉट वह वर्ग है जो बोर्ड पर स्थिति का प्रतिनिधित्व करता है) जिसमें सभी संभावित अंतिम पद शामिल हैं। बेशक आपको यह सुनिश्चित करने में थोड़ा और गहन होना होगा कि Spot.North एक वैध स्थान है, लेकिन यह आपके लिए एक बुनियादी विचार है।

ऊपर दी गई विधि उपयोगकर्ता को एक ही स्थान पर दो बार एक ही स्थान पर जाने की अनुमति नहीं देगी, लेकिन बार्केड या अन्य बाधाओं की तलाश नहीं करती है। यह किसी भी धब्बे को नियंत्रित नहीं करता है जो आंदोलन को रोकता है या किसी विशेष दिशा में कोई संभावित आंदोलन नहीं करता है।

हालांकि, आपको यह विचार करना चाहिए कि इसे कैसे जाना चाहिए।

+0

मैंने अपनी विधि के साथ मेरी getPossibleMoves() विधि अपडेट की है। (मुख्य पोस्ट देखें) मुझे इसके बारे में अच्छी भावना है, लेकिन संकलक मुझे एक त्रुटि दे रहा है कि सभी संभावित पथ वापसी मूल्य नहीं देते हैं। कुछ अनुमान है इसे कैसे ठीक किया जा सकता है? – Snowy007

+0

हां। सभी कोड पथ एक मूल्य वापस नहीं करते हैं। 'Else' ब्लॉक में कुछ भी वापस नहीं किया गया है, है ना? उस और ब्लॉक के अंत में कुछ वापस किया जाना चाहिए। अन्य ब्लॉक में, या विधि के बहुत अंत में retMoves लौटने का प्रयास करें। – Jeff

+0

@ Snowy007 यह भी ध्यान दें कि रिटर्न सेट में होने से एक ही स्थिति को कई बार रोकना कुछ नहीं है, क्योंकि यह वर्तमान में खड़ा है। आप विशिष्ट वस्तुओं को प्राप्त करने के लिए शायद सूची में कुछ करना चाहते हैं। – Jeff

0

कुछ इस यह करना चाहिए की तरह,

यह recusively प्रत्येक लिंक विश्लेषण करता है और एक HashSet को Field रों कहते हैं डुप्लिकेट को रोकने के लिए। रिकर्सन बंद हो जाता है, worp0 पर गिना जाता है, लिंक 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 से खारिज कर दिया जा रहा है रोका जा सके की गणना को छोड़ते हुए द्वारा अनुकूलित किया जा सकता है।

संबंधित मुद्दे