2017-09-08 4 views
-1

現在、戦艦ボーンズモジュールをC#で作成しようとしていますが、大部分のコードはうまく処理されていますが、ヒットとミスをマークしようとしていますプレイヤーが正しくまたは間違って推測するたびにC#戦艦グリッドとケース実装の問題

私がしようとしているのは、人々が適切なグリッド座標を入力するとケース "H"とケース "M"をアクティブにすることです。

コードはC#にあります。

基本戦艦を:起こってすることになっているもの

。これはC#の私の最初の本当のプロジェクトであり、船を隠すことは私にとって重要ではありません。私はちょうど船の座標がケースHとケースMに割り当てられた適切なXとバックグラウンド/フォアグラウンドカラーに置き換えられるのに苦労しています。

何か不足していて追加情報が必要な場合は、私は知っている!

これは、これまで私が持っているコードです:

class Program 
{ 
    static void Main(string[] args) 
    { 
     while (true) 
     { 

      //Basic function that allows the user to enter their 'guesses' for the ship locations. 
      printGrid(Grid); 
      Console.WriteLine("Type 'exit' to exit."); 
      Console.WriteLine("Enter your guess: "); 
      string cons = Console.ReadLine(); 
      cons.Substring(0, 1); 
      cons.Substring(1, 1); 
      cons = cons.ToUpper(); 
      char column = cons[0]; 
      char row = cons[1]; 
      int num = cons[0]; 
      bool result = Int32.TryParse(cons, out num); 

      //Disallows the user from entering anything other than what's valid. Valid characters are, obviously, A - J. 
      string validChars = "ABCDEFGHIJ"; 

      //This allows the user to exit the application by typing "Exit" instead of guessing. 
      if (cons == "EXIT") 
      { 
       return; 
      } 

      //Again, checks to see if the user inputs any numbers higher than what's allotted. 
      else if (!validChars.Contains(column) || (num >= 11)) 
      { 
       Console.WriteLine("Please enter only A-J, and 1-10 e.g 'B5'"); 
      } 
      Console.WriteLine("Column = {1}, Row = {0}", row, column); 

     if (result == false) 
      { 
       Console.WriteLine("Guess was a miss!"); 
      } 
      else 
      { 
       Console.WriteLine("Guess was a hit!"); 
      } 

     } 
    } 
    private static readonly char[,] Grid = new char[,] 
    { 
     {'.', '.', '.', '.', 'S', 'S', 'S', '.', '.', '.'}, 
     {'P', 'P', '.', '.', '.', '.', '.', '.', '.', '.'}, 
     {'.', '.', '.', '.', '.', '.', '.', '.', '.', 'P'}, 
     {'.', '.', '.', '.', '.', '.', '.', '.', '.', 'P'}, 
     {'.', '.', 'A', 'A', 'A', 'A', 'A', '.', '.', '.'}, 
     {'.', '.', '.', '.', '.', '.', '.', 'B', '.', '.'}, 
     {'.', 'S', '.', '.', '.', '.', '.', 'B', '.', '.'}, 
     {'.', 'S', '.', '.', '.', '.', '.', 'B', 'P', 'P'}, 
     {'.', 'S', '.', '.', '.', '.', '.', 'B', '.', '.'}, 
     {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.'}, 
    }; 
    public static void printGrid(Char[,] Grid) 
    { 

     //Let's make the layout pretty. 
     Console.WriteLine("  | A | B | C | D | E | F | G | H | I | J |"); 
     Console.WriteLine("-----#-----#-----#-----#-----#-----#-----#-----#-----#-----#------#"); 

     for (int i = 0; i < 10; i++) 
     { 
      if (i == 9) 
      { 
       Console.Write(" {0} ", i + 1); 
      } 
      else 
       Console.Write(" {0} ", i + 1); 
      for (int j = 0; j < 10; j++) 
      { 
       ShipColors(Grid[i, j]); 
      } 

      //This needs to match the header in order to format properly. 
      Console.Write(" |\r\n"); 
      Console.WriteLine("-----#-----#-----#-----#-----#-----#-----#-----#-----#-----#------#"); 
     } 
    } 

    //Now we're going to declare which colors each ship's cell is going to be. 
    public static void ShipColors(char useThis) 
    { 
     /* 
     * Legend for each ship name: 
     * P = patrol boat 
     * S = Submarine 
     * B = Battleship 
     * A = Aircraft Carrier 
     */ 
     switch(useThis) 
      //Going to use case statements here to automatically color any of the grid's cells with any special characters. 
      //Using cases allows the grid to be re-organized and still be colored properly. 
     { 
      case '.': 
       Console.Write(" | "); 
       //Blank space here needed to be added for formatting the cells properly. 
       Console.Write(" "); 
       break; 
      case 'A': 
       Console.Write(" | "); 
       Console.BackgroundColor = ConsoleColor.Blue; 
       Console.Write(" A "); 
       break; 
       case 'B': 
       Console.Write(" | "); 
       Console.BackgroundColor = ConsoleColor.Green; 
       Console.ForegroundColor = ConsoleColor.Black; 
       Console.Write(" B "); 
       break; 
      case 'P': 
       Console.Write(" | "); 
       Console.BackgroundColor = ConsoleColor.Yellow; 
       Console.ForegroundColor = ConsoleColor.Black; 
       Console.Write(" P "); 
       break; 
      case 'S': 
       Console.Write(" | "); 
       Console.BackgroundColor = ConsoleColor.Red; 
       Console.ForegroundColor = ConsoleColor.Black; 
       Console.Write(" S "); 
       break; 
      case 'H': 
       Console.Write(" | "); 
       Console.ForegroundColor = ConsoleColor.Red; 
       Console.Write(" X "); 
       break; 
      case 'M': 
       Console.Write(" | "); 
       Console.ForegroundColor = ConsoleColor.White; 
       Console.Write(" X "); 
       break; 

     } 
     Console.ResetColor(); 
    } 
} 
+1

私はいくつかの問題を見ることができますが、それらはすべてデバッガを使用してコードをクリーンアップするだけで検出可能でなければなりません。きれいなコードの例では、 'cons.Substring(1,1);'という行があり、これはsomethignに割り当てられずに何もせず、他の同様の行を削除することができます。 'int num = cons [0];'行はコンス[0](文字列の最初の文字であるchar)をとり、アスキー表現であるintに変換します。おそらくあなたが望むものではありません。 – Chris

+1

あなたの行 'bool result = Int32.TryParse(cons、out num);'はおそらくあなたが望むことをしません。 consは、あなたが "A1"のようなものになると期待している入力ですので、整数として解析することはできません。代わりに、数値を含む部分文字列を解析したいと思っていたかもしれません(おそらく、以前の部分文字列呼び出しを割り当てたはずです)。これらの問題の多くは、デバッガを使用して実行されるプログラムの状態を調べるだけで検出されます。あなたはnumが疑わしい価値を持っていて、調査しているのを見ることができました。 – Chris

+0

最後に、スタックのオーバーフローに関する質問をするときに、それらを特定のままにしてください。この質問はかなり漠然としています。「私は、船の座標をケースHとケースMに割り当てられている適切なXとバックグラウンド/フォアグラウンドカラーに置き換えるだけで苦労しています。この質問は本当に私に何も言わない。 「私は苦労している」とは、「どこから始めるのかわからない」から「私の検証が失敗している」から「それを実行するたびに私のハードドライブを再フォーマットする」などです。質問は正確でなければなりません "TryParseはなぜ1の代わりに49を返し続けますか?彼らは簡単に答えられるように... – Chris

答えて

0

あなたは一つの方法で多くのことをやろうとしています。理想的には、入力を検証するメソッド、ヒットを確認するメソッド、グリッドを直前に推測したスポットの指標で再描画するメソッドなど、いくつかのメソッド呼び出しに分解するのが理想的です。

しかし、あなたが入力が正しかったことの検証をやった後に、この特定の問題を支援するために、あなただけのような何か実行する必要があります。

  1. インデックスに入力行を変換します。 1で始まる行を表示しますが、配列インデックスは0で始まるので、入力から1を引く必要があります。
  2. 入力列をインデックスに変換します。文字Aはint値が65であり、Aが最初の行であることから、インデックスを取得するために列から65を引きます。

そして、それは文字が含まれているかどうかを確認するために、インデックス[newRow, newCol]で私達のGrid配列内のチェックの問題だ:

:ここ

if (char.IsLetter(Grid[rowNumber, colNumber])) 
{ 
    Console.WriteLine("HIT!"); 
} 
else 
{ 
    Console.WriteLine("MISS."); 
} 

はあなたのコードの半クリーンアップバージョンです。

while (true) 
{ 
    Console.Write("Enter your guess: "); 
    string userGuess = Console.ReadLine().ToUpper(); 
    if (userGuess == "EXIT") return; 

    int rowNumber; 

    // Validate input 
    if (userGuess.Length < 2 || userGuess.Length > 3) 
    { 
     Console.WriteLine("Guess must be in the form of ColumnRow, like: B5"); 
    } 
    else if (!"ABCDEFGHIJ".Contains(userGuess[0])) 
    { 
     Console.WriteLine("Guess must begin with a valid column letter (A-J)"); 
    } 
    else if (!int.TryParse(userGuess.Substring(1), out rowNumber) 
      || rowNumber < 1 || rowNumber > 10) 
    { 
     Console.WriteLine("Guess must end with a valid row number (1-10)"); 
    } 
    else 
    { 
     // Valid input! Set actual indexes for the guess 
     int colNumber = userGuess[0] - 65; 
     rowNumber--; 

     if (char.IsLetter(Grid[rowNumber, colNumber])) 
     { 
      Console.WriteLine("HIT!"); 
     } 
     else 
     { 
      Console.WriteLine("MISS."); 
     } 
    } 
} 
+0

ルーファス、これは完璧です!私のためにBarneyスタイルを破ってくれてありがとう、ありがとう。 C#の初心者の方では、初心者がたいていの場合ヒットしてしまうようなマイナス面があるため、ここに投稿するのはちょっと躊躇しました。あなたの解決策は、私が持っていたすべての質問を明らかにしただけでなく、私が長年煮詰めてきたスパゲッティのきれいなバージョンを提供しました。ありがとうございました! –