2011-08-05 24 views
0

我很難從EndLoop()獲取bool完成值並將其移到Start()方法來結束我的while循環。我究竟做錯了什麼?從其他方法獲取bool while循環結束

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 


     public static void Main(string[] args) 
     { 
      Start("r"); 
     } 

     public static string Start(string move) 
     { 

      Console.Write("Welcome to the Shotgun App\nEnter s for single player and m for multiplayer: "); 
      string gameType = Console.ReadLine(); 

      if (gameType == "s") 
      { 

       Console.Write("Single Player Controls:\n r = reload\n s = shield\n f = fire\nYou start with 1 ammo\nReady to play?"); 
       Console.ReadLine(); 

       int ammo = 1; 
       int geniusAmmo = 1; 
       string geniusMove = ""; 
       bool done = false; 
       while (!done) 
       { 
        Console.Write("\nEnter your move: "); 
        move = Console.ReadLine(); 


        switch (move) 
        { 
         case "r": 
          Console.Write("\nYou have reloaded, press enter for Genius\n"); 

          ammo++; 
          Console.Write("Your ammo is " + ammo); 

          Console.ReadLine(); 
          Genius(geniusMove, move, geniusAmmo, done); 


          break; 
         case "s": 
          Console.Write("\nYou have shielded, press enter for Genius\n"); 

          Console.Write("Your ammo is " + ammo); 

          Console.ReadLine(); 
          Genius(geniusMove, move, geniusAmmo, done); 


          break; 
         case "f": 
          if (ammo != 0) 
          { 
           Console.Write("\nYou have fired, press enter for Genius\n"); 

           ammo--; 
           Console.Write("Your ammo is " + ammo); 

           Console.ReadLine(); 

           Genius(geniusMove, move, geniusAmmo, done); 

          } 
          else 
          { 
           Console.Write("You don't have enough ammo, try again"); 
           done = false; 
          } 
          break; 
         default: 
          Console.Write("\nInvalid move, try again\n"); 
          done = false; 
          break; 
        } 

        Console.ReadLine(); 

       } 
       return move; 
      } 
      else 
      { 
       return move; 
      } 
     } 

     public static string Genius(string geniusMove, string move, int geniusAmmo, bool done) 
     { 
      Random RandomNumber = new Random(); 
      int x = RandomNumber.Next(0,3); 
      if (x == 0) 
      { 
       geniusMove = "f"; 
       geniusAmmo--; 
       Console.Write("Genius had decided to fire.\nGenius ammo is " + geniusAmmo + "\n"); 
       TestMoves(move, geniusMove); 
      } 
      else if (x == 1) 
      { 
       geniusMove = "r"; 
       geniusAmmo++; 
       Console.Write("Genius had decided to reload.\nGenius ammo is " + geniusAmmo + "\n"); 
       TestMoves(move, geniusMove); 
      } 
      else if (x == 2) 
      { 
       geniusMove = "s"; 
       Console.Write("Genius had decided to shield.\nGenius ammo is " + geniusAmmo + "\n"); 
       TestMoves(move, geniusMove); 
      } 

      return geniusMove; 

     } 


     public static void TestMoves(string move, string geniusMove) 
     { 
      bool done = false; 
      if (move == "s" && geniusMove == "f") 
      { 
       Console.Write("Nice shield, no one has died yet"); 
       EndLoop(move, geniusMove, done); 


      } 
      else if (move == "f" && geniusMove == "f") 
      { 
       Console.Write("You both died! Good game!"); 
       EndLoop(move, geniusMove, done); 


      } 
      else if (move == "r" && geniusMove == "f") 
      { 
       Console.Write("No shield!? You died! Good game!"); 
       EndLoop(move, geniusMove, done); 


      } 
      else if (move == "f" && geniusMove == "s") 
      { 
       Console.Write("Genius is too good, no one has died yet"); 
       EndLoop(move, geniusMove, done); 


      } 
      else if (move == "f" && geniusMove != "s") 
      { 
       Console.Write("Genius let his guard down! Good game!"); 
       EndLoop(move, geniusMove, done); 


      } 
      else if (move != "f" && geniusMove != "f") 
      { 
       Console.Write("Keep playing it safe."); 
       EndLoop(move, geniusMove, done); 


      } 
      else 
      { 
       EndLoop(move, geniusMove, done); 

      } 

     } 

     public static bool EndLoop(string move, string geniusMove, bool done) 
     { 

      if (move == "s" && geniusMove == "f") 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "s" && geniusMove == "r") 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "s" && geniusMove == "s") 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "r" && geniusMove == "f") 
      { 
       done = true; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "r" && geniusMove == "r") 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "r" && geniusMove == "s") 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "f" && geniusMove == "f") 
      { 
       done = true; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "f" && geniusMove == "r") 
      { 
       done = true; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else if (move == "f" && geniusMove == "s") 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
      else 
      { 
       done = false; 
       Console.Write(move + geniusMove + done); 
       return done; 
      } 
     } 
    } 
} 
+0

何苦在循環歸國做了什麼?設置它應該是足夠的 –

+0

噢,好吧,好點。 –

+0

儘管... –

回答

1

聲明static bool done = false;在你的班級的範圍內,並使用相同的,而不是通過state通過不同的方法。如果將狀態傳遞給調用函數Start,則可以這樣做。

