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

이동민·2023년 10월 29일
0

체스 봇 개발 일지 9일차

2023 10 29

지난번에 버전3의 새로운 알고리즘을 만들었다. 버전3의 알고리즘에 대해 간단히 설명하자면 버전1과 버전2의 단점을 보안해 다음 수를 계산해 손해를 최소화 하고 이익을 최대화 하는 알고리즘이다. 하지만 손해가 없는 상황에서도 상대 기물을 잡지 않는 상황이 생겼다. 그래서 오늘은 이 문제점을 고쳐 볼 것이다.

1. 버전3의 문제점

버전3의 문제점은 ai의 기물이 플레이어의 기물을 잡고 다음턴에 잡히는 상황이 아닌데도 ai가 그 기물을 잡지 않는다는 것이다. 정확한 오류 상황은 8일차에 명시해 두었다.

2. 문제 분석

왜 오작동이 하는지 파악하기 위해 몇몇 if문에 출력해주는 코드를 작성했다. 일단 ai 기물의 좌표, 플레이어의 기물의 좌표가 잘 들어가는지 이 좌표들 먼저 출력을 해주었다.

첫번째 좌표가 공격을 진행 할 ai 기물의 좌표이고, 두번째 좌표가 공격을 당할 플레이어의 기물의 좌표이다. 그리고 세번째 좌표는 공격을 진행했을때 ai 기물을 잡을 수 있는 플레이어의 기물의 좌표이다. 보다시피 좌표에는 문제가 없다.

그 다음 가중치(score)를 출력을 해주었다.

첫번째가 기물을 잡을때 가중치이고, 두번째가 ai의 기물이 잡힐 경우 ai의 기물의 점수를빼준 가중치이다. 원래 두번째도 1이여야 하는데 보다시피 0 이다. 가중치를 처리하는 코드가 잘못된것 같다.

3. 코드 수정

int srch(int c,int d,Piece _pBoard[][10]) { //탐색 1
	
	for (int a = 1; a <= 8; a++) { //x
		for (int b = 1; b <= 8; b++) { //y
			if (_pBoard[b][a].team == 0) {
				if (_pBoard[b][a].type == 1) {
					if (Pa_sr(0, a, b, c, d, _pBoard)) {
						
						printf("p\n");
						//score -= (_pBoard[b][a].type);
						return 1;
					}
				}
				else if (_pBoard[b][a].type == 2) {
					if (Ro_sr(0, a, b, c, d, _pBoard)) {
						//printf("(%d %d)\n", c, d);
						//printf("(%d %d)\n", a, b);
						//score -= (_pBoard[b][a].type);
						return 1;
					}
				}
				else if (_pBoard[b][a].type == 3) {
					if (Kn_sr(0, a, b, c, d, _pBoard)) {
						printf("k");
						//score -= (_pBoard[b][a].type);
						return 1;
					}
				}
				else if (_pBoard[b][a].type == 4) {
					//printf("(%d %d)", a, b);
					if (Bi_sr(0, a, b, c, d, _pBoard)) {
						printf("b");
						//score -= (_pBoard[b][a].type);
						return 1;
					}
				}
				else if (_pBoard[b][a].type == 5) {
					//printf("(%d %d)", a, b);
					if (Qu_sr(0, a, b, c, d, _pBoard)) {
						printf("q");
						//score -= (_pBoard[b][a].type);
						return 1;
					}
				}
			}
		}
	}
	return 0;
}

ai의 기물이 플레이어의 기물을 잡고 다음턴에 잡히는지 판단해주는 함수를 int형으로 바꾸어 만약 ai의 기물이 잡고 잡히는 경우 1을 리턴해주었다.

int fu(int x, int y, Piece _pBoard[][10]) { //탐색2  
	for (int i = 1; i <= 8; i++) {//x
		for (int j = 1; j <= 8; j++) {//y
			if (_pBoard[j][i].team == 1) {
				if (_pBoard[j][i].type == 1) {
					if (Pa_ch(1, i, j, x, y, _pBoard)) {
						//printf("%d %d\n", x, y);
						score += _pBoard[y][x].type;
						printf("1: %d\n", score);
						if (srch(x, y, _pBoard)) {
							score -= _pBoard[j][i].type;
						}
						printf("2: %d\n", score);
						if (score > 0) {
							_move(i, j, x, y, _pBoard);
							score = 0;
						}
						else {
							score = 0;
							break;
						}
						return 1;
					}
				}
			}
		}
	}
	return 0;
}

그리고 만약 1이 리턴되었을때 이 함수에서 가중치를 빼줬다.

4. 작동 장면

이제 정상적으로 두번째 값이 1이 출력된다.

그리고 잡는것 까지 된다.

5. 마치며

이렇게 해서 버전3의 문제점을 고쳐 버전4를 만들었다. 승률은 내가 직접 10판 해봤을때 ai가 2판을 이긴다. 20% 정도 되는것 같다. 다음에는 승률을 올릴 수 있는 전략을 연구 할 것이다.

0개의 댓글