자바로 만든 체스(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
를 반환한다.
위 검사를 모두 통과하면 정상적으로 캐슬링이 이루어진다.
두 피스의 firstMove
를 true
로 만들고, 캐슬링 규칙에 맞추어 피스 위치를 이동시킨다.
특수룰 앙파상
} 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;
기존에는 없던 latestPiece
와 Piece.doubleMove
를 새로 선언했는데,
각각 가장 마지막에 움직임이 이루어진 피스와 해당피스(폰)가 2칸이동을 실시했는지 확인한다.
앙파상의 규칙 상, ‘바로 직전’에 ‘2칸’이동한 상대방의 피스에 대해서만 해당되기 때문에 필요했다.
원래 폰의 2칸이동을 위해 Piece
에 firstMove
가 있었는데,
캐슬링에서 이를 활용하고 있기 때문에 새로이 doubleMove
를 선언해야 했다.
위 코드는 1플레이어 기준으로 작성되어 있다.
첫번째로, 해당피스위치의 y값이 4인지 검사한다.
아니라면 false
를 반환한다.
다음으로 이동하고자 하는 위치가 대각선앞위치인지 검사한다.
아니라면 false
를 반환한다.
다음으로 앙파상의 대상이 되는 상대방의 피스가 폰인지,
해당 피스가 2칸을 움직였는지, 바로 직전에 움직인 피스인지,
이동하고자 하는 자리가 비어있는지 확인한다.
아니라면 false
를 반환한다.
위 검사를 모두 통과하면 앙파상이 이루어진다.
상대방의 피스 1개를 잡기 때문에 화면 우측에 잃은 피스를 표시하는 코드까지 포함했다.
구현해야 할 목록
- 킹이 잡힘에 따른 패배처리(화면만 구현하면 됨)
- 음악, 효과음 등
- (추가) 승패를 로그로 기록, 지난 경기기록 확인하기
- 멀티플레이 기능(중요)
Leave a comment