Othello-判定(2017/10/9)
いろいろどたばたしてて間があいたが,まぁ現状読者もいないので問題ないだろう.
特に気にすることもなく気楽に更新する.
前回の更新はオセロの初期配置のみでしょうもないものだったが安心してほしい
今回からは本格的にゲームに重要なあたりを書く.
オセロのルールとして最低1枚以上相手の石をひっくり返すことのできる場所にしか置けないと言ったものがある.
これを実装するにはどうするのがいいのか.
アルゴリズムとしては簡単で
周囲8マスを走査し,それぞれでplayer_colorでない石が置かれていればその方向に走査をのばす.その方向の延長線上にplayer_colorの石があればokといったものである.
とりあえず実装するにあたって便利なので指定方向の反転可能な石の数を返す関数と,それを組み込んだ正当性判定の関数を作ろうと思う.
以下は指定方向の石の数を返す関数である.
def can_turn_over(board,player_color,p,q,d,e):
i = 1
while(board[p+i*d][q+i*e]==enemy_color(player_color)):
i+=1
if(board[p+i*d][q+i*e]==player_color):
return i-1;
else:
return 0;
簡単に引数と動作を解説すると,
(オセロ板の配列,置く石の色,石を置くy座標,石を置くx座標,y方向のベクトル,x方向のベクトル)
最後の2つには,それぞれ{-1|0|1}が入る
中で使ってるenemy_color(player_color)という関数だがこれはただ引数にいれられた石の色ではない色を返すだけの関数なので記載は省略する.
やってる内容は指定方向の次の石が違う色である間,返す値を加算し,while文を抜けたあとの次の石の色が自分のものであれば,挟んだ判定となり反転可能な石の数を返す.それ以外(つまり石がない,または場外)の場合,挟めていないので0を返す.
再帰で書いたほうがスマートだと思うが,面倒なのでまた別の記事で行おうと思う.
次は正当性の判定(指定した座標に石を置けるか置けないか)
def can_put(board,player_color,p,q):
if(p<1 or 8<p or q<1 or 8<q):
return 0;
elif(board[p][q] != 0):
return 0;
for i in range(-1,2,1):
for j in range(-1,2,1):
if(i==j==0):
None;
elif(can_turn_over(board,player_color,p,q,i,j) >0):
return 1;
else:
None;
return 0;
やってることが書いてるまんますぎるので解説はなし.
ただただ指定方向上の反転可能な石の数が0以上なら1返して,0なら0返すだけ.
またしばらく更新は止まると思うが,時間があれば更新するつもり.