AI 체스 봇 개발 일지(6일차)

이동민·2023년 10월 8일
0

체스 봇 개발 일지 6일차

2023 10 08

5차까지 캐슬링, 계승, 체스 기능들을 모두 완성시켰다. 이번부터는 체스를 혼자 할 수 있게끔 상대가 돼줄 ai를 만들 것이다. 더 나아가 그전 버전의 단점을 보안해 줄 새로운 버전을 계속 개발해 승률을 높일 것이다. 오늘은 버전 1을 만들 것이다. 추석 연휴가 껴있어서 1주가 밀렸다.

1. 버전1 의 알고리즘

일단 ai는 하얀색 팀으로 고정시켜놓았다. 버전1 은 상대의 기물을 잡는것을 최우선시 한다. 또 기물에 따라 각각 다른 점수를 부여해 점수가 가장 높은 기물을 우선으로 먹게 설계가 되었다. 기물의 점수는 "킹(6) > 퀸(5) > 비숍(4) >나이트(3) > 룩(2) > 폰(1)" 이러하다. 최소 점수의 기물이 최대 점수의 기물을 잡는게 최대의 이익이므로 이 점도 고려하여 설계했다.

2. 코드 설명

int fu(int x, int y, Piece _pBoard[][10]) { //탐색2  
	for (int i = 1; i <= 8; i++) {
		for (int j = 1; j <= 8; j++) {
			if (_pBoard[i][j].team == 0) {
				if (_pBoard[i][j].type == 6) {
					if (_pBoard[y][x].type == 1) {
						if (Pa_ch(1, x, y, j, i, _pBoard)) {
							_move(x, y, j, i, _pBoard);
							return 1;
						}
					}
					if (_pBoard[y][x].type == 2) {
						if (Ro_ch(1, x, y, j, i, _pBoard)) {
							_move(x, y, j, i, _pBoard);
							return 1;
						}
					}
					if (_pBoard[y][x].type == 3) {
						if (Kn_ch(1, x, y, j, i, _pBoard)) {
							_move(x, y, j, i, _pBoard);
							return 1;
						}
					}
					if (_pBoard[y][x].type == 4) {
						if (Bi_ch(1, x, y, j, i, _pBoard)) {
							_move(x, y, j, i, _pBoard);
							return 1;
						}
					}
					if (_pBoard[y][x].type == 5) {
						if (Qu_ch(1, x, y, j, i, _pBoard)) {
							_move(x, y, j, i, _pBoard);
							return 1;
						}
					}
					if (_pBoard[y][x].type == 6) {
						if (Ki_ch(1, x, y, j, i, _pBoard)) {
							_move(x, y, j, i, _pBoard);
							return 1;
						}
					}
				}
			}
		}
	}
}

위 코드는 ai의 기물들이 플레이어의 킹을 잡을 수 있는지 탐색하는 것이다. 킹이 점수가 가장 높으므로 킹을 잡을 수 있는지 탐색을 가장 먼저 하게 했다. 또한 이 킹을 잡을 수 있는지 탐색하는 for 문 안에서는 폰을 가장 먼저 두어 폰으로 킹을 잡는 경우를 최우선으로 두었다. 그다음 코드는 퀸을 잡을 수 있는지 탐색하는 코드이다. 비슷한 구조이기 때문에 생략하겠다.

위 사진 (1, 6)의 하얀색 룩이 검은색 폰 또는 검은색 룩을 잡을 수 있는 상황에서

룩을 선택한 모습

만약 ai의 기물이 플레이어의 기물을 잡을 수 없는 상황이라면 폰을 전진시키게 설계하였다. 폰을 끝까지 전진시켜 퀸으로 계승시키기 위함이다.

void pma(Piece _pBoard[][10]) {//폰 전진
	for (int x = 1; x <= 8; x++) {
		for (int y = 8; y >= 1; y--) {
			if (_pBoard[y][x].type == 1 && _pBoard[y][x].team == 1) {
				if (y == 2) {
					if (Pa_ch(1, x, y, x, y + 2, _pBoard)) {
						_move(x, y, x, y + 2, _pBoard);
						return;
					}
				}
				else {
					if (Pa_ch(1, x, y, x, y + 1, _pBoard)) {
						_move(x, y, x, y + 1, _pBoard);
						return;
					}
				}
			}
		}
	}
}

위 코드가 폰을 전진시키는 함수이다. 플레이어의 진영 끝에 가장 가까운 폰부터 전진을 시키게 했다. 즉 가장 빨리 계승이 가능한 폰부터 이동시키는 것이다.

3. 버전1 의 승률

실제로 내가 ai와 직접 경기를 해봤을 때 ai의 승률은 0%에 수렴했다. 체스를 잘 두지 못하는 친구와도 경기를 시켜봤는데도 승률은 크게 다르지 않았다.

4. 버전1 의 단점

버전1 의 단점은 3가지 정도 있다. 첫 번째는 체크 상황일 때 ai의 킹이 피하지 못하는 것이다. 두 번째는 무작정 폰을 전진시킨다고 이길 확률이 높아지지는 않는 것 같다. 마지막 3번째는 한 수 앞을 내다보지 못한다는 것이다. 예를 들어

이 상황에서

룩으로 폰을 잡는 선택을 해서

룩이 비숍한테 잡힌다. 즉 룩과 폰을 교환을 한 것이므로 손해를 보았다. 이 경우가 한 수 앞을 내다보지 못한다는 예시이다.

5. 마치며

이번 6일차에는 ai 의 첫번째 버전인 버전1 을 만들었다. 여러 경우들을 고려해서 만들어 봤지만 생각보다 허점이 많았다. 7일차에는 이 점들을 보안한 ai 버전 2를 만들 것이다.

0개의 댓글