0

當您調用EndLoop時,您需要將bool設置爲靜態和全局,並且設置循環中done的值。

class Program 
{ 
    static bool done = false; 
    // rest of code 
} 

你也應該只是檢查你想要設置爲true的條件並忽略其餘的條件(將其從false更改爲false什麼都不做)。

1

您有兩個名爲done的局部變量。它們是單獨的變量,因此Start中的完成與TestMoves中完成的變量不同。和EndLoop中的參數都不相同。

最好的做法是實際創建一個程序實例,並具有像類成員一樣的通用變量。

如果有一些重要原因讓你希望一切都是靜態的,那麼只需要一個名爲done的靜態類變量,而不是所有的局部變量和參數。

這段代碼還有很多其他的錯誤 - 例如還有其他局部變量和/或參數可以改變其值,但這種改變不會影響調用方法。 if/else if/else的每個分支中都有很多重複的代碼,可以在最後移出一個調用。

2

我知道我沒有直接回答你的問題,但我想我會嘗試給你一個實現你的遊戲的替代方式,使用對象和LINQ,並試圖使代碼更加模塊化。真的是爲了感興趣。

這就是:

void Main() 
{ 
    var moves = new Dictionary<string, Move>() 
    { 
     { "r", new Move(1, "Reloaded") }, 
     { "s", new Move(0, "Shielded") }, 
     { "f", new Move(-1, "Fired") }, 
    }; 

    var messages = new Dictionary<string, string>() 
    { 
     { "Shielded-Fired", "Nice shield, no one has died yet" }, 
     { "Fired-Fired", "You both died! Good game!" }, 
     { "Reloaded-Fired", "No shield!? You died! Good game!" }, 
     { "Shielded-Shielded", "Keep playing it safe." }, 
     { "Fired-Shielded", "Genius is too good, no one has died yet" }, 
     { "Reloaded-Shielded", "No-one fired" }, 
     { "Shielded-Reloaded", "No-one fired" }, 
     { "Fired-Reloaded", "Genius let his guard down! Good game!" }, 
     { "Reloaded-Reloaded", "No-one fired" }, 
    }; 

    var isDone = new Dictionary<string, bool>() 
    { 
     { "Shielded-Fired", false }, 
     { "Fired-Fired", true }, 
     { "Reloaded-Fired", true }, 
     { "Shielded-Shielded", false }, 
     { "Fired-Shielded", false }, 
     { "Reloaded-Shielded", false }, 
     { "Shielded-Reloaded", false }, 
     { "Fired-Reloaded", true }, 
     { "Reloaded-Reloaded", false }, 
    }; 

    var rnd = new Random(); 
    var choices = new [] { "r", "s", "f", }; 

    var human = new Player("You",() => Console.ReadLine(), m => Console.WriteLine(m)); 
    var genius = new Player("Genius",() => choices[rnd.Next(0, 3)], m => { }); 

    var allMoves = GetPlayerMoves(moves, human).Zip(GetPlayerMoves(moves, genius), (h, g) => 
    { 
     human.Play(h); 
     genius.Play(g); 
     var hg = String.Format("{0}-{1}", h.Name, g.Name); 
     Console.WriteLine(messages[hg]); 
     return isDone[hg]; 
    }); 

    foreach (var done in allMoves) 
     if (done) 
      break; 
} 

private static IEnumerable<Move> GetPlayerMoves(Dictionary<string, Move> moves, Player player) 
{ 
    while (true) 
    { 
     player.WriteMessage("\nEnter your move: "); 
     var choice = player.GetChoice(); 
     if (moves.ContainsKey(choice)) 
     { 
      var move = moves[choice]; 
      if (move.Play(player.Ammo) < 0) 
      { 
       player.WriteMessage("\nYou don't have enough ammo, try again.\n"); 
      } 
      else 
      { 
       yield return move; 
      } 
     } 
     else 
     { 
      player.WriteMessage("\nInvalid move, try again.\n"); 
     } 
    } 
} 

public class Player 
{ 
    public Player(string name, Func<string> getChoice, Action<string> writeMessage) 
    { 
     this.Name = name; 
     this.Ammo = 1; 
     _getChoice = getChoice; 
     _writeMessage = writeMessage; 
    } 

    private readonly Func<string> _getChoice; 
    private readonly Action<string> _writeMessage; 

    public string GetChoice() 
    { 
     return _getChoice(); 
    } 

    public void WriteMessage(string message) 
    { 
     _writeMessage(message); 
    } 

    public string Name { get; private set; } 
    public int Ammo { get; private set; } 

    public void Play(Move move) 
    { 
     this.Ammo = move.Play(this.Ammo); 
     Console.Write(String.Format("{0} {1} (ammo is {2}.)\n", this.Name, move.Name.ToLowerInvariant(), this.Ammo)); 
    } 
} 

public class Move 
{ 
    public Move(int ammoChange, string name) 
    { 
     this.AmmoChange = ammoChange; 
     this.Name = name; 
    } 

    public string Name { get; private set; } 

    private int AmmoChange { get; set; } 

    public int Play(int ammo) 
    { 
     return ammo + AmmoChange; 
    } 
}