자바로 만든 체스(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[][]
board
는 Piece
로 이루어진 배열인데, 빈자리를 어떻게 처리해야 할지 잘 모르겠어서
그냥 의미없는 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
메소드가 실행될 떄 보드위에 그림을 직접 그려줬는데,
이제는 setBoard
와 drawBoard
메소드를 호출하도록 하였다.
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의 값으로 나타낼 수 있는
mouseXOnBoard
와 mouseYOnBoard
를 정의했다.
그 후 movable
이라는 메소드로 하여금 boolean값을 받아온다.
이는 내가 선택한 피스가 선택한 장소로 이동할 수 있는지에 대한 boolean값이다.
movable
의 경우에는 순서대로
- 이동하고자 하는 자리가 보드 안에 있는가?
- 제자리로 이동하려하는 것은 아닌가?
- 이동하고자 하는 자리에 본인의 피스가 있는 것은 아닌가?
- 피스의 종류에 따라, 그 이동법에 근거하여 이동할 수 있는 자리인가? 를 확인한다.
만약 참이라면, 일단 해당 피스가 Pawn
인 경우에는 피스의 firstMove
를 true
로 바꾼다.
즉, 해당 피스(폰)은 한번에 두칸을 이동할 수 없다.
그 다음으로 이동하고자 하는 자리에 플레이어 2의 피스가 있는지 확인한다.
만약 참이라면, 플레이어 2의 피스의 setLife
를 false
로 만들고, 더이상 보드위에 보이지 않도록 한다.
이미 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