자바로 만든 체스(3~4일차)

Updated:

3~4일차 진행상황

Piece클래스 수정 및 board 구성

    private int pos_y;
    private int pos_x;
    private String name;
    private boolean life;
    private int turn;
    private int no;
    private boolean firstMove = false;

일단, 필요에 따라 Piece클래스의 필드를 위와 같이 수정했다. 각각의 피스에 대해서

pos_y : 해당피스의 y값(1~8) pos_x : 해당피스의 x값(1~8) name : 피스의 종류 (King, Queen 등) life : 피스가 생존하였는가에 대한 boolean turn : 어떤 플레이어의 피스인가? no : 해당 피스의 고유번호 firstMove : Pawn이 첫 이동을 제어하기 위한 boolean

private Piece nullPiece = new Piece(0,0,"",0, 0);
private Piece[][] board = new Piece[][]

boardPiece로 이루어진 배열인데, 빈자리를 어떻게 처리해야 할지 잘 모르겠어서
그냥 의미없는 nullPiece를 만들고 채워넣었다.

    public void setBoard() {
        for (int i = 0 ; i < 16 ; i++) {
            board[player1.getPieces()[i].getPos_y()][player1.getPieces()[i].getPos_x()] = player1.getPieces()[i];
            board[player2.getPieces()[i].getPos_y()][player2.getPieces()[i].getPos_x()] = player2.getPieces()[i];
        }
    }

    public void drawBoard() {
        for (int i = 0 ; i < 16 ; i++) {
            if (player1.getPieces()[i].isLife()) {
                p1bt[i].setBounds(-23 + 75 * player1.getPieces()[i].getPos_x(), -15 + 75 * player1.getPieces()[i].getPos_y(), 75, 75);
            }
            if (player2.getPieces()[i].isLife()) {
                p2bt[i].setBounds(-23 + 75 * player2.getPieces()[i].getPos_x(), -15 + 75 * player2.getPieces()[i].getPos_y(), 75, 75);
            }
        }
    }

기존엔 localgame메소드가 실행될 떄 보드위에 그림을 직접 그려줬는데,
이제는 setBoarddrawBoard메소드를 호출하도록 하였다.

setBoard메소드는 위의 board에 양측플레이어의 모든 피스들을 등록한다.

drawBoard메소드는 총 32개의 피스들에 대하여 만약 아직 살아있다면 이를 그림으로 그려주는 역할을 한다.

플레이어 권한 넘기기

    public void changeTurn(int turn) {
        if (turn == 1) {
            for (int i = 0 ; i < 16 ; i++) {
                p1bt[i].addNotify();
                p2bt[i].removeNotify();
            }
            turnPlayer = 1;
        } else {
            for (int i = 0 ; i < 16 ; i++) {
                p2bt[i].addNotify();
                p1bt[i].removeNotify();
            }
            turnPlayer = 2;
        }
    }

플레이어의 권한을 넘기기 위해서 changeTurn메소드를 생성했다. 인자로는 int형을 받아오는데, turn으로 플레이어를 바꾸겠다는 의미이다.

플레이어2가 성공적으로 피스를 이동했을 때, turn = 1을 인자로 받는다.

그렇게되면 플레이어2의 모든 피스에 대하여 권한이 사라지고 플레이어1의 모든 피스에 대하여 권한을 얻는다.

즉, 플레이어1에게 턴이 양도되는 것이다.
따라서 turnPlayer도 1로 바뀐다.

기물의 드래그 앤 드랍 수정

    mouseXOnBoard = (23 + (e.getXOnScreen() - getLocation().x)) / 75;
    mouseYOnBoard = (15 + (e.getYOnScreen() - getLocation().y)) / 75;
    if (movable(board[previous_y][previous_x], previous_x, previous_y, mouseXOnBoard, mouseYOnBoard)) {
        if (board[previous_y][previous_x].getName().equals("Pawn")) {
            board[previous_y][previous_x].setFirstMove(true);
        }
        if (board[mouseYOnBoard][mouseXOnBoard].getTurn() == 2) {
            board[mouseYOnBoard][mouseXOnBoard].setLife(false);
            p2bt[board[mouseYOnBoard][mouseXOnBoard].getNo()].setVisible(false);
        }
        board[previous_y][previous_x].setPos_y(mouseYOnBoard);
        board[previous_y][previous_x].setPos_x(mouseXOnBoard);
        board[mouseYOnBoard][mouseXOnBoard] = board[previous_y][previous_x];
        board[previous_y][previous_x] = nullPiece;
        changeTurn(2);
    }
    drawBoard();

플레이어 1의 예시를 가져왔다.

보드 위에서 내 마우스의 위치를 1~8의 값으로 나타낼 수 있는
mouseXOnBoardmouseYOnBoard를 정의했다.

그 후 movable이라는 메소드로 하여금 boolean값을 받아온다. 이는 내가 선택한 피스가 선택한 장소로 이동할 수 있는지에 대한 boolean값이다. movable의 경우에는 순서대로

  1. 이동하고자 하는 자리가 보드 안에 있는가?
  2. 제자리로 이동하려하는 것은 아닌가?
  3. 이동하고자 하는 자리에 본인의 피스가 있는 것은 아닌가?
  4. 피스의 종류에 따라, 그 이동법에 근거하여 이동할 수 있는 자리인가? 를 확인한다.

만약 참이라면, 일단 해당 피스가 Pawn인 경우에는 피스의 firstMovetrue로 바꾼다.
즉, 해당 피스(폰)은 한번에 두칸을 이동할 수 없다.

그 다음으로 이동하고자 하는 자리에 플레이어 2의 피스가 있는지 확인한다.
만약 참이라면, 플레이어 2의 피스의 setLifefalse로 만들고, 더이상 보드위에 보이지 않도록 한다.

이미 movable에서 내 피스가 있는 곳은 아닌지 검사를 진행했으므로,
이동하고자 하는 곳은 내가 잡을 수 있는 상대 피스의 자리거나, 빈 자리이므로
해당 자리에 내 말을 옮겨놓고 원래 있던 자리는 nullPiece를 채워넣는다.

턴을 변경하고, board위에 변화가 있었으므로 drawBoard메소드를 실행한다.

