pythonでオセロ(8×8)を作る方法

おはようございます!にわこまです。今回はpythonを使って(8×8)のオセロを作ってみました。

何かご指摘があればご連絡ください!

 

 

スポンサードサーチ


pythonでオセロを作る方法

今回はpythonを使って(8×8)のオセロを作ってみました。なぜ(8×8)を付けるのかというと、(8×8)のオセロを作る前に(4×4)のオセロを作ったからです。

(4×4)のオセロを作る方法はこちらから。

 

(4×4)のオセロを作ってから(8×8)のオセロを作っているため、比較的簡単に作ることができました。

また、(4×4)のオセロは約400行で作りましたが、(8×8)のオセロは少しプログラムを書きかえて約325行で作ることができました。

今回も(4×4)のオセロと同様に人間対コンピュータで対局するプログラムを作りました。

 

「pythonでオセロ(8×8)を作る方法のコード」はこちらのページに全て載せてあります。

 

 

アルゴリズム

まず、オセロのルールを確認します。

ルール
1. 先手は黒石、後手は白石です
2. 自分の石を相手の石を挟むように置く、置くことが出来なければpassを宣言します
3. 2で置いた石で挟まれている相手の石をひっくり返します
4-1. 先手、後手両者が石を置くことが出来なくなったら対局を終了します
4-2. 2で置いた石が、本来置くことが出来ないマス置いていたら反則負けとして対局を終了します
5. 対局が終了しなければ相手に手番が回ります
6. 対局が終了したら、盤面に残っている石を数えて、多い方を勝者とします

ルール4-1には2つの状態があります。
1つ目は盤面に全てに石が置かれている状態です。 2つ目は先手、後手両者が連続してpassを宣言した状態です。

 

 

スポンサードサーチ


コード

コードはこちらに全て載せてあります。

 

開発環境
OS : Windows 10
CPU : intel CORE i7 7th Gen
python : 3.7

 

プログラムを作りにあたってライブラリからインポートしたものを紹介します。ライブラリからインポートするのは「numpy」「random」「copy」です。

今回定義した関数は以下の10つです。
・stone_location(stone)
・empty_location(stone_list)
・bw_turn(TURN)
・update_field(TURN, point, offset_list)
・address2point(address)
・point2offset(point, TURN)
・address_check(point, TURN)
・point2address(point)
・show_resutl()
・main()

 

また、今回定義したグローバル変数は以下の11つです。

# define
global EMPTY
EMPTY = 0
global BLACK
BLACK = 1
global WHITE
WHITE = 2
global Player
global Computer
global TURN

global field
field = np.array([[0,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0],
                  [0,0,0,2,1,0,0,0],
                  [0,0,0,1,2,0,0,0],
                  [0,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0]])

global field_address
field_address = np.array([["a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"],
                          ["a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2"],
                          ["a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3"],
                          ["a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4"],
                          ["a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5"],
                          ["a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6"],
                          ["a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7"],
                          ["a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8"]]) # 4

global offset
offset = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 0), (0, 1), (1, -1), (1, 0), (1, 1)]

 

定義した関数について説明してきます。

まず、「stone_location(stone)」と「empty_location(stone_list)」について説明していきます。

stone_location(stone)」は、引数にBLACKかWHITEを代入します。「stone_location(stone)」は引数に代入された色の石がどこにあるか調べて、そのマスの座標をリストとして返却します。

empty_location(stone_list)」は、「stone_location(stone)」から得られたリストを引数に代入します。リストから座標を1つずつ取り出し、その座標のマスから8方向を調べます。

その8方向に空欄のマスがあったら、その座標とその方向をdictionary型で返却します。

以下の画像のような感じです。(0, 0)が基準マスになります。

 

次に、「bw_turn(TURN)」について説明します。(4×4)のオセロでは「black_turn()」と「white_turn()」として定義していました。

bw_turn(TURN)」は、引数にBLACKかWHITEを代入します。引数に代入された色の石の手をタプル型で座標(point)とリスト型でひっくり返す方向(offset_list)の2つを返します。

 

