早くAIを作りたいのに、ところどころ気になってしまって、また改良。
名前を入力できるようにしました。
↓ソースコード↓
オセロ再改良版
#include <stdio.h>
#include <string.h>
/*実行する関数(どっちの番か、ボード配列)戻り値→置けたら0,置ける場所がなかったら1*/
int run(char user[20], char board[12][12],char user1[20],char user2[20]);
/*配置を出力する関数*/
void outputBoard(char board[12][12]);
/*裏返す関数(どっちの番か、ベクトル、初期位置(縦、横)、配列)*/
int revers(char user[20], int i, int j, int vertical, int horizon, char board[12][12],char user1[20],char user2[20]);
/*まだ打てる場所があるか確認する関数(どっちの番か、ボード配列)、戻り値→置けない場所の数*/
int check(char user[20], char board[12][12],char user1[20],char user2[20]);
/*そこに打てるか確認だけする関数*/
int spe_check(char user[20], int i, int j, int vertical, int horizon, char board[12][12], char user1[20], char user2[20]);
/*ベクトル(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 user1[20] ;
char user2[20] ;
char partner = 'W';
char disc = 'B';
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("先攻のプレイヤーの名前を入力してください。");
scanf_s("%s", user1, 20);
printf("後攻のプレイヤーの名前を入力してください。");
scanf_s("%s", user2, 20);
/*----実行-----*/
while (1) {
/*---------Bの番---------*/
cntNoRev = run(user1, board, user1, user2);
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の番---------*/
cntNoRev = run(user2, board, user1, user2);
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であなたの勝ちです", cntB, cntW);
if (cntB == cntW)
printf("引き分けです");
if (cntB < cntW)
printf("%d対%dでの勝ちです", 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");
}
}
/*実行する関数(どっちの番か、ボード配列)戻り値→置けたら0,置ける場所がなかったら1*/
int run(char user[20], char board[12][12], char user1[20], char user2[20])
{
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;//どこにも置けない→+1
char disc = 'W';
char partner = 'B';
char you[20] ;
char computer[20] ;
strcpy_s(you, user1);
strcpy_s(computer, user2);
if (strcmp(you, user) == 0) {
disc = 'B';
partner = 'W';
}
else if (strcmp(computer, user) == 0) {
disc = 'W';
partner = 'B';
}
while (cntRev == 0 || cntRev == cntNoPut) {
tmp1 = check(user, board, user1, user2);
if (tmp1 == 64) {
printf(" %cをどこにも置けません\n", disc);
cntNoRev++;
break;
}
printf("%sの番です。どこに%cを打ちますか?(上の数字が先)\n", user, disc);
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, user1, user2);
cntRev++;
if (tmp2 != 0)
cntNoPut++;
}
}
}
if (cntRev == 0 || cntRev == cntNoPut) {
printf("そこには打てません\n");
board[vertical][horizon] = ':';
}
}
}
return cntNoRev;
}
/*裏返す関数(ベクトル、初期位置(縦、横)、配列),裏返せた→0、裏返せない→1*/
int revers(char user[20], int dir_ver, int dir_hor, int vertical, int horizon, char board[12][12], char user1[20], char user2[20])
{
int move = 1;
int i, tmp_hor, tmp_ver;
tmp_hor = horizon;
tmp_ver = vertical;
int isReversed = 0;
char disc = 'B';
char partner = 'W';
char you[20] ;
char computer[20] ;
strcpy_s(you, user1);
strcpy_s(computer, user2);
if (strcmp(you, user) == 0) {
disc = 'B';
partner = 'W';
}
else if (strcmp(computer, user) == 0) {
disc = 'W';
partner = 'B';
}
board[vertical][horizon] = disc;
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] == disc) {
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] = disc;
if (dir_ver == 0)
board[vertical][horizon + dir_hor - dir_hor * i] = disc;
if (dir_hor == 0)
board[vertical + dir_ver - dir_ver * i][horizon] = disc;
}
}
}
return isReversed;
}
/*打てる場所を確認する関数、戻り値→置けない場所の数*/
int check(char user[20], char board[12][12], char user1[20], char user2[20])
{
int i, j, dir_ver, dir_hor, is, horizon, vertical;
int cntRev = 0;
int cntNoPut = 0;
int cnt = 0;//打てなかった数をカウント
char disc = 'B';
char partner = 'W';
char you[20] ;
char computer[20] ;
strcpy_s(you, user1);
strcpy_s(computer, user2);
if (strcmp(you, user) == 0) {
disc = 'B';
partner = 'W';
}
else if (strcmp(computer, user) == 0) {
disc = '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, user1, user2);
cntRev++;
if (is != 0)
cntNoPut++;
}
}
}
if (cntRev == 0 || cntRev == cntNoPut) {
cnt++;
}
cntRev = 0;
cntNoPut = 0;
}
}
return cnt;
}
/*そこに打てるか確認だけする関数(打てる→0、打てない→1)*/
int spe_check(char user[20], int dir_ver, int dir_hor, int vertical, int horizon, char board[12][12], char user1[20], char user2[20])
{
int tmp_ver, tmp_hor;
tmp_hor = horizon;
tmp_ver = vertical;
int is = 0;
char disc = 'B';
char partner = 'W';
char you[20] ;
char computer[20];
strcpy_s(you, user1);
strcpy_s(computer, user2);
if (strcmp(you, user) == 0) {
disc = 'B';
partner = 'W';
}
else if (strcmp(computer, user) == 0) {
disc = '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] == disc) {
break;
}
}
return is;
}