movable 메소드

    public boolean movable(Piece piece, int previous_x, int previous_y, int mouseXOnBoard, int mouseYOnBoard) {
        if (mouseXOnBoard < 1 || mouseXOnBoard > 8 || mouseYOnBoard < 1 || mouseYOnBoard > 8) return false;
        if (previous_x == mouseXOnBoard && previous_y == mouseYOnBoard) return false;
        if (board[mouseYOnBoard][mouseXOnBoard].getTurn() == turnPlayer) return false;

        if (piece.getName().equals("King")) {
            if (mouseXOnBoard >= previous_x - 1 && mouseXOnBoard <= previous_x + 1 && mouseYOnBoard >= previous_y - 1 && mouseYOnBoard <= previous_y + 1) return true;
            else return false;

        } else if (piece.getName().equals("Queen")) {
            if (previous_x == mouseXOnBoard) {
                if (previous_y < mouseYOnBoard) {
                    for (int i = previous_y + 1 ; i < mouseYOnBoard ; i++) {
                        if (board[i][previous_x] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_y - 1 ; i > mouseYOnBoard ; i--) {
                        if (board[i][previous_x] != nullPiece) return false;
                    }
                }
            } else if (previous_y == mouseYOnBoard) {
                if (previous_x < mouseXOnBoard) {
                    for (int i = previous_x + 1 ; i < mouseXOnBoard ; i++) {
                        if (board[previous_x][i] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_x - 1 ; i > mouseXOnBoard ; i--) {
                        if (board[previous_x][i] != nullPiece) return false;
                    }
                }
            } else if (previous_y - mouseYOnBoard == previous_x - mouseXOnBoard){
                if (previous_y < mouseYOnBoard) {
                    for (int i = previous_y + 1, j = previous_x + 1 ; i < mouseYOnBoard && j < mouseXOnBoard ; i++, j++) {
                        if (board[i][j] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_y - 1, j = previous_x - 1 ; i > mouseYOnBoard && j > mouseXOnBoard ; i--, j--) {
                        if (board[i][j] != nullPiece) return false;
                    }
                }
            } else if (previous_y - mouseYOnBoard == -(previous_x - mouseXOnBoard)) {
                if (previous_y < mouseYOnBoard) {
                    for (int i = previous_y + 1, j = previous_x - 1; i < mouseYOnBoard && j > mouseXOnBoard ; i++, j--) {
                        if (board[i][j] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_y - 1 , j = previous_x + 1 ; i > mouseYOnBoard && j < mouseXOnBoard ; i--, j++) {
                        if (board[i][j] != nullPiece) return false;
                    }
                }
            } else {
                return false;
            }

나이트

        } else if (piece.getName().equals("Knight")) {
            if (previous_x + 1 == mouseXOnBoard && previous_y + 2 == mouseYOnBoard) return true;
            if (previous_x + 2 == mouseXOnBoard && previous_y + 1 == mouseYOnBoard) return true;
            if (previous_x + 2 == mouseXOnBoard && previous_y - 1 == mouseYOnBoard) return true;
            if (previous_x + 1 == mouseXOnBoard && previous_y - 2 == mouseYOnBoard) return true;
            if (previous_x - 1 == mouseXOnBoard && previous_y - 2 == mouseYOnBoard) return true;
            if (previous_x - 2 == mouseXOnBoard && previous_y - 1 == mouseYOnBoard) return true;
            if (previous_x - 2 == mouseXOnBoard && previous_y + 1 == mouseYOnBoard) return true;
            if (previous_x - 1 == mouseXOnBoard && previous_y + 2 == mouseYOnBoard) return true;
            return false;

비숍

        } else if (piece.getName().equals("Bishop")) {
            if (previous_y - mouseYOnBoard == previous_x - mouseXOnBoard){
                if (previous_y < mouseYOnBoard) {
                    for (int i = previous_y + 1, j = previous_x + 1 ; i < mouseYOnBoard && j < mouseXOnBoard ; i++, j++) {
                        if (board[i][j] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_y - 1, j = previous_x - 1 ; i > mouseYOnBoard && j > mouseXOnBoard ; i--, j--) {
                        if (board[i][j] != nullPiece) return false;
                    }
                }
            } else if (previous_y - mouseYOnBoard ==  -(previous_x - mouseXOnBoard)) {
                if (previous_y < mouseYOnBoard) {
                    for (int i = previous_y + 1, j = previous_x - 1; i < mouseYOnBoard && j > mouseXOnBoard; i++, j--) {
                        if (board[i][j] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_y - 1, j = previous_x + 1; i > mouseYOnBoard && j < mouseXOnBoard; i--, j++) {
                        if (board[i][j] != nullPiece) return false;
                    }
                }
            } else return false;

        } else if (piece.getName().equals("Rook")) {
            if (previous_x == mouseXOnBoard) {
                if (previous_y < mouseYOnBoard) {
                    for (int i = previous_y + 1 ; i < mouseYOnBoard ; i++) {
                        if (board[i][previous_x] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_y - 1 ; i > mouseYOnBoard ; i--) {
                        if (board[i][previous_x] != nullPiece) return false;
                    }
                }
            } else if (previous_y == mouseYOnBoard) {
                if (previous_x < mouseXOnBoard) {
                    for (int i = previous_x + 1 ; i < mouseXOnBoard ; i++) {
                        if (board[previous_x][i] != nullPiece) return false;
                    }
                } else {
                    for (int i = previous_x - 1 ; i > mouseXOnBoard ; i--) {
                        if (board[previous_x][i] != nullPiece) return false;
                    }
                }
            } else return false;

        } else if (piece.getName().equals("Pawn")) {
            if (!piece.isFirstMove()) {
                if (turnPlayer == 1) {
                    if (previous_x == mouseXOnBoard && previous_y - 2 == mouseYOnBoard &&
                            board[previous_y - 1][previous_x] == nullPiece && board[previous_y - 2][previous_x] == nullPiece) return true;
                } else if (turnPlayer == 2) {
                    if (previous_x == mouseXOnBoard && previous_y + 2 == mouseYOnBoard &&
                            board[previous_y + 1][previous_x] == nullPiece && board[previous_y + 2][previous_x] == nullPiece) return true;
                }
            }
            if (turnPlayer == 1) {
                if (previous_x == mouseXOnBoard && previous_y - 1 == mouseYOnBoard && board[previous_y - 1][previous_x] == nullPiece) return true;
                if ((previous_x - 1 == mouseXOnBoard || previous_x + 1 == mouseXOnBoard) && previous_y - 1 == mouseYOnBoard &&
                        board[mouseYOnBoard][mouseXOnBoard].getTurn() == 2) return true;
            } else if (turnPlayer == 2) {
                if (previous_x == mouseXOnBoard && previous_y + 1 == mouseYOnBoard && board[previous_y + 1][previous_x] == nullPiece) return true;
                if ((previous_x - 1 == mouseXOnBoard || previous_x + 1 == mouseXOnBoard) && previous_y + 1 == mouseYOnBoard &&
                        board[mouseYOnBoard][mouseXOnBoard].getTurn() == 2) return true;
            }
            return false;
        }
        return true;
    }

비숍과 퀸, 룩과 퀸에서 반복이 일어나기에, 추후에 리팩토링 할 생각이다.

구현해야 할 목록

  • 앙파상, 캐슬링 등 특수기술
  • 킹이 잡힘에 따른 패배처리
  • 폰이 보드 끝으로 이동함에 따른 특수기술(어려울 것으로 예상)
  • 플레이화면의 UI 구현
  • 가능하면 음악, 효과음 등
  • 멀티플레이 기능(중요)

Leave a comment