数日後にゲーム作るタニ いつかめ 〜斜めに進むのは難しい〜
今日は、前回に引き続き挟めるかどうかの判定について、ななめについても対応できるようにします。ついでに、昨日の記事でswitch文で書いていた部分も簡潔に省略させます。今回は正常に動作するコードから。
int judge_North_West(int x, int y, int player, int board[8][8]){ //x-1, y-1
if( y == 0 || x == 0){
return 1;
}
if(board[y-1][x-1] != 10 - player){
return 1;
} else {
for(int i = 1; i < 8; i++){
if(y-i < 0 || x-i < 0){
return 1;
}
if(board[y-i][x-i] == 0){ //なし
return 1;
} else if(board[y-i][x-i] == player){
return 0;
}
}
}
return 1;
}
judge_(方角)関数(Ver. 斜め)。引数は置いた座標を表す二つの整数、黒と白を区別する整数、盤面であるint型2次元リスト。今回のオセロでは、2次元リストにオセロを配置する時、○を1、●を9として表現することとしました。これを利用していきます。例えば、○を置いた時、周りに●、すなわち9があればいいので、9=10−1と考えます。逆の時は1=10−9と考えれば、場合分けをしなくても両方に対応できます。また、挟める時にはもう一度1or9、自分のオセロが見つかればいいので、playerが見つかればいいということになります。for文ではyやxからiを足したり引いたりすることで、斜めへの移動を可能とします。
続いては、失敗コード
int judge_North_West(int x, int y, int player, int board[8][8]){ //x-1, y-1
if( y == 0 || x == 0){
return 1;
}
if(board[y-1][x-1] != 10 - player){
return 1;
} else {
for(int i = (y-1); i > 0; i--){
for(int j = (x-1); j > 0; j--0{
if(board[i][j] == 0){ //なし
return 1;
} else if(board[i][j] == player){
return 0;
}
}
}
}
return 1;
}
最初に私が書いてしまった失敗コードの忠実再現ではないですが、これは入門書等にも載ってる?かもしれない、for文の典型的ミスですね。斜めに調べる時は、xもyも同時に±1したい。こうしてしまうと、jのループを一通り終えたあと、iを一つ減らすといったことになり、y座標を固定して、x座標を全て調べてしまいます。しっかり反省して、以後気をつけるように。
これで斜めにおけるかどうかの判定ができるようになりました!さらに、1+9=10 を利用したことで、switch文を使わなくて良くなり、今まで書かれていた同じような処理を省略できました!(これで、100行近く減らせた)
が、しかし!オセロがひっくり返ってないので、最初の状態からプレイしてもデバッグができないのです、もちろんデバッグ用にオセロを適当に配置してもいいのですが、、、
ということで、次回、ついにオセロをひっくり返します。