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
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.
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.
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