체스 봇 개발 일지 4일차
2023 09 24
지난번까지 추가 기능인 캐슬링과, 승진을 만들었다. 이번에는 체스에 매우 중요한 역할을 하는 체크 기능을 만들 것이다. 정확히 말하자면 체크 상황에 체크라고 멘트를 해주는 기능을 만들 것이다.
1. 체크란
체크는 체스의 아주 기본적인 룰이다. 체크란 킹이 공격받는 경우를 체크라고 한다.
2. 구현
일단 각 팀의 왕의 좌표를 저장해 줄 변수인 bkx(검은색 킹 x좌표), bky (검은색 킹 y좌표), wkx(흰색 킹 x좌표), wky(흰색 킹 y좌표)를 만들어준다. 그리고 킹이 이동할 때마다 이 변수들의 값을 계속 바꿔준다.
int Pa_ch(int team, int ax, int ay, int bx, int by, Piece _pBoard[][10]) {
if (team == 1) {
if (_pBoard[by][bx].type > 0) {
if (ay + 1 == by && abs(ax - bx) == 1) {
return 2;
}
}
else if (ay == 2) {
if (ax == bx && (by - ay == 1 || (by - ay == 2 && _pBoard[ay + 1][by].type < 1))) {
return 1;
}
}
else {
if ((ax == bx && by - ay == 1)) {
return 1;
}
}
return 0;
}
else if (team == 0) {
if (_pBoard[by][bx].type > 0) {
if (ay - 1 == by && abs(ax - bx) == 1) {
return 2;
}
}
else if (ay == 7) {
if (ax == bx && (by - ay == -1 || (by - ay == -2 && _pBoard[ay - 1][by].type < 1))) {
return 1;
}
}
else {
if ((ax == bx && by - ay == -1)) {
return 1;
}
}
return 0;
}
return 0;
}
또 위와 같이 이동 또는 공격은 하지 않지만 이동, 공격이 가능한지 확인만 해주는 함수를 만들었다. 이동이 가능하면 1을 리턴하고, 공격이 가능하면 2를 리턴하고 다 불가능하면 0을 리턴한다. 위의 함수는 폰이 이동, 공격이 가능한지 확인해 주는 함수인 Pa_ch이다. 룩이 가능한지 확인하는 함수의 이름은 Ro_ch, 나이트는 Kn_ch 이런 식으로 이름을 지어줬다.
int check(int team, Piece _pBoard[][10]) {
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
if (_pBoard[i][j].team == team) {
if (team == 0) {
if (_pBoard[i][j].type == 1) {
if (Pa_ch(0, j, i, wkx, wky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 2) {
if (Ro_ch(0, j, i, wkx, wky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 3) {
if (Kn_ch(0, j, i, wkx, wky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 4) {
if (Bi_ch(0, j, i, wkx, wky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 5) {
if (Qu_ch(0, j, i, wkx, wky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 6) {
if (Ki_ch(0, j, i, wkx, wky, _pBoard) == 2) {
return 1;
}
}
}
else if (team == 1) {
if (_pBoard[i][j].type == 1) {
if (Pa_ch(1, j, i, bkx, bky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 2) {
if (Ro_ch(1, j, i, bkx, bky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 3) {
if (Kn_ch(1, j, i, bkx, bky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 4) {
if (Bi_ch(1, j, i, bkx, bky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 5) {
if (Qu_ch(1, j, i, bkx, bky, _pBoard) == 2) {
return 1;
}
}
else if (_pBoard[i][j].type == 6) {
if (Ki_ch(1, j, i, bkx, bky, _pBoard) == 2) {
return 1;
}
}
}
}
}
}
return 0;
}
그다음 check라는 함수를 만들어주었다. 공격을 하는 팀이 흰색 팀이냐 검은색 팀이냐에 따라 나누어주고, 중첩 for 문으로 킹을 공격하는 기물들을 모두 탐색하여 그 기물들의 종류에 따라(예: 폰/룩/나이트 등..) 또 나누어준다. 그리고 아까 말한 함수들을 이용하여 이 기물이 상대 킹을 잡을 수 있는지 확인을 했다. (Pa_ch, Ro_ch, Kn_ch ...)의 리턴 값이 2이면 공격이 가능하다는 뜻이므로 이 경우에는 1을 리턴해 주었다.
매 턴마다 이동이 끝나면 check 함수를 호출해서 체크인지 확인을 해준다. 만약 체크라면 다음 턴 즉, 체크를 방어해야 하는 플레이어의 턴 때 check!라고 출력이 되게 했다.
3. 작동 사진

검은색 퀸 이 하얀색 킹을 공격 가능한 상황에 하얀색 턴 때 check!라고 출력해 주는 모습
4. 마치며
오늘까지 해서 모든 추가 기능인 캐슬링, 승진 그리고 체크까지 만들었다. 다음번부터는 체스를 직접 두는 ai를 만들 것이다.