Notice
Recent Posts
Recent Comments
Link
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

I'm FanJae.

[Gomoku] Day 2. 오목 리팩토링 II 본문

Projects/Gomoku (Console)

[Gomoku] Day 2. 오목 리팩토링 II

FanJae 2026. 5. 9. 21:42

1. 리팩토링 대상

(1) 좌표값 분리

readonly struct Position
{
    public int Row { get; }
    public int Col { get; }

    public Position(int row, int col)
    {
        Row = row;
        Col = col;
    }
}

- 좌표값을 하나로 담아놓지 않고, 처리하면 분명히 실수가 발생할 것이라고 판단해 분리했다.

 

(2) 실제 돌 놓기와 규칙 등으로 임시 돌을 놓는 상황 분리

public bool TryPlaceStone(Position pos, Stone stone) // 실제 돌 놓기 
{
    if (!IsInside(pos)) return false;

    if (!IsEmpty(pos)) return false;

    cells[pos.Row, pos.Col] = stone;
    return true;
}

public void SetStone(Position pos, Stone stone) // 룰 체크, 시뮬레이션 등등에 활용할 용도의 돌 놓기
{
    cells[pos.Row, pos.Col] = stone;
}

- 오목에서 실제로 돌을 놓는 상황일때와 3,3룰과 같은 상황에서 임시 돌을 놓아야 하는 상황에 대한 메서드를 분리했다.

- SetStone() 같은 경우, 돌을 제거할 수 있는 경우도 만들어 두었다.

 

(3) 보드 렌더링 방식 교체

- 바둑판에 배치하는 느낌이 제대로 나도록 바꿨다.

 

private string GetCellSymbol(Board board, Position cell, Position cursor, Stone turn, bool showCursor) // 해당 위치의 문자 출력
{
    if (showCursor && cell.Row == cursor.Row && cell.Col == cursor.Col)
    {
        return board.IsEmpty(cell) ? GetStoneSymbol(turn) : InvalidCell; // 유효하지 않은 칸 반환
    }

    Stone stone = board.GetStone(cell); // 돌 정보 획득

    if (stone != Stone.Empty)  
    {
        return GetStoneSymbol(stone);
    }

    return GetEmptyBoardCellSymbol(board, cell);
}
private string GetEmptyBoardCellSymbol(Board board, Position cell) // 빈 칸일때 어떤 보드 선 문자를 출력할지 결정
{
    int row = cell.Row;
    int col = cell.Col;

    bool top = row == 0;
    bool bottom = (row == Board.Size - 1);
    bool left = col == 0;
    bool right = (col == Board.Size - 1);

    Position rightPos = new Position(row, col + 1);
    bool rightHasStone = (col + 1 < Board.Size) && (board.GetStone(rightPos) != Stone.Empty); // 돌이 있는 경우, - 하나 제거할 것.

    string horizontal = rightHasStone ? " " : "─"; 

    if (top && left) return "┌" + horizontal;  
    if (top && right) return "┐ ";
    if (bottom && left) return "└" + horizontal;
    if (bottom && right) return "┘ ";
    if (top) return "┬" + horizontal; 
    if (bottom) return "┴" + horizontal;
    if (left) return "├" + horizontal;
    if (right) return "┤ ";

    return "┼"  + horizontal;
}

- 이 과정에서 기존에 있던 렌더링 함수보다 조금 복잡해졌다.

 

- 바둑판을 표현하는 과정에서 흑돌이 배치된 곳에 애매하게 저렇게 침투하는 문제가 있었다.

 

② 돌이 있는 경우에 대한 보정 처리

Position rightPos = new Position(row, col + 1);
bool rightHasStone = (col + 1 < Board.Size) && (board.GetStone(rightPos) != Stone.Empty); // 돌이 있는 경우, - 하나 제거할 것.

string horizontal = rightHasStone ? " " : "─";

- 돌이 있는 경우 가로 선에 대한 보정을 하도록 처리하였다.

 

2. TODO

① 오목 봇(CPU) 추가 예정

 

 

 
 

'Projects > Gomoku (Console)' 카테고리의 다른 글

[Gomoku] Day 3. CPU 추가  (0) 2026.05.10
[Gomoku] Day 1. 기존 오목 리팩토링 I  (0) 2026.05.08
Comments