I made this Rock Paper Scissors Game with GUI.
It works fine. But what can I do to make it simpler? Anybody?

import random

class RPC:

    def __init__(self):
        self.comChoice = ''
        self.choices = ['Rock','Paper','Scissors']

    def chooseCom(self):
        self.comChoice = self.choices[random.randint(0,2)]
        return self.comChoice

    def player(self, choice, Com):
        if choice == 'rock' and Com == 'Scissors':
            return ('You won!')
        elif choice == 'paper' and Com == 'Rock':
            return ('You won!')
        elif choice == 'scissors' and Com == 'Paper':
            return('You won!')
        elif choice == 'scissors' and Com == 'Rock':
            return ('You lost!')
        elif choice == 'rock' and Com== 'Paper':
            return('You lost!')
        elif choice == 'paper' and Com == 'Scissors':
            return ('You lost!')
        else:
            return ('Tie!')
from tkinter import *
import RPCclass

def ComputerChoice():
    game = RPCclass.RPC()
    c = game.chooseCom()
    return c

def winner(choice, Com):
    game = RPCclass.RPC()
    w = game.player(choice, Com)
    return w

def numWin(self, choice, Com):
    game = RPCclass.RPC()
    a = game.player(choice, Com)
    if a == 'You won!':
        self.numPlayerWin +=1
    elif a == 'You lost!':
        self.numComWin +=1
    else:
        self.numPlayerWin += 0
        self.numComWin +=0
    

    self.message4.config(text = 'Player won ' + \
                          str(self.numPlayerWin) + ' times.')
    self.message5.config(text = 'Computer won ' + \
                          str(self.numComWin) + ' times.')
    

class GUI: 
    def __init__(self): 
        root = Tk() 
        root.title('Welcome to Rock Paper Scissors')

        self.numComWin = 0
        self.numPlayerWin = 0


        self.label = Label(root, text='"Choose Rock, Paper, or Scissors."', 
                           fg='Black', 
                           bd=10) 
        self.label.grid(row=5, columnspan = 3) 

        

        self.button1 =  Button(root, text='Rock', 
                              bg='Blue', 
                              fg='white', 
                              padx=10, pady=5, 
                              command=self.buttonAction1) 
        self.button1.grid(row=7, column=0, rowspan=2)

        self.button2 =  Button(root, text='Paper', 
                              bg='Blue', 
                              fg='white', 
                              padx=10, pady=5, 
                              command=self.buttonAction2) 
        self.button2.grid(row=7, column =1, rowspan =2)

        self.button3 =  Button(root, text='Scissors', 
                              bg='blue', 
                              fg='white', 
                              padx=10, pady=5, 
                              command=self.buttonAction3) 
        self.button3.grid(row=7, column =2, rowspan=2)

        self.button4 =  Button(root, text='Reset', 
                              bg='black', 
                              fg='white', 
                              padx=10, pady=5, 
                              command=self.buttonAction4) 
        self.button4.grid(row=12, column =1, rowspan=2)
        

        self.message1 = Label(root, text='',fg='Black')
        self.message1.grid(row=9, columnspan=3)

        self.message2 = Label(root, text='',fg='Black')
        self.message2.grid(row=10, columnspan=3)

        self.message3 = Label(root, text='',fg='Red', font=('Times',16,'bold'))
        self.message3.grid(row=11, columnspan=3)

        self.message4 = Label(root, text='',fg='black')
        self.message4.grid(row=12, column=0, rowspan=2)

        self.message5 = Label(root, text='',fg='black')
        self.message5.grid(row=12, column=2, rowspan=2)
   
        root.mainloop()


    def buttonAction1(self):
        choice = 'rock'
        self.message1.config(text= 'You choose Rock.')
        Com = ComputerChoice() 
        self.message2.config(text= 'Computer has chosen %s.' % Com)
        self.message3.config(text = winner(choice, Com))
        numWin(self,choice, Com)
        
                
    def buttonAction2(self):
        choice = 'paper'
        self.message1.config(text= 'You choose Paper.')
        Com = ComputerChoice()
        self.message2.config(text= 'Computer has chosen %s.' % Com)
        self.message3.config(text = winner(choice, Com))
        numWin(self,choice, Com)
        
        
    def buttonAction3(self):
        choice = 'scissors'
        self.message1.config(text= 'You choose Scissors.')
        Com = ComputerChoice()
        self.message2.config(text= 'Computer has chosen %s.' % Com)
        self.message3.config(text = winner(choice, Com))
        numWin(self,choice, Com)

    def buttonAction4(self):
        self.message1.config(text= '')
        self.message2.config(text= '')
        self.message3.config(text= '')
        self.numComWin = 0
        self.numPlayerWin = 0
        numWin(self,0, 0)
        self.message4.config(text = '')
        self.message5.config(text = '')
        
GUI()

Dani AI

Generated

Nice start, . You can shrink both logic and GUI code by (1) normalizing case once, (2) using random.choice() to pick the computer move, and (3) expressing the rules as a small set of winning pairs instead of many if/elif lines. That keeps the game logic pure and easy to test. (docs.python.org)

import random

CHOICES = ('rock', 'paper', 'scissors')
WINS = {('rock', 'scissors'), ('paper', 'rock'), ('scissors', 'paper')}

def play_round(player):  # player is 'rock'/'paper'/'scissors'
    comp = random.choice(CHOICES)
    if player == comp:
        result = 'Tie!'
    else:
        result = 'You won!' if (player, comp) in WINS else 'You lost!'
    return comp.title(), result

On the GUI side, you do not need three separate callbacks or to create a new game object each click. Keep one handler and pass the player’s choice via the button’s command using functools.partial. Also use StringVar with textvariable so labels update without repetitive .config(...) calls. This makes the code shorter and more maintainable. (docs.python.org)

import tkinter as tk
from functools import partial

root = tk.Tk()
you = tk.StringVar(); comp = tk.StringVar(); outcome = tk.StringVar()

def on_click(choice):
    c, r = play_round(choice)
    you.set(f'You chose {choice.title()}.')
    comp.set(f'Computer chose {c}.')
    outcome.set(r)

for i, label in enumerate(('Rock', 'Paper', 'Scissors')):
    tk.Button(root, text=label,
              command=partial(on_click, label.lower())).grid(row=0, column=i)

’s dictionary idea is good; the set-of-tuples above is a similar, compact pattern. Whichever you pick, keep one game state (win counters) on the GUI instance instead of instantiating a new object per click, and prefer command= for buttons over manual <Button-1> binding for simple click actions. (docs.python.org)

Recommended Answers

All 2 Replies

It's personal preference, but I would use a dictionary in the players() function.

def player(self, choice, Com):
        win_d = { 'rock':'Scissors', 'paper':'Rock',
                       'scissors':'paper'}
        if choice.lower() == Com.lower():
            return 'Tie!'
        elif win_d[choice] == Com:
            return 'You won!'
        else:
            return 'You lost!'

Also, you can create all four buttons with one function, and use one function as the call-back if you pass the button number to that function. Note that this is from memory so if there are problems or you don't understand something, post back.

def __init__(self, root):
        self.root = root
        self.create_button('Rock', 7, 0, 1)
        self.create_button('Paper', 7, 1, 2)
        self.create_button('Scissors', 7, 2, 3)
        self.create_button('Reset', 12, 1, 4)

    ##-------------------------------------------------------------------
    def create_button(self, text_in, row_in, col_in, num_in):
        ret_button =  Button(self.root, text=text_in,
                              bg='Blue',
                              fg='white',
                              padx=10, pady=5)
        ret_button.grid(row=row_in, column=col_in, rowspan=2)

        def handler(event, self=self, button_num=num_in):
            return self.cb_handler(event, button_num)
        ret_button.bind("<Button-1>", handler)

    ##-------------------------------------------------------------------
    def cb_handler(self, event, button_num):
        button_dict = { 1:'Rock', 2:'Paper', 3:'Scissors' }
        if button_num in button_dict:
            choice = button_dict[button_num]
            self.message1.config(text= 'You choose ' + choice)
            Com = ComputerChoice()
            self.message2.config(text= 'Computer has chosen %s.' % Com)
            choice = choice.lower()
            self.message3.config(text = winner(choice, Com))
            numWin(self,choice, Com)
        else:     ## 4 is the only other button option
            self.message1.config(text= '')
            self.message2.config(text= '')
            self.message3.config(text= '')
            self.numComWin = 0
            self.numPlayerWin = 0
            numWin(self,0, 0)
            self.message4.config(text = '')
            self.message5.config(text = '')

Finally, it you are going to be coding in python you want to read and follow the style guide here http://www.python.org/dev/peps/pep-0008/ variable names are all lower case with underscores for example.

nice!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.