あれからいろいろとコードをいじっていたところ、無事AIを実装できました。
ですが今度は置けなくなったときににパスが発生しなくなってしまいました。
パスをするcheckEnd関数はあるのですが、どのように関連させるのかわかりません。
どのように関連させればいいでしょうか。
以下がコードの内容です
//CPUと自分がパスがされない
#include "DxLib.h"
#include <stdio.h>
int key[256];
int gpUpdatekey()
{
char tmpkey[256]; //現在のキーの入力状態を格納
GetHitKeyStateAll(tmpkey); //すべてのキーの入力状態を得る
for (int i = 0; i < 256; ++i)
{
if (tmpkey[i] != 0)
{
++key[i];
}
else
{
key[i] = 0;
}
}
return 0;
}
struct Obj {
int x,
y,
w,
h,
Handle;
};
enum Game_Data {
Me = 0,
CPU = 1,
End = 2,
EMPTY = 0,
BLACK = 1,
WHITE = 2,
SCREEN_WIDIH = 840,
SCREEN_HEIGHT = 640,
CURSOR_MAX = 480,
CELLSIZE = 80,
BOARDSIZE = 8
};
int board_x,
board_y;
int b, //ゲーム終了時にコマの数を数えるための変数
w;
int board[BOARDSIZE][BOARDSIZE];
int boardGraph;
int vec_y[] = { -1,-1,0,1,1,1,0,-1 };
int vec_x[] = { 0,1,1,1,0,-1,-1,-1 };
Obj black;
Obj white;
Obj cursor;
int Meturn;
int turn;
//画像のロード
void Graph_Ini()
{
boardGraph = LoadGraph("画像/オセロ.bmp");
black.Handle = LoadGraph("画像/クロ駒.bmp");
white.Handle = LoadGraph("画像/シロ駒.bmp");
cursor.Handle = LoadGraph("画像/選択.png");
}
//ゲーム情報の初期化
void Game_Ini()
{
turn = Me; //ターン、0は黒が先手
board_x = BOARDSIZE,
board_y = BOARDSIZE;
}
//盤面の初期化
void Board_Ini()
{
for (int y = 0; y < BOARDSIZE; ++y)
{
for (int x = 0; x < BOARDSIZE; ++x)
{
board[y][x] = EMPTY;
}
}
board[BOARDSIZE / 2 - 1][BOARDSIZE / 2] = BLACK; //[3][4]
board[BOARDSIZE / 2][BOARDSIZE / 2 - 1] = BLACK; //[4][3]
board[BOARDSIZE / 2][BOARDSIZE / 2] = WHITE; //[4][4]
board[BOARDSIZE / 2 - 1][BOARDSIZE / 2 - 1] = WHITE; //[3][3]
}
//カーソルの初期化
void Cursor_Ini()
{
cursor.x = 0;
cursor.y = 0;
}
//カーソルの移動
void Cursor_Move()
{
if (key[KEY_INPUT_RIGHT] == 1 && cursor.x <= CURSOR_MAX)
{
cursor.x += CELLSIZE;
}
if (key[KEY_INPUT_LEFT] == 1 && cursor.x > 0)
{
cursor.x -= CELLSIZE;
}
if (key[KEY_INPUT_UP] == 1 && cursor.y > 0)
{
cursor.y -= CELLSIZE;
}
if (key[KEY_INPUT_DOWN] == 1 && cursor.y <= CURSOR_MAX)
{
cursor.y += CELLSIZE;
}
}
//vecで指定された向きについてひっくり返るコマがあるか確認する(8方向のチェック)
int CheckFlip(int y, int x, int turn, int vec)
{
int flag = 0;
while (1)
{
y += vec_y[vec];
x += vec_x[vec];
//盤面の外に出ていたら終了(盤面内か?)
if (x < 0 || y < 0 || x > BOARDSIZE - 1 || y > BOARDSIZE - 1)
{
return 0;
}
//空きマス(置けるマス)だったら終了(その場所はおけるか?)
if (board[y][x] == EMPTY)
{
return 0;
}
//相手のコマがあったらフラグを立てる
if (board[y][x] == (turn ? BLACK : WHITE)) //真なら黒(1)、偽なら白(0)
{
flag = 1;
//(ループを続ける)
}
//自分のコマがあった場合にフラグが立っていれば置ける
if (board[y][x] == (turn ? WHITE : BLACK))
{
if (flag == 1)
{
return 1;
}
//置けない
else
{
return 0;
}
}
}
return 1;
}
//その場所に置くことができるかを確認
int Check(int y, int x, int turn) //座標とターン
{
int vec;
//どれか一方向でもひっくり返るか確認
for (vec = 0; vec < 8; ++vec)
{
if (CheckFlip(y, x, turn, vec) == 1)
{
return 1; //ひっくり返るなら1を返す
}
}
return 0; //0は返せない
}
//実際に裏返す処理
void Flip(int y, int x, int turn, int vec)
{
while (1)
{
y += vec_y[vec];
x += vec_x[vec];
//自分のコマがあったら終了
if (board[y][x] == (turn ? WHITE : BLACK))
{
break;
}
//それ以外なら自分の駒で塗りつぶす
board[y][x] = (turn ? WHITE : BLACK);
}
}
//入力を受けて裏返せるか確かめる関数
int Put(int y, int x, int turn)
{
int vec,
flag = 0;
//空白でなければ終了
if (board[y][x] != EMPTY)
{
return 0;
}
//全方向について確認
for (vec = 0; vec < 8; ++vec)
{
if (CheckFlip(y, x, turn, vec) == 1)
{
//裏返す
Flip(y, x, turn, vec);
flag = 1;
}
}
if (flag == 1)
{
//この場所にコマを置く
board[y][x] = (turn ? WHITE : BLACK);
return 1;
}
return 0;
}
//終了判定
int CheckEnd(int turn)
{
int y,
x;
//おける場所があるか確認
for (y = 0; y < BOARDSIZE; ++y)
{
for (x = 0; x < BOARDSIZE; ++x)
{
//あれば普通に続行
if (board[y][x] == EMPTY && Check(y, x, turn) == 1)
{
return Me;
}
}
}
//場所がなかったので交替して探す
turn = (turn + 1) % 2;
for (y = 0; y < BOARDSIZE; ++y)
{
for (x = 0; x < BOARDSIZE; ++x)
{
//あればpassして続行
if (board[y][x] == EMPTY && Check(y, x, turn) == 1)
{
return CPU;
}
}
}
//なかったのでゲーム終了
return End;
}
//コマを置く処理
void Me_PutPice(int by, int bx, int &turn)
{
for (int y = 0; y < BOARDSIZE; ++y)
{
for (int x = 0; x < BOARDSIZE; ++x)
{
if (key[KEY_INPUT_Z] == 1 && CELLSIZE * x == cursor.x && CELLSIZE * y == cursor.y && turn == Me)
{
if (Put(y, x, turn) == 1)
{
board[by][bx] = BLACK;
turn = CPU;
}
}
}
}
}
//CPU置ける所に適当に置く
void AI(int by, int bx, int &turn)
{
for (int y = 0; y < BOARDSIZE; ++y)
{
for (int x = 0; x < BOARDSIZE; ++x)
{
if (key[KEY_INPUT_X] == 1 && turn == CPU)
{
if (Put(y, x, turn) == 1)
{
board[by][bx] = WHITE;
turn = Me;
}
}
}
}
}
//勝敗判定
void CheckWinner()
{
b = 0,
w = 0;
//コマを数え上げる
for (int y = 0; y < BOARDSIZE; ++y)
{
for (int x = 0; x < BOARDSIZE; ++x)
{
switch (board[y][x])
{
case BLACK:
++b;
break;
case WHITE:
++w;
break;
default:
break;
}
}
}
//勝敗決定時
if (b > w)
{
DrawFormatString(680, 100, GetColor(255, 255, 255), "黒の勝ちです");
}
else if (b < w)
{
DrawFormatString(680, 100, GetColor(255, 255, 255), "白の勝ちです");
}
else
{
DrawFormatString(680, 100, GetColor(255, 255, 255), "引き分けです");
}
}
//盤面の表示
void Draw_Board()
{
//盤面
DrawGraph(0, 0, boardGraph, false);
//文字の表示
if (turn == Me)
{
DrawFormatString(680, 50, GetColor(255, 255, 255), "黒(自分)のターン");
}
if (turn == CPU)
{
DrawFormatString(680, 50, GetColor(255, 255, 255), "白(CPU)のターン");
DrawFormatString(680, 70, GetColor(255, 255, 255), "Xキーで置きます");
}
//コマ
for (int y = 0; y < BOARDSIZE; ++y)
{
for (int x = 0; x < BOARDSIZE; ++x)
{
//ボードの情報がWHITEなら白コマが置かれる
if (board[y][x] == WHITE)
{
DrawGraph(CELLSIZE * x, CELLSIZE * y, white.Handle, false);
}
//ボードの情報がBLACKなら黒コマが置かれる
if (board[y][x] == BLACK)
{
DrawGraph(CELLSIZE * x, CELLSIZE * y, black.Handle, false);
}
}
}
//グリッド線を引く
for (int x = 0; x < 9; ++x)
{
DrawLine(CELLSIZE * x, 0, CELLSIZE * x, SCREEN_HEIGHT, GetColor(255, 255, 255), true);
}
for (int y = 0; y < 9; ++y)
{
DrawLine(0, CELLSIZE * y, SCREEN_HEIGHT, CELLSIZE * y, GetColor(255, 255, 255), true);
}
//カーソル
DrawGraph(cursor.x, cursor.y, cursor.Handle,true);
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定
SetGraphMode(SCREEN_WIDIH, SCREEN_HEIGHT, 32);
Graph_Ini();
Game_Ini();
Cursor_Ini();
Board_Ini();
// while(裏画面を表画面に反映、メッセージ処理、画面クリア、キーの更新)
while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdatekey() == 0) //無限ループ
{
//ここにゲームの処理を描く------------------------------------------------
if (turn < End)
{
Cursor_Move();
Me_PutPice(board_y, board_x, turn);
AI(board_y, board_x, turn);
switch(CheckEnd(turn))
{
case End:
CheckWinner();
break;
}
}
Draw_Board();
//----------------------------------------------------------------------
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}