I tried to make GUI tic-tac-toe with Python and Tkinter

at first

For learning python, it's okay to copy and paste something like "CUI Othello in Python!" That is lying around, but looking back, what's wrong? Even if you try to understand each one, the amount is large (not large) for beginners.

After all, the best way to acquire knowledge is to move your hands and memorize it while worrying about it! So, for a while, I decided to use CUI Othello as a GUI without relying on existing code. I don't know what to start with ...

It's a common story for beginners to try something extra and frustrate, so for the time being, I changed my direction to tic-tac-toe. I feel like I can do it just by lowering the level a little. It's simple.

I lose motivation when I think about it before I make it, so I tried to make a tic-tac-toe by the code addition method, which I investigated and implemented as needed.

The code that appears in the middle is cut out from the finished product, so it may be a little hard to see, but it's not bad. The big picture is at the bottom of the page

Finished image Tictac.gif

Make for the time being

First, make a screen. Equipped with a button. I press the button. I will start from here.


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('Tic-tac-toe')
    TictapApp(root)
    root.mainloop()


if __name__ == '__main__':
    main()

Apparently, if you import something called Tkinter, you can install GUI functions. It seems that you can change the appearance in various ways by giving various attributes to the button, but here is a 3x3 arrangement with fewer buttons than the calculator while imitating the calculator. If there is mainloop () in the main function, it seems that you can operate it as long as you do not close the window. It wasn't possible to put a function in the Button, and as a result of various trials and errors, it settled down to the above.

Self that you can see even if you don't like using python. I don't fully understand it yet, but if I define the variables used in multiple functions with self, I can manage it. It is about recognition.

If you proceed while executing it, you can keep your motivation as if something is completed, and you can feel which code plays what role, so I used it this time when I wanted to make something else. It seems that the parts can be applied as a business trip set.


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

If the screen is created, we will add functions this time. When you press the button, you want to display 〇 or × where you press it, so add the mark function to the Tictac class. If you use the bind method of Button, it seems that you can execute the function when the button is pressed, so create a function that displays characters on the button when pressed. Overwrite the text of event.widget with str ('string').


    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

If you can press a button, it seems that you need to record which player pressed which button, so create a record function. I created a set_value function because the container that holds the record is likely to be too tight. In addition, the current player information and parameters for final judgment are also included. In the record function, the player's acquisition information is set in the container, it is judged whether the three lines are lined up, the players are replaced, and if it is settled, the board is returned to the initial state. I was very busy. It's a bad part of the code addition method.


    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()

Since it became necessary to determine whether the third line was lined up, I created a line_check function. If you look inside vertically, horizontally and diagonally and there are three values that are the same as the player, the game is over. The last diagonal judgment was solved by force.


    def game_end(self):
        if self.player == 1:
            messagebox.showinfo('Settlement', 'The victory of the leading player!')
        else:
            messagebox.showinfo('Settlement', 'The second player wins!')
        self.finish = 1

If you line up three, you have to let us know the victory or defeat. Implementation of the game_end function. When the game_end function is called, a message box will appear to let you know the outcome and set the final flag.


    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()

If it is not settled, the player will be replaced, and if it is, the board will be created again and initialized. That's how the tic-tac-toe is completed.

Impressions I made

I added the code on the spot, so in the end it became extremely hard to see. .. .. It's completed, so it's okay! If you try to make it beautifully while thinking about the whole picture, it will be awkward, but if you add functions as needed while making it, I feel that it is easy to bring it to completion while maintaining motivation as it is. If you add one by one, it will be checked each time, so it was easy to digest.

This time I learned the function of pressing a button to execute a function, so next I would like to make something that has more functions while incorporating it.

The whole code of the finished product


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('Settlement', 'The victory of the leading player!')
        else:
            messagebox.showinfo('Settlement', 'The second player wins!')
        self.finish = 1

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


def main():
    root = Tk()
    root.title('Tic-tac-toe')
    TictacApp(root)
    root.mainloop()


if __name__ == '__main__':
    main()

Recommended Posts

I tried to make GUI tic-tac-toe with Python and Tkinter
I tried to make a periodical process with Selenium and Python
I tried to make a periodical process with CentOS7, Selenium, Python and Chrome
I tried to make a simple mail sending application with tkinter of Python
I tried to make Kana's handwriting recognition Part 3/3 Cooperation with GUI using Tkinter
I tried to make various "dummy data" with Python faker
Fractal to make and play with Python
[5th] I tried to make a certain authenticator-like tool with python
[2nd] I tried to make a certain authenticator-like tool with python
[3rd] I tried to make a certain authenticator-like tool with python
I tried to make a 2channel post notification application with Python
I tried to make a todo application using bottle with python
[4th] I tried to make a certain authenticator-like tool with python
I tried to easily detect facial landmarks with python and dlib
[1st] I tried to make a certain authenticator-like tool with python
I tried to make an image similarity function with Python + OpenCV
[Python] I tried to make an application that calculates salary according to working hours with tkinter
I want to make a game with Python
I tried Jacobian and partial differential with python
I tried to get CloudWatch data with Python
I tried function synthesis and curry with python
I tried to make a calculator with Tkinter so I will write it
[AWS] [GCP] I tried to make cloud services easy to use with Python
I tried to make a traffic light-like with Raspberry Pi 4 (Python edition)
[Zaif] I tried to make it easy to trade virtual currencies with Python
I tried fp-growth with python
Programming with Python and Tkinter
I tried scraping with Python
I tried gRPC with Python
I tried to read and save automatically with VOICEROID2 2
I tried to implement and learn DCGAN with PyTorch
I want to handle optimization with python and cplex
I tried to implement Minesweeper on terminal with python
I tried to get started with blender python script_Part 01
I tried to touch the CSV file with Python
I tried to draw a route map with Python
I tried to solve the soma cube with python
Continuation ・ I tried to make Slackbot after studying Python3
I tried to automatically read and save with VOICEROID2
I tried to get started with blender python script_Part 02
I tried to implement an artificial perceptron with python
I tried to automatically generate a password with Python3
I tried to analyze J League data with Python
I tried to implement Grad-CAM with keras and tensorflow
I tried to make an OCR application with PySimpleGUI
I tried to solve AOJ's number theory with Python
I tried to automate internal operations with Docker, Python and Twitter API + bonus
[Patent analysis] I tried to make a patent map with Python without spending money
[ES Lab] I tried to develop a WEB application with Python and Flask ②
I tried to make a simple image recognition API with Fast API and Tensorflow
I tried to predict and submit Titanic survivors with Kaggle
I tried to find the entropy of the image with python
Try to make it using GUI and PyQt in Python
I tried to simulate how the infection spreads with Python
I tried to make a real-time sound source separation mock with Python machine learning
I tried various methods to send Japanese mail with Python
I tried to touch Python (installation)
I tried web scraping with python.
I tried follow management with Twitter API and Python (easy)
I tried to automate the article update of Livedoor blog with Python and selenium.
[GUI with Python] PyQt5-Drag and drop-