次に、「update_field(TURN, point, offset_list)」について説明します。これは盤面を更新するための関数です。

update_field(TURN, point, offset_list)」は、
引数のTURNにBLACKかWHITE、
pointに「bw_turn(TURN)」のタプル型の座標、
offset_listに「bw_turn(TURN)」のリスト型のひっくり返す方向
を代入します。 引数に代入された石の色に盤面を更新していき、fieldを返却します。

 

次に、「address2point(address)」と「point2offset(point, TURN)」と「address_check(point, TURN)」について説明します。

address2point(address)」は、プレイヤーから入力された文字列の手(「a1」,「d4」など)を座標に変える関数です。引数には、プレイヤーから入力された文字列の手を代入します。

また、それに対応した座標(point)を返却します。

point2offset(point, TURN)」は、「address2point(address)」で返却されたpointとTURNにBLACKかWHITEを代入します。引数のTURNに代入された石の色の視点から盤面を見ます。引数のpointの座標に石を置いたとき、石をひっくり返す方向をリスト型で返却します。

イメージ的には、
bw_turn(TURN)」で返却されるタプル型の座標を「address2point(address)」が担当していて、リスト型のひっくり返す方向を「point2offset(point, TURN)」が担当している感じです。

address_check(point, TURN)」は、プレイヤーが入力した手が有効であるか?ないか?を判定する関数です。

address_check(point, TURN)」は、引数に「address2point(address)」から返却されるpointとTURNにBLACKかWHITEを代入します。

引数のTURNに代入された石の色の視点から見ます。その時pointは置くことが可能な座標であるか判定し、TrueまたはFalseを返却します。

 

次に、「point2address(point)」について説明します。これは、「address2point(address)」と逆のことを行っている関数です。

point2address(point)」は、引数に座標を代入します。引数に代入された座標を文字列(「a1」,「d4」など)に変える関数です。

 

次に、「show_result()」について説明します。この関数は結果を表示する関数です。盤面に全て石が置かれている場合のみ結果を表示するように設定されています。

 

次に、「main()」について説明します。これは、オセロ(8×8)を実装している関数です。

上記で説明した関数やグローバル変数を使ってオセロ(8×8)を実装しています。 アルゴリズムで説明した通りにほぼ書かれています。

 

 

グローバル変数について説明していきます。

まず、「EMPTY」、「BLACK」、「WHITE」、「Player」、「Computer」について説明していきます。これらは、石または空欄を判別する変数と手番を判別する変数です。

 

次に、「field」、「field_address」について説明していきます。

field」は、配列によって盤面を表現しています。「field_address」は、1マス1マスの名称(「a1」、「d4」など)を座標に対応して定義しています。

 

次に、「offset」について説明します。「offset」は、石をひっくり返す方向や基準マスからの方向を調べるときに使う変数です。

 

 

使い方

コードはこちらに全て載せてあります。

 

手順

(1) pythonのコードを任意の名前で保存してください。

(2) ご自身のPCでコマンドプロンプトを起動してください。

(3) pythonのコードを保存したフォルダまで移動してください。

(4) コマンドプロンプトに「python othello.py」と入力して、エンターを押してください。(othello.pyと保存した場合)

(5) 以上で、コマンドプロンプト上で(8×8)のオセロをプレイすることができます。

 

注意
・コマンドプロンプト上でのプレイはかなり見にくいです。
・空欄を「0」、黒を「1」、白を「2」で表現しています。
・手順の(4)は、path の関係により「python」が「python3」になります。

 

 

スポンサードサーチ


まとめ

今回はpythonで(8×8)のオセロを作ってみました。

コマンドプロンプト上でプレイするプログラムだったためとても見にくく、プレイしにくいオセロになってしまいました。

次回は「pygame」を使って、グラフィカルにもっと見やすく、プレイしやすいオセロにしたいと思います。

最後まで読んでいただきありがとうございます。


スポンサードサーチ