数日後にゲーム作るタニ よっかめ 〜挟めるの?〜
やりました!現実では一応、遊べるオセロが完成しました!まだ二人いないと遊べないですが、しっかりオセロとしてルール通りに遊べるものが完成しました!ここからは、コンピュータプレイヤーの実装などを行なう予定です。
noteの記事の方は少しずつすすめていきます。今日は挟めるかどうかの判定をする部分をやっていきましょう!「みっかめ」の記事で紹介したおけるかどうかを判断する関数、judge_place関数に付け足します。下のコードは後にバグが発生することになるコードです。
int judge_place(int x, int y, int player, int board[8][8], int state){ //stateが1ならリバース
if(x < 0 || y < 0 || x > 7 || y > 7){ // 範囲外
return 1;
}
if(board[y][x] != 0){ //置いてある
return 1;
}
int count = 0;
if(judge_North(x, y, player, board) &&
judge_South(x, y, player, board) &&
judge_East(x, y, player, board) &&
judge_West(x, y, player, board) &&
judge_North_East(x, y, player, board) &&
judge_North_West(x, y, player, board) &&
judge_South_West(x, y, player, board) &&
judge_South_East(x, y, player, board)){
return 1;
}
return 0;
}
judge_(方角)関数は、それぞれの方角のマスで挟めるかどうかを判定する関数です。後で紹介しますが、この関数では挟める時には0、挟めない時には1を返します。なので、全部挟めないよ!ってなったらjudge_(方角)関数から全部1が返ってきます。"&&"理論演算子がうまく作用して、置けるか置けないかの判断だけであれば問題ありません。が、、、後にひっくり返す時に困ったことが発生します。その修正は、必要な時に紹介します。
続いて、先ほどのjudge_(方角)関数を紹介しますが、斜めはバグ発生させた過去があるので、別で紹介しようかと。
int judge_North(int x, int y, int player, int board[8][8]){
if( y == 0){
return 1;
}
switch(player){
case 9:
if(board[y-1][x] != 1){
return 1;
} else {
for(int i = (y-1); i >= 0; i--){
if(i < 0){
return 1;
}
if(board[i][x] == 0){ //なし
return 1;
} else if(board[i][x] == 9){ //黒発見
return 0;
}
//この間のところに、case 1:の場合も入れます。基本はcase 9:と同じです。
}
}
}
return 1;
}
judge_(方角)関数。返り値は整数。引数はオセロを置いた座標を表す二つの整数、白と黒どちらのプレイヤーのターンかを示す整数、ボードであるint型2次元リスト。黒が置いた場合で説明すると、一つ目のifが盤面の端かどうか。switch文内にある二つ目のifが上に白があるかどうか。白があったら、for文に入ってどんどん上のマスを参照しながら黒で挟んであるかどうかを調べます。上のコードは北の例ですが、他の東、西、南についてもxとyのどちらを固定するか、++するか、--していくかを変えていくだけです。しかしこのコード、いろいろ修正した今見ると、本当に無駄が多いですね、、、
ひとまず、これで縦横方向に挟めるところにだけ置けるようになったので、最初の1ターン目までは置いていい場所に置けるというのが再現できるようになりました!!
にしても、こうして記事で書いていくと、一つ一つの処理の言葉にするだけでなかなかハードですね、思考の整理にはなってとてもよき。
次回は、斜めもひっくり返せる用意します。