자바로 만든 체스(7~8일차)

Updated:

7~8일차 진행상황

특수룰 캐슬링

  } else if (board[previous_y][previous_x].getName().equals("King") &&
          !board[previous_y][previous_x].isFirstMove() && previous_y == mouseYOnBoard &&
          (previous_x + 2 == mouseXOnBoard || previous_x - 2 == mouseXOnBoard)) {
      if (checkCastling(board[previous_y][previous_x], mouseXOnBoard, mouseYOnBoard)) {
          changeTurn(1);
      }

만약 피스의 release가 이루어졌는데, movalble메소드에서 false가 반환됐다면,

선택한 피스가 킹이고 한번도 움직인 적이 없으며 내려놓는 곳이 현재 위치보다 좌측2칸 또는 우측2칸일 경우 checkCastling메소드를 호출한다.

    public boolean checkCastling(Piece piece, int mouseXOnBoard, int mouseYOnBoard) {
        if (mouseXOnBoard > piece.getPos_x()) {
            if (board[mouseYOnBoard][8].isFirstMove())
                return false;
            for (int i = piece.getPos_x() + 1; i < 8; i++) {
                if (board[mouseYOnBoard][i] != nullPiece)
                    return false;
            }
            for (int i = piece.getPos_x() ; i <= piece.getPos_x() + 2 ; i++) {
                for (int j = 0 ; j < 16 ; j++) {
                    if (turnPlayer == 1) {
                        if (player2.getPieces()[j].isLife() &&
                                movable(player2.getPieces()[j], player2.getPieces()[j].getPos_x(),
                                        player2.getPieces()[j].getPos_y(),i, mouseYOnBoard))
                            return false;
                    } else {
                        if (player1.getPieces()[j].isLife() &&
                                movable(player1.getPieces()[j], player1.getPieces()[j].getPos_x(),
                                        player1.getPieces()[j].getPos_y(),i, mouseYOnBoard))
                            return false;
                    }
                }
            }
            latestPiece = piece;
            piece.setFirstMove(true);
            board[mouseYOnBoard][8].setFirstMove(true);
            piece.setPos_x(piece.getPos_x() + 2);
            board[mouseYOnBoard][mouseXOnBoard] = piece;
            board[mouseYOnBoard][mouseXOnBoard - 2] = nullPiece;
            board[mouseYOnBoard][8].setPos_x(piece.getPos_x() - 1);
            board[mouseYOnBoard][piece.getPos_x() - 1] = board[mouseYOnBoard][8];
            board[mouseYOnBoard][8] = nullPiece;
            drawBoard();
            return true;
        }

캐슬링하고자 하는 대상 룩이 좌측인지 우측인지 나누어서 설계했다.
위는 캐슬링하고자 하는 방향이 오른쪽일때이다.

가장 먼저 해당 방향의 룩이 이동한 적이 있는지 확인한다.
이동한 적이 있다면 false를 반환한다.

킹과 룩 사이에 다른 피스가 있는지 확인한다.
다른 피스가 있다면 false를 반환한다.

다음으로 상대플레이어의 16개의 피스를 모두 조사한다.
그 중 만약 현재 킹의 위치 및 킹과 캐슬링하고자 하는 방향의 룩 사이에
상대방의 피스가 닿을 수 있는지 검사한다.
만약 하나라도 있다면 캐슬링의 규칙에 위배되므로 false를 반환한다.

위 검사를 모두 통과하면 정상적으로 캐슬링이 이루어진다.

두 피스의 firstMovetrue로 만들고, 캐슬링 규칙에 맞추어 피스 위치를 이동시킨다.

특수룰 앙파상

    } else if (checkEnPassant(board[previous_y][previous_x], mouseXOnBoard, mouseYOnBoard)) {
        changeTurn(2);
    }

만약 캐슬링 검사에서도 false를 리턴받았다면, checkEnPassant메소드드 호출하여
앙파상 검사를 실시한다.

public boolean checkEnPassant(Piece piece, int mouseXOnBoard, int mouseYOnBoard) {
        if (!piece.getName().equals("Pawn"))
            return false;

        if (turnPlayer == 1) {
            if (piece.getPos_y() != 4)
                return false;
            if (mouseXOnBoard != piece.getPos_x() - 1 && mouseXOnBoard != piece.getPos_x() + 1)
                return false;
            if (mouseYOnBoard != piece.getPos_y() - 1)
                return false;
            if (board[mouseYOnBoard + 1][mouseXOnBoard].getName().equals("Pawn") &&
            board[mouseYOnBoard + 1][mouseXOnBoard].isDoubleMove() &&
            latestPiece == board[mouseYOnBoard + 1][mouseXOnBoard] &&
            board[mouseYOnBoard][mouseXOnBoard] == nullPiece)
            {
                latestPiece = piece;
                piece.setFirstMove(true);
                board[piece.getPos_y()][piece.getPos_x()] = nullPiece;
                piece.setPos_y(mouseYOnBoard);
                piece.setPos_x(mouseXOnBoard);
                board[mouseYOnBoard][mouseXOnBoard] = piece;
                board[mouseYOnBoard + 1][mouseXOnBoard].setLife(false);
                p2bt[board[mouseYOnBoard + 1][mouseXOnBoard].getNo()].setBounds(670 + (deadWhite % 8) * 75, 400 + (deadWhite / 8) * 75, 75, 75);
                deadWhite++;
                board[mouseYOnBoard + 1][mouseXOnBoard] = nullPiece;
                return true;
            }
            return false;

기존에는 없던 latestPiecePiece.doubleMove를 새로 선언했는데, 각각 가장 마지막에 움직임이 이루어진 피스와 해당피스(폰)가 2칸이동을 실시했는지 확인한다.

앙파상의 규칙 상, ‘바로 직전’에 ‘2칸’이동한 상대방의 피스에 대해서만 해당되기 때문에 필요했다.

원래 폰의 2칸이동을 위해 PiecefirstMove가 있었는데,
캐슬링에서 이를 활용하고 있기 때문에 새로이 doubleMove를 선언해야 했다.

위 코드는 1플레이어 기준으로 작성되어 있다.

첫번째로, 해당피스위치의 y값이 4인지 검사한다.
아니라면 false를 반환한다.

다음으로 이동하고자 하는 위치가 대각선앞위치인지 검사한다.
아니라면 false를 반환한다.

다음으로 앙파상의 대상이 되는 상대방의 피스가 폰인지,
해당 피스가 2칸을 움직였는지, 바로 직전에 움직인 피스인지,
이동하고자 하는 자리가 비어있는지 확인한다.
아니라면 false를 반환한다.

위 검사를 모두 통과하면 앙파상이 이루어진다.

상대방의 피스 1개를 잡기 때문에 화면 우측에 잃은 피스를 표시하는 코드까지 포함했다.

구현해야 할 목록

  • 킹이 잡힘에 따른 패배처리(화면만 구현하면 됨)
  • 음악, 효과음 등
  • (추가) 승패를 로그로 기록, 지난 경기기록 확인하기
  • 멀티플레이 기능(중요)

Leave a comment