re:C++でオセロのAIを作る１（超初心者です）

以前の記事で自作オセロ（人vs人）を投稿して、コメントでアドバイスをいただけたので、改良して再投稿。
＜改良点＞
・変数名を分かりやすくした
・Bの番専用の関数、Wの番専用の関数があった
→if文を使って一つにまとめた

合計の行数が１００行くらい減り、関数の数も減ったのでより分かりやすくなりました。

実はぐちゃぐちゃな方のプログラムを元手に、深層学習ナシでオセロのコツを学ばせただけの、打ち返してくるオセロAIを作ってました。なんと行数８００。

今度はこっちを元に作って、より高度なものかつ分かりやすいものに挑戦します。

↓ソースコード↓
```:オセロ（改良版）
#include <stdio.h>

/*実行する関数(どっちの番か、ボード配列)戻り値→置けたら０，置ける場所がなかったら１*/
int run(char user,char board[12][12]);

/*配置を出力する関数*/
void outputBoard(char board[12][12]);

/*裏返す関数（どっちの番か、ベクトル、初期位置(縦、横)、配列）*/
int revers(char user,int i, int j, int vertical, int horizon, char board[12][12]);

/*まだ打てるか確認する関数*/
int check(char user,char board[12][12]);

/*そこに打てるか確認だけする関数*/
int spe_check(char user,int i, int j, int vertical, int horizon, char board[12][12]);


/*ベクトル(dir_ver,dir_hor)
(-1,-1)(-1,0)(-1,1)
(0,-1)(vertical,horizon)(0,1)
(1,-1)(1,0)(1,1)*/

int main(void) {

	int i, j, cntNoRev;
	int cntB = 0;
	int cntW = 0;
	char user = 'B';
	char partner = 'W';
	char board[12][12];

	/*最初の配置を配列に代入(縦がi）*/
	for (i = 0; i < 12; i++) {
		for (j = 0; j < 12; j++) {
			if ((i == 4 && j == 4) || (i == 5 && j == 5)) {
				board[i][j] = 'B';
				continue;
			}

			if ((i == 4 && j == 5) || (i == 5 && j == 4)) {
				board[i][j] = 'W';
				continue;
			}
			board[i][j] = ':';
		}
	}

	/*配置を出力*/
	outputBoard(board);

	printf("Bが先行です。\n");

	/*----実行-----*/

	while(1){

		/*---------Bの番---------*/
		user = 'B';

		cntNoRev = run(user, board);

		if(cntNoRev==0){
			outputBoard(board);
		}

        cntB = 0;
		cntW = 0;

		/*決着の確認*/
		for (i = 1; i <= 8; i++) {
			for (j = 1; j <= 8; j++) {
				if (board[i][j] == 'B')
					cntB++;
				if (board[i][j] == 'W')
					cntW++;
			}
		}

		if ((cntB + cntW == 64) || cntB == 0 || cntW == 0)
			break;

		cntB = 0;
		cntW = 0;

		/*---------Wの番---------*/
		user = 'W';

		cntNoRev = run(user, board);

		if (cntNoRev == 0){
			outputBoard(board);
		}

        cntB = 0;
		cntW = 0;

		/*決着の確認*/
		for (i = 1; i <= 8; i++) {
			for (j = 1; j <= 8; j++) {
				if (board[i][j] == 'B')
					cntB++;
				if (board[i][j] == 'W')
					cntW++;
			}
		}

		if ((cntB + cntW == 64) || cntB == 0 || cntW == 0)
			break;

		cntB = 0;
		cntW = 0;

	}

	/*勝敗の確認*/

	cntB = 0;
	cntW = 0;

for (i = 1; i <= 8; i++) {
		for (j = 1; j <= 8; j++) {
			if (board[i][j] == 'B')
				cntB++;
			if (board[i][j] == 'W')
				cntW++;
		}
	}

	if (cntB > cntW)
		printf("%d対%dでBの勝ちです", cntB, cntW);
	if (cntB == cntW)
		printf("引き分けです");
	if (cntB < cntW)
		printf("%d対%dでWの勝ちです", cntB, cntW);

	return 0;
}

/*配置を出力する関数*/
void outputBoard(char board[12][12])
{
	int i, j;

	for (i = 1; i <= 8; i++) {
		printf("\t%d", i);
	}
	printf("\n");

	for (i = 1; i <= 8; i++) {
		printf("%d\t", i);
		for (j = 1; j <= 8; j++) {
			printf("%c\t", board[i][j]);
		}
		printf("\n\n");
	}
}

/*実行する関数(どっちの番か、ボード配列)戻り値→置けたら０，置ける場所がなかったら１*/
int run(char user, char board[12][12])
{
	int i, j, horizon, vertical, dir_ver, dir_hor, tmp1, tmp2;
	int cntRev = 0;//revers_to_Aを実行した回数をカウント
	int cntNoPut = 0;//revers_to_Aを実行したけど置けなかった回数をカウント
	int cntNoRev = 0;//どこにも置けない→１
	char partner='W';

	if (user == 'B') {
		partner = 'W';
	}
	else if (user == 'W') {
		partner = 'B';
	}

	while (cntRev == 0 || cntRev == cntNoPut) {

		tmp1 = check(user,board);
		if (tmp1 == 64) {
			printf("%cをどこにも置けません\n",user);
			cntNoRev++;
			break;
		}

		printf("%cの番です。どこに打ちますか？（上の数字が先）\n",user);

		scanf_s("%d", &horizon);
		scanf_s("%d", &vertical);

		j = 0;
		if (board[vertical][horizon] != ':') {
			printf("そこには打てません\n");
			continue;
		}

		if (board[vertical][horizon] == ':') {

			/*置いて裏返す*/
			for (i = vertical - 1; i <= vertical + 1; i++) {
				for (j = horizon - 1; j <= horizon + 1; j++) {
					if (board[i][j] == partner) {
						dir_ver = i - vertical;
						dir_hor = j - horizon;
						tmp2 = revers(user,dir_ver, dir_hor, vertical, horizon, board);
						cntRev++;
						if (tmp2 != 0)
							cntNoPut++;
					}
				}
			}
			
			if (cntRev == 0 || cntRev == cntNoPut) {
				printf("そこには打てません\n");
				board[vertical][horizon] = ':';
			}
		}
	}

	return cntNoRev;
}


/*裏返す関数（ベクトル、初期位置(縦、横)、配列）,裏返せた→０、裏返せない→１*/
int revers(char user,int dir_ver, int dir_hor, int vertical, int horizon, char board[12][12])
{
	int move = 1;
	int i, tmp_hor, tmp_ver;
	tmp_hor = horizon;
	tmp_ver = vertical;
	int isReversed = 0;
	char partner='W';

	if (user == 'B') {
		partner = 'W';
	}
	else if (user == 'W') {
		partner = 'B';
	}

	board[vertical][horizon] = user;

	while (board[tmp_ver + dir_ver][tmp_hor + dir_hor] == partner) {


		if (board[vertical + dir_ver * 2][horizon + dir_hor* 2] == ':') {
			isReversed++;
			break;
		}

		if (board[vertical + dir_ver * 2][horizon + dir_hor * 2] == partner) {
			horizon += dir_hor;
			vertical += dir_ver;
			move++;
		}

		if (board[vertical + dir_ver * 2][horizon + dir_hor * 2] == user) {

			for (i = 0; i <= move; i++) {

				if (dir_ver != 0 && dir_hor != 0)
					board[vertical + dir_ver - dir_ver * i][horizon + dir_hor - dir_hor * i] = user;

				if (dir_ver == 0)
					board[vertical][horizon + dir_hor- dir_hor * i] = user;

				if (dir_hor == 0)
					board[vertical + dir_ver - dir_ver * i][horizon] = user;

			}

		}

	}

	return isReversed;

}


/*まだ打てるか確認する関数、戻り値→置けない場所の数*/
int check(char user,char board[12][12]) 
{
	int i,j,dir_ver,dir_hor,is,horizon, vertical;
	int cntRev = 0;
	int cntNoPut = 0;
	int cnt = 0;//打てなかった数をカウント
	char partner='W';

	if (user == 'B') {
		partner = 'W';
	}
	else if (user == 'W') {
		partner = 'B';
	}

	for (vertical = 1; vertical <= 8; vertical++) {
		for (horizon = 1; horizon <= 8; horizon++) {

			if (board[vertical][horizon] != ':') {
				cnt++;
				continue;
			}

			for (i = vertical - 1; i <= vertical + 1; i++) {
				for (j = horizon - 1; j <= horizon + 1; j++) {
					if (board[i][j] == 'W') {
						dir_ver = i - vertical;
						dir_hor = j - horizon;
						is = spe_check(user,dir_ver, dir_hor, vertical, horizon, board);
						cntRev++;
						if (is != 0)
							cntNoPut++;
					}
				}
			}
		
			if (cntRev == 0 || cntRev == cntNoPut) {
				cnt++;
			}

			cntRev = 0;
			cntNoPut = 0;

		}
	}

	return cnt;
}

/*そこに打てるか確認だけする関数(打てる→０、打てない→１）*/
int spe_check(char user,int dir_ver, int dir_hor, int vertical, int horizon, char board[12][12]) 
{

	int  tmp_ver, tmp_hor;
	tmp_hor = horizon;
	tmp_ver = vertical;
	int is = 0;
	char partner='W';

	if (user == 'B') {
		partner = 'W';
	}
	else if (user == 'W') {
		partner = 'B';
	}

	while (board[tmp_ver + dir_ver][tmp_hor + dir_hor] == partner) {

		if (board[vertical + dir_ver * 2][horizon + dir_hor * 2] == ':') {
			is++;
			break;
		}

		if (board[vertical + dir_ver * 2][horizon + dir_hor * 2] == partner) {
			horizon += dir_hor;
			vertical += dir_ver;
		}

		if (board[vertical + dir_ver * 2][horizon + dir_hor * 2] == user) {
			break;
		}

	}

	return is;

}