〇✕ゲームを作ってみた

#動機
小さい頃、三目並べというゲームを空いている少しの時間で友達とやるのが自分のブームだったという時があった。だから今回作ってみようと思った。

***

##実行結果

 ![スクリーンショット (39).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638197/62519a54-522f-40f3-e516-71d9b272493f.png)

***

### 内容

 画面とボタンを作る

```python
from tkinter import *
from tkinter import ttk
from tkinter import messagebox

squares = 3

class TictacApp(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.create_widgets()
        self.set_value()

    def create_widgets(self):
        for i in range(squares):
            for j in range(squares):
                button = ttk.Button(self, command=self.record(i, j))
                button.bind('<Button-1>', self.mark)
                button.grid(column=i, row=j, sticky=(N, S, E, W))

        for i in range(squares):
            self.columnconfigure(i, weight=1)
            self.rowconfigure(i, weight=1)

        self.master.columnconfigure(0, weight=1)
        self.master.rowconfigure(0, weight=1)

        self.grid(column=0, row=0, sticky=(N, S, E, W))


def main():
    root = Tk()
    root.title('〇✕ゲーム')
    TictapApp(root)
    root.mainloop()


if __name__ == '__main__':
    main()
```
***

 〇や✕を表示

```python
def mark(self, event):
        if not event.widget['text']:
            if self.player == 1:
                event.widget['text'] = str('〇')
            else:
                event.widget['text'] = str('×')

```
***

押したボタンを記憶

```python

def record(self, i, j):
        def x():
            if not self.field[i][j]:
                self.field[i][j] = self.player
                self.line_check()
                self.change_player()
                self.clear()
        return x

    def set_value(self):
        self.player = 1
        self.field = []
        for i in range(squares):
            self.field.append(['' for i in range(squares)])
        self.finish = 0

```
***
三目並んでいるか判定

```python
    def line_check(self):
        cross = 0
        for i in range(squares):
            horizon = 0
            vertical = 0
            for j in range(squares):
                if self.field[i][j] == self.player:
                    horizon += 1
                if self.field[j][i] == self.player:
                    vertical += 1
            if self.field[i][i] == self.player:
                cross += 1
            if horizon == 3 or vertical == 3 or cross == 3:
                self.game_end()
        if self.field[0][2] == self.field[1][1] == self.field[2][0] == self.player:
            self.game_end()
```
***
　勝敗を知らせる

```python
   def game_end(self):
        if self.player == 1:
            messagebox.showinfo('おめでとう！', '先行の勝利')
        else:
            messagebox.showinfo('おめでとう！', '後攻の勝利')
        self.finish = 1
```
決着がつかない場合

```python
    def change_player(self):
        if self.finish == 0:
            self.player = -self.player

    def clear(self):
        if self.finish == 1:
            self.create_widgets()
            self.set_value()
```
***

#### ソースコード
```python
from tkinter import *
from tkinter import ttk
from tkinter import messagebox

squares = 3


class TictacApp(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.create_widgets()
        self.set_value()

    def set_value(self):
        self.player = 1
        self.field = []
        for i in range(squares):
            self.field.append(['' for i in range(squares)])
        self.finish = 0

    def create_widgets(self):
        for i in range(squares):
            for j in range(squares):
                button = ttk.Button(self, command=self.record(i, j))
                button.bind('<Button-1>', self.mark)
                button.grid(column=i, row=j, sticky=(N, S, E, W))

        for i in range(squares):
            self.columnconfigure(i, weight=1)
            self.rowconfigure(i, weight=1)

        self.master.columnconfigure(0, weight=1)
        self.master.rowconfigure(0, weight=1)

        self.grid(column=0, row=0, sticky=(N, S, E, W))

    def mark(self, event):
        if not event.widget['text']:
            if self.player == 1:
                event.widget['text'] = str('〇')
            else:
                event.widget['text'] = str('×')

    def record(self, i, j):
        def x():
            if not self.field[i][j]:
                self.field[i][j] = self.player
                self.line_check()
                self.change_player()
                self.clear()
        return x

    def change_player(self):
        if self.finish == 0:
            self.player = -self.player

    def line_check(self):
        cross = 0
        for i in range(squares):
            horizon = 0
            vertical = 0
            for j in range(squares):
                if self.field[i][j] == self.player:
                    horizon += 1
                if self.field[j][i] == self.player:
                    vertical += 1
            if self.field[i][i] == self.player:
                cross += 1
            if horizon == 3 or vertical == 3 or cross == 3:
                self.game_end()
        if self.field[0][2] == self.field[1][1] == self.field[2][0] == self.player:
            self.game_end()

    def game_end(self):
        if self.player == 1:
            messagebox.showinfo('おめでとう！', '先行の勝利')
        else:
            messagebox.showinfo('おめでとう！', '後攻の勝利')
        self.finish = 1

    def clear(self):
        if self.finish == 1:
            self.create_widgets()
            self.set_value()


def main():
    root = Tk()
    root.title('OXゲーム')
    TictacApp(root)
    root.mainloop()


if __name__ == '__main__':
    main()
```
***


##### 作ってみた感想

今回参考にさせてもらった「PythonとTkinterでGUI三目並べ作ってみた」を見ながらしたが何をしているのか調べながらプログラムを書いていった。〇✕ゲームを作るだけでも私はとても苦労しました。また今回は参考にさせてもらったものがあったが1から作るとなればとても大変だと思った。これから自分一人で１から作れるように勉強しようと思った。

***


######　参考文献

- PythonとTkinterでGUI三目並べ作ってみた

   https://qiita.com/TN0321/items/d0ba918eefa5d9c7e587

- いちばんやさしいPython入門教室書　大澤文孝[著]