Reputation: 124
Good day all,
I have been working on creating a GUI for my Tic Tac Toe game using PySimpleGUI. My code is as follow:
import PySimpleGUI as sg
import random
board_layout1 = {(2,0):" ", (2,1):" ", (2,2): " ", (1,0): " ", (1,1): " ", (1,2): " ", (0,0): " ", (0,1): " ", (0,2): " "}
Board layout is based on:
I then created an interface to take in user input (i.e. name and choosing X or O symbol).
layout = [
[sg.Text("Please enter your Name and your opponent's name")],
[sg.Text('Name', size=(15, 1)), sg.InputText('')],
[sg.Text('Name of opponent', size=(15, 1)), sg.InputText('')],
[sg.Frame(layout=[
[sg.Radio('X', "RADIO1", default=True, size=(10,1)), sg.Radio('O', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags')],
[sg.Submit(), sg.Cancel()]
]
window = sg.Window('Tic Tac Toe Game').Layout(layout)
button, events = window.Read()
print(events)
window.close()
player1, player2, player1_event, player2_event = events[0], events[1], events[2], events[3]
player1 and player2 will return their names. Player1_event and player2_event will return True or False. As I am using a checkbox, events2 will be True if I checked it while events[3] will be False.
I then assign the marker respectively.
if player1_event == True:
player1_marker, player2_marker = ("X", "O")
else:
player1_marker, player2_marker = ("O", "X")
Now, I will create the GUI for the board.
def board_gui():
max_row = max_col = 3
layout = [[sg.Button(' ', size=(8, 4), key=(i,j), pad=(0,0)) for j in range(max_col)] for i in range(max_col)]
window = sg.Window('Tictactoe', layout)
button, events = window.Read()
return button
window.close()
Next (where the problem is), I created the function to update the board accordingly. So let's say if play1 starts first and he decided to choose 'X' as his marker. He picked the first grid and click on it. It marks 'X'. So the next click should belong to play2, whose marker is 'O'. My code seems to have issue updating the marker for the second click.
What I did:
def board_gui_update(marker):
max_row = max_col = 3
layout = [[sg.Button(' ', size=(8, 4), key=(i,j), pad=(0,0)) for j in range(max_col)] for i in range(max_col)]
window = sg.Window('Tictactoe', layout)
while True:
button, events = window.Read()
if button in (None, 'Exit'):
break
window[button].update(marker)
window.close()
What I have tried:
def board_gui_update(marker):
max_row = max_col = 3
layout = [[sg.Button(' ', size=(8, 4), key=(i,j), pad=(0,0)) for j in range(max_col)] for i in range(max_col)]
window = sg.Window('Tictactoe', layout)
while True:
button, events = window.Read()
if button in (None, 'Exit'):
break
if marker == player1_marker:
turn = player1
if turn == player1:
window[button].update(player1_marker)
turn = player2
else:
window[button].update(player2_marker)
else:
if marker == player2_marker:
turn = player2
if turn == player2:
window[button].update(player2_marker)
turn = player1
else:
window[button].update(player1_marker)
window.close()
Doesn't seem to work here as well. I have looked into the documentations and also solutions that involved tkinter but nothing seems to be able to update the marker.
You can view the issue in this snapshot.
Upvotes: 4
Views: 4026
Reputation: 1
Based on the samples above, I made this code wich can alternate between the 'O' and 'X'.
I used a variable that alternates between False and True, and two ifs that identifies the values inside window[event].get_text()
, analysis it and changes the variable.
import PySimpleGUI as sg
layout = [[sg.Button(' ', size=(8,4)), sg.Button(' ', size=(8,4)),
sg.Button(' ', size=(8,4))],
[sg.Button(' ', size=(8,4)), sg.Button(' ', size=(8,4)),
sg.Button(' ', size=(8,4))],
[sg.Button(' ', size=(8,4)), sg.Button(' ', size=(8,4)),
sg.Button(' ', size=(8,4))]]
turn = True
window = sg.Window('Tic Tac Toe', layout)
while True: # Event Loop
event, values = window.read()
print(event, values) #Just for development purposes.
if event in (None, 'Exit'):
break
current_marker = window[event].get_text()
# I placed all updates conditionals inside this, works better than
# individuals 'ifs' for each of they.
window[event].update('X' if current_marker == ' ' and
turn == True else 'O' if current_marker == ' ' and
turn == False else 'X' if current_marker == 'X'
else 'O' if current_marker == 'O' else ' ')
# The conditionals that change which value should be inserted.
if window[event].get_text() == 'X':
turn = False
elif window[event].get_text() == 'O':
turn = True
window.close()
Upvotes: 0
Reputation: 5754
See if this does what you're after. Every time you click on a square, it will change to a new marker. I think you're saying you cannot change the value shown on the button. This program shows you how to do it.
import PySimpleGUI as sg
layout = [[sg.B(' ', size=(8,4), key=(i,j)) for i in range(3)] for j in range(3)]
window = sg.Window('Tic Skeleton', layout)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
current_marker = window[event].get_text()
window[event].update('X' if current_marker == ' ' else 'O' if current_marker == 'X' else ' ')
window.close()
Upvotes: 1