Reputation: 15
So I've been teaching myself some tkinter to start building some real apps, and my first project is to build an interface for the Courera's all-too-famous Rock-Paper-Scissors-Lizard-Spock game.
Up to now I have all the buttons working fine enough (even though I feel like they are not updating anything if i repeatedly click on the same button without changing choice, as the result of the match never changes) and the result panel also works. that's what's makng me crazy, as far as I can see, the win counters and the computer choice panel follow the same logic and for some reason are not updating when I click a button. any hints?
Thanks already for the patience, and code as follows
import tkinter as tk
import random
from functools import partial
#setting the window early as I had issues and bugs when called after defining functions
window = tk.Tk()
window.geometry('350x200')
#global variables
result= tk.StringVar()
result.set("")
comp = tk.IntVar()
guess = tk.StringVar()
guess.set("")
playerWin = tk.IntVar()
playerWin.set(0)
compWin = tk.IntVar()
compWin.set(0)
#function that handles the computer's play in each game
def compPlay():
global guess, comp
comp.set(random.randrange(0,5))
if comp.get()== 0:
guess.set("Rock")
elif comp.get()== 1:
guess.set("Spock")
elif comp.get() == 2:
guess.set("Paper")
elif comp.get() == 3:
guess.set("Lizard")
elif comp.get() == 4:
guess.set("Scissors")
#function to play human vs computer choices and see who wins
def gameplay(playerNum,compNum):
global result, comp, playerWin, compWin
if playerNum == comp.get():
result.set("It's a tie!")
elif (playerNum - comp.get()) % 5 <= 2:
result.set("Player wins!")
playerWin = playerWin.get() + 1
elif (playerNum - comp.get()) % 5 >= 3:
result.set("Computer wins!")
compWin += compWin.get() + 1
else:
result.set(text = "")
# game title
lblGame= tk.Label(text="Rock, Scissors, Paper, Lizard, Spock").pack()
#frame with the buttons for player choices
playerFrame = tk.Frame(window)
btRock = tk.Button(playerFrame, text = "Rock", width = 15, command = partial(gameplay, 0,compPlay)).pack()
btScissors = tk.Button(playerFrame, text = "Scissors", width = 15, command = partial(gameplay, 1,compPlay)).pack()
btPaper = tk.Button(playerFrame, text = "Paper", width = 15, command = partial(gameplay, 2,compPlay)).pack()
btLizard = tk.Button(playerFrame, text = "Lizard", width = 15, command = partial(gameplay, 3,compPlay)).pack()
btSpock = tk.Button(playerFrame, text = "Spock", width = 15, command = partial(gameplay, 4,compPlay)).pack()
playerFrame.pack(side = tk.LEFT)
#frame with info about the game, as in what the computer chose and the result of the play
compFrame = tk.Frame(window)
lbComp = tk.Label(compFrame, text = "Computer plays:").pack()
lbGuess = tk.Label(compFrame, textvariable = guess, relief = tk.GROOVE, borderwidth = 5, width = 15).pack()
lbRes = tk.Label(compFrame, text = "and the result of the game is").pack()
lbMatch = tk.Label(compFrame, textvariable = result, relief = tk.GROOVE, borderwidth = 5, width = 15).pack()
#mini frames for score keeping
playerFrame = tk.Frame(compFrame, relief = tk.GROOVE, borderwidth = 3)
playerSide = tk.Label(playerFrame, text = "Player points:").pack()
playerScore = tk.Label(playerFrame, textvariable = str(playerWin)).pack()
playerFrame.pack(side = tk.LEFT)
compScoreFrame = tk.Frame(compFrame, relief = tk.GROOVE, borderwidth = 3)
compSide = tk.Label(compScoreFrame, text = "Computer points:").pack()
compScore = tk.Label(compScoreFrame, textvariable = str(compWin)).pack()
compScoreFrame.pack(side = tk.RIGHT)
compFrame.pack(side = tk.RIGHT)
window.mainloop()
I get this error on the console whenever the game should give points to either player:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
return self.func(*args)
File "~/Interactive Python/teste tkinter3.py", line 54, in gameplay
playerWin = playerWin.get() + 1
AttributeError: 'int' object has no attribute 'get'
Upvotes: 0
Views: 111
Reputation: 3448
There are several problems that are not working properly here:
compPlay()
function. This function should be called each time the player presses the left-hand button, but this function is unused in the gameplay
method. Simply call this function to refresh the computer guess and set the value of a label.gameplay
function the compWin
and playerWin
objects are not ints
but tkinter.Intvar
so you should set
their variables instead of using +
and +=
. This is the reason for this error.Upvotes: 1
Reputation: 1159
That's because playWin
is a tkinter.Intvar
object,you need to change the function gameplay
to:
def gameplay(playerNum, compNum):
global result, comp, playerWin, compWin
if playerNum == comp.get():
result.set("It's a tie!")
elif (playerNum - comp.get()) % 5 <= 2:
result.set("Player wins!")
playerWin.set(playerWin.get() + 1)
elif (playerNum - comp.get()) % 5 >= 3:
result.set("Computer wins!")
compWin.set(compWin.get() + 1)
else:
result.set(text="")
Upvotes: 2