どん底から這い上がるまでの記録

どん底から這い上がりたいけど這い上がれない人がいろいろ書くブログ(主にプログラミング)

オセロ盤をつくる

オセロ盤を作ってみました。

できたのがこちら、

f:id:pytry3g:20180225233309p:plain

すごいシンプルな感じで作りました。

今回はオセロ盤を作るのみで、石の反転やマスがクリックされたときの処理は次回以降に書きます。

このオセロ盤を作るステップは

 1.  メインウィンドウをつくる

 2.  Canvasをメインウィンドウに貼る

 3.  Canvas上に線を引きマスをつくる。

 4.  オセロ盤の設定。

 5.  Labelを作る。

です。

1. メインウィンドウを作る

はじめに、メインウィンドウを作ります。

メインウィンドウの作り方は以前書いた記事で一応説明しています。

pytry3g.hatenablog.com

 

 

前回と違うのは、Tkクラスを継承してAppクラスを定義しているところのみです。

下のプログラムをベースにset_widgetsメソッドでwidgetを作ってメインウィンドウに配置していきます。

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super(App, self).__init__()
        self.title("オセロ")
        self.geometry("{}x{}+{}+{}".format(550, 550, 300, 100))
        self.resizable(0, 0)
        self.iconbitmap("othello.ico")
        self.configure(bg="white")
        self.set_widgets()

    def set_widgets(self):
        pass

    def run(self):
        self.mainloop()


if __name__ == "__main__":
    app = App()
    app.run()

 

2. Canvasを作る

Canvasの使い方ですが、今回やることは下の記事の説明で十分間に合うと思います。

 

pytry3g.hatenablog.com

 

はじめに、Canvasを使ってオセロ盤を作ります。

    def set_widgets(self):
        # オセロ盤
        self.board = tk.Canvas(self, bg="lime green", width=350, height=350)
        self.board.pack(pady=(30, 0))

 

f:id:pytry3g:20180226000357p:plain

 

3. Canvas上に線を引く

次に縦線と横線を引いてマスを作ります。

線をひく必要はなかった。

 

        # 縦線
        for x in range(15, 336, 40):
            self.board.create_line(x, 15, x, 335)
        # 横線
        for y in range(15, 336, 40):
            self.board.create_line(15, y, 335, y)

 

線を引かずに長方形を作ってマスを配置していきます。このマスの上に白と黒の石を配置するようになります。

例えば、長方形を作るには下のような感じ作ります。

    def set_widgets(self):
        # オセロ盤
        self.board = tk.Canvas(self, bg="lime green", width=350, height=350)
        self.board.pack(pady=(30, 0))

        # 長方形を作る
        self.board.create_rectangle((20, 20, 60, 50), fill="red")

(20, 20, 60, 50)で長方形の大きさを指定し、fillで背景の色を赤色にしています。

 

f:id:pytry3g:20180312144636p:plain

 

オセロ盤は8x8の64個のマスが必要となるので 下の画像になるように長方形を作っていきます。次のオセロ盤の設定のところで実際に64個の長方形を作っています。

 

f:id:pytry3g:20180226001036p:plain

 

4. オセロ盤の設定

続いて、オセロ盤の設定をします。

ここでしていることは、

 盤面の情報をもつリストを用意する。

 8x8の盤面をつくるために、64個の長方形を配置する。

 盤面の初期設定をする。

        # オセロ盤の設定
        self.board2info = [-1] * 10 + [[0, -1][i in [0, 9]] for i in range(10)] * 8 + [-1] * 10
        # tag
        self.numstr = '12345678'
        self.alpstr = "abcdefgh"
        # tagからクリックされたtagの位置を得る
        self.tag2pos = {}
        # 1次元の座標からtagを得る
        self.z2tag = {}
        # 長方形を配置する。
        for i, y in zip(self.numstr, range(15, 336, 40)):
            for j, x in zip(self.alpstr, range(15, 336, 40)):
                pos = x, y, x+40, y+40
                tag = i + j
                self.tag2pos[tag] = pos
                self.board.create_rectangle(*pos, fill="lime green", tags=tag)
                self.z2tag[self.z_coordinate(tag)] = tag
        # 初期設定
        for p, i in zip([1, 2], "45"):
            for q, j in zip([2, 1], "de"):
                color = ["black", "white"][p-q]
                tag = i + j
                self.board2info[self.z_coordinate(tag)] = [1, 2][p-q]
                self.board.create_oval(*self.tag2pos[tag], fill=color, tags=tag)
        self.get_board_info()

board2infoにはオセロ盤の情報を入れています。オセロ盤は8x8の8路盤ですが、

どこに石が置けるのか、どの石が反転できるのかを判定しやすくするために盤の外を加え10x10にして、さらに1次元の座標で表しています。

-1は盤外、0は空点、1は黒、2は白を表します。

 numstralpstrはtagに使います。tagを使う理由は2つあります。1つは、座標の位置を理解しやすくするため。もう1つは、Canvas上に長方形をつくるときに、すべての長方形にtagを設定するためです。

長方形にtagを設定することにより、オセロ盤がクリックされたとき、どの長方形がクリックされたのかを判別することができ、かつ、その長方形のtagを取得することができるようになります。

tag2posはtagからそのtagが設定されている長方形の座標を入れています。これは、石をひっくり返すときや空点に新しく石を置くときに使います。

z2tagは1次元の座標をtagに変換します。

z_coordinateはtagから1次元の座標を手に入れるために使います。

    def z_coordinate(self, tag):
        x = self.alpstr.index(tag[1])+1
        y = self.numstr.index(tag[0])+1
        return y*10 + x

tagは以下のような感じで上から順に1から8まで、左から順にaからhまでの数字とアルファベットを組み合わせて設定します。例えば一番左上は1a、一番左下は8aとなります。

 

f:id:pytry3g:20180226005024p:plain

 

get_board_infoはオセロ盤の情報を表示する。

    def get_board_info(self):
        board_format = " {:2d} " * 10
        print("", *[board_format.format(*self.board2info[i:i+10]) \
                                    for i in range(0, 100, 10)], sep='\n')

初期設定のところで、create_ovalを使い、マスの上に白と黒の石を配置しています。

初期設定をした後、オセロ盤の情報を表示すると、

こんな感じで表示されます。

f:id:pytry3g:20180226010242p:plain

 

5. Labelを作る

最後にLabelの設定をします。ラベルにはテキスト(手番)を表示するようにします。

手番が変わると、表示するテキストも変わるようにします。

やり方は以下の記事で書いてある通りです。

 

pytry3g.hatenablog.com

 

今回はキャンバスを作ってその上にラベルを配置しています。

        # Label
        self.turn = 1
        self.info = tk.Canvas(self, bg="white", width=300, height=100)
        self.info.pack(pady=(30, 0))
        self.var = tk.StringVar()
        self.update_label()
        self.label = tk.Label(self.info, bg="white",
                              font=("Helvetica", 15), textvariable=self.var)
        self.label.pack()

 

     def update_label(self):
        self.var.set("{}のターン".format(["AI", "あなた"][self.turn]))

と、ここまでオセロ盤の作り方をざっくり説明してみました。

今後このプログラムを空いているマスに石を置いたり、石を反転させれるようにするつもりです。

To be continued...

 

続き ↓↓↓

pytry3g.hatenablog.com