【はじめてのPython】オセロを作る②~石を置いてみる~

ITスキル

こんにちは。ヒトツメです。
前回に引き続き、今回もオセロを作ってみるということで話を進めていきますが、今回は実際に石を置いてみるときの処理について考えていきます。

【はじめてのPython】オセロを作る①~最初の盤面を作る~
こんにちは。ヒトツメです。前回に引き続き、Python 3についての記事を投稿していこうと思います。前回は、Anacondaを使って Pythonを使える環境を作り、「Hello World!」が成功しました。 初めから一つ一つ構文などを覚...
スポンサーリンク

石を置いてみる

前回、初期の盤面を作ることに成功しましたが、今回、初期の盤面において、4行目の5番目の位置を「白(1)」にすることを考えていきます。この時、まずはじめに、該当の部分を「1」に変更するという処理をする必要があります。
したがって、「game[3][5]=1」という処理を入れる必要があります。ここは別に難しくもなんともありません。

ただ、これだと、game[3][4]の位置が、「-1」のままです。ここで単に「game[3][4]=1」などとしていくだけでは芸がありませんので、実際にこの部分を「1」にするときに人間が考える思考にしたがって、どの部分を「1」にしていくかを考えていきます。

全方向を確認する

そこでまず、石を置く場所を基準に、8方向を見ていきます。この時、その方向に相手の石があれば、その石をひっくり返す必要があるかもしれないので、さらに判定していく必要がありますが、そうでなければ、ひっくり返すかどうかをみる必要はありません。

置いた石を基準に8方向を確認し、その方向に相手の石があるかどうかを見ていく

このとき便利なのが、「for文」という表現です。
「for 変数 in オブジェクト:」という構文で、オブジェクトを一つ一つ取り出し、取り出した値を変数として以下に続く文を繰り返し処理します。
例えば次のような表現によってprint部分を繰り返すことが可能です。

オブジェクトとして指定されているリストの要素を一つ一つ取り出し、iterという変数の中に入れ込み、続くprintの部分を繰り返す

これとrange関数という関数を併用して、指定した回数の繰り返しを表現することができます。
range関数は、整数の引数を一つ指定すると、0から1ずつ引数分増えていくリストを返却することができます。例えば「range(5)」の中身は、「[0, 1, 2, 3, 4]」となります。
引数を複数指定すると、第一引数を起点として、第三引数ずつ増える、第二引数の長さのリストを返却します。

for dc in range(-1, 2, 1):
    for dr in range(-1, 2, 1):
        if game[3 + dr][5 + dc] == -1:
            #相手の石があるためひっくり返すかどうかの判定が必要
            #→その先に自分の石があるかを判定
        else:
            #ひっくり返す必要はないためスルー

以上より、このような記載により、8方向を順番に見て、相手の石があるかどうかを判定することができます。
ちなみに、「#」を入れると、それ以降はコメントとして認識され、処理されません。
また、pythonでは、「=」は、左辺の変数に右辺の定数を入れ込む場合に利用し、右辺と左辺が同じ場合にTrueを返すためには、「==」と記載します。なので、if文のなかでは、「==」を使います。

石を置いた場所を基準として、drとdcを-1から1まで1ずつ増やしながら順番に8方向を見ていき、そこに相手の石があればひっくり返す可能性があるという判定をしていくということです。

さらにその先に自分の石があるか

さらにその先に自分の石があるかということに関しては、dcとdrを整数倍していき、その場所に自分の石があるかどうかを見ていきます。
下の図に記載されている通り、dcとdrを整数倍すると、石を置いた場所を基準として、さらにその先にある場所の位置を判定することが可能です。

この時も先ほどの同じようにfor文を使って処理をすることが考えられます。
オセロは8マスなので、一番遠くても、7マス先です。なので、「for length in range(2, 8 ,1):」という記載で一つ一つ見ていくことが可能です。
この時、そのマスにある石が自分の石なら、その間にある相手の石をすべてひっくり返します(自分の石と同じ石にします)。
このような処理を先ほどのコードと続けて記載すると次の通りになります。

game[3][5] = 1
for dc in range(-1, 2, 1):
    for dr in range(-1, 2, 1):
        if game[3 + dr][5 + dc] == -1:
            #一8向を見ていき、相手の石があればひっくり返すかどうかの判定に移る
            for length in range(2, 8, 1):
                #石を置いた場所を基準としてさらにその先を見ていく
                if game[3 + dr * length][5 + dc * length] == 1:
                    #自分の石があれば処理をする
                    for iter in range(length):
                        #自分の石がある場所まで一つ一つ処理をする
                        game[3 + dr * iter][5 + dc * iter] = 1

実際に処理をすると、このように、game[3][4]の位置が「1」になりました。
とはいえ、これだけだと、実はエラーが出てしまいます。次回は、この構文を少し圧縮しつつ、エラーを回避する部分についても入れていこうと思います。

コメント

タイトルとURLをコピーしました