2017-09-08 1 views
-1

전 C#으로 전함 뼈대 모듈을 만들려고하는데 대다수의 코드가 잘 풀 렸지만 히트와 미스를 표시하려고 할 때가 많습니다. 플레이어가 올 바르고 틀린 것을 추측 할 때마다 코드를 작성하십시오.C# 전함 그리드 및 사례 구현 문제

사람들이 적절한 그리드 좌표를 입력 할 때 Case "H"와 Case "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];'줄은 cons [0] (문자열의 첫 번째 문자 인 char)을 취해 ASCII 표현 인 int로 변환합니다. 아마도 원하는 것이 아닐 수도 있습니다. – Chris

+1

그러면'bool result = Int32.TryParse (cons, out num);'라는 라인이 당신이 원하는대로하지 않을 것입니다. 단점은 "A1"과 같은 것으로 기대되는 입력이므로 정수로 파싱 할 수 있다고 기대할 수는 없습니다. 대신 아마 숫자를 포함하고있는 부분 문자열을 파싱하기를 원할 것입니다 (어쩌면 우리는 그 부분 문자열을 미리 somethign에 할당해야했습니다). 이러한 문제는 디버거를 사용하여 실행되는 프로그램의 상태를 검사함으로써 많은 문제를 발견 할 수있었습니다. 당신은 num이 의심스러운 가치를 지니고 조사했음을 알았을 것입니다. – Chris

+0

마지막으로 스택 오버플로에 대해 질문 할 때 특정 스택을 계속 사용하려고 시도 할 때. 이 질문은 매우 모호합니다. "저는 선박의 좌표가 사례 H와 사례 M에 지정된대로 적절한 X 및 배경/전경색으로 대체되는 데 어려움을 겪고 있습니다." 이 질문은 내게 아무 것도 말해주지 않습니다. "나는 고심하고있다"는 말은 "어디서부터 시작해야할지 모르겠다"에서 "내 검증이 실패했다"에서 "실행할 때마다 내 하드 드라이브를 다시 포맷한다"등의 모든 것일 수 있습니다. 질문은 정확해야합니다 "TryParse가 1 대신 49를 계속 반환하는 이유는 무엇입니까?" 그래서 그들은 쉽게 대답 할 수 있습니다 ... – Chris

답변

0

:

내가 지금까지 가지고있는 코드입니다. 이상적으로는 입력을 확인하는 메소드, 히트를 확인하는 메소드, 방금 추측 한 지점의 일부 표시기로 그리드를 다시 그리는 메소드 등 여러 메소드 호출로 구분할 수 있습니다.

  1. 인덱스에 입력 행을 변환 : 당신이 입력이 정확하다고 검증을 완료 한 후에

    그러나이,이 특정 문제에 도움이, 당신은 같은 것을 할 필요가있다. 1으로 시작하는 행을 표시하지만 배열 색인은 0으로 시작하므로 입력에서 하나를 뺍니다.
  2. 입력 열을 인덱스로 변환하십시오. 문자 A은 int 값이 65이고, A이 첫 번째 행이므로 인덱스에서 65을 뺍니다. 코드의 반 청소 최대 버전 여기

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

    됩니다 :

그런 다음 그것을 편지가 들어 있는지 확인하기 위해 인덱스 [newRow, newCol]에서 우리 Grid 배열에 체크 단지 문제

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#의 초보자로서 처음에는 초보자들이 대히트하는 부정적인 장벽 때문에 여기에 게시하는 것을 주저했습니다. 당신의 솔루션은 제가 가지고있는 모든 질문을 명확히 할뿐만 아니라 오랫동안 끓인 스파게티의 훌륭한 버전을 제공했습니다. 고맙습니다! –