Skip to content

Instantly share code, notes, and snippets.

@lasagnaphil
Created July 13, 2019 19:36
Show Gist options
  • Save lasagnaphil/5c7aa4b761fad7a59386c73ed42a01c0 to your computer and use it in GitHub Desktop.
Save lasagnaphil/5c7aa4b761fad7a59386c73ed42a01c0 to your computer and use it in GitHub Desktop.

코드 리뷰

플레이 후기

  • PPT 정말 잘 만들었습니다. 메카닉이 단번에 이해가 가는군요
  • 잘못된 인풋을 넣었더니 갑자기 메세지박스가 떠서 놀랐습니다. 나중에 코드를 보니 WinForms을 잘 찾아 쓴것 같군요...
  • 실제로 게임을 좀 더 해봤더니, 플레이어 중 한 명이 바보가 아닌 이상 승부가 쉽게 나지 않는것 같습니다. 이 이유 때문에 데스매치 메카닉을 넣은 것 같지만, 일단 데스매치가 나올 때 까지 기다리는 것이 좀 지루한 것 같습니다. 그래서 좀 더 재밌는 게임이 되려면 기본 메카닉에 좀 더 수정을 가해야 할 것 같습니다.

...하지만 여기는 기획 스터디가 아니므로, 바로 프로그래밍으로 넘어가도록 하죠 ㅎㅎ

인풋 처리 관련

플레이어 키를 누르면 콘솔창에 그 값이 뜨지 않고도 입력값을 받을 수 있는 방법이 있습니다. 바로 Console.ReadKey() 함수입니다. (https://docs.microsoft.com/ko-kr/dotnet/api/system.console.readkey?view=netframework-4.8)

string -> enum

가급적이면 종류를 나타내는 변수에 대해서는 enum을 씁시다!

string으로 모든걸 처리하려고 하다 보면 가독성이 저하될 뿐만 아니라, 오타로 인해 변수에 잘못 된 문자열을 넣게 될 가능성이 있습니다. (예를 들어 "O"를 입력해야 하는데 모르고 숫자 "0"를 넣다던가... 이런 일 생각보다 자주 나옵니다) 그리고 string이 메모리를 좀 더 많이 차지하기도 합니다. 물론 이정도로 작은 게임에서 그리 신경쓸만한 일은 아니지만... enum의 좋은 이유 중 하나는 오타를 쳐서 이상한 값을 집어넣어도 프로그램이 컴파일되기 전에 미리 오류를 어느정도 잡아 줄 수 있다는 것이죠.

예를 들어, 이 게임에서는 이러한 enum을 정의해 쓸 수 있겠죠:

enum Player {
    O, X    
}

enum Tile {
    Empty, O, X, V
}

pR, pC, cR, cC 변수

이 변수들은 각각 현재 플레이어와 캐논의 위치를 int로 나타낸 것입니다. 그런데 이 변수들을 콘솔에서 입력받기 전에는 어떤 값으로 초기화해야 할 까요? 여기서는 9로 한 것 같은데, 보통 이럴때는 프로그래머들이 -1이라는 숫자를 많이 사용합니다. 근데 어차피 값이 쓰여지게 될 변수이면, 굳이 초기화할 필요가 없긴 합니다. 스터디에서는 가금적이면 초기화를 하라고는 했지만, 이 경우에는 필요 없을것 같습니다.

static int pR;

그리고 변수 이름은 가급적이면, 이름만 봐서도 어떤 기능을 하는지를 알 수 있게끔 짓는 것이 좋습니다.

예를 들어,

pR -> playerRow

pC -> playerCol

cR -> cannonRow

cC -> cannonCol

변수 이름이 좀 더 길면 치는데 좀 더 귀찮을 수 있지만, 일단 코드의 가독성에 매우 도움이 되고, 어차피 Visual Studio와 같은 편집기에서는 자동완성이 있기 때문에 권장합니다.

근데 이 변수들이 기존의 playerRow, cannonRow 등의 string 변수들과 겹치군요! 이것의 해결 방법은 바로 다음 섹션에서 알려드리겠습니다:

Turn()

줄 128, 141:

playerRow와 playerColumn 변수가 static으로 바깥에 나와있을 필요가 없을 것 같습니다. 인풋을 불러오는데만 사용되고, 어차피 pR과 pC 변수로 값이 숫자로 변환될테니 프로그램의 전체 진행동안 가지고 있을 필요가 없겠죠. 이런 변수들은 local하게 만들어줍시다. 이를테면:

string playerRowStr = Console.ReadLine();
...
pR = Int32.Parse(playerRow) - 1;

물론 바로 전에 예기했던 조언대로 pR이라는 int 변수의 이름을 playerRow로 바꾸는게 좋겠죠.

CheckWinner()

continue를 쓰지 않고, bool 변수 하나를 이용해서 코드를 좀 더 단순하게 만들 수 있습니다.

for (int i = 0; i < 5 ; i++)
{
    bool rowFilled = true;
    for (int j = 0; j < 5; j++)
    {
        if (board[i,j] != player)
        {
            rowFilled = false;
            break;
        }
    }
    if (rowFilled) return true;
}

나머지 코드도 위와 비슷하게 단순화 할 수 있습니다.

CheckFullBoard()

여기도 전과 비슷하게, 굳이 continue를 쓰지 않아도 될 것 같습니다.

for (int i = 0; i < 5; i++)
{
    for (int k = 0; k < 5; k++)
    {
        if (board[i, k] == " ")
        {
            return false;
        }
    }
}
return true;

그럼 수고하셨습니다! 앞으로의 게임 프로그래밍 여정에 행운이 있기를...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment