As always, I welcome feedback.
#! /usr/bin/env python3 # Do the imports import os import tkinter as tk from tkinter import messagebox from functools import partial import random as rnd # Used to close the register window without causing an error in console def close(event): os.sys.exit() # Define player class with some set values class Player: player_name = '' player_wins = 0 player_loss = 0 player_ties = 0 games_played = 0 # Define the game class class Game: def __init__(self, parent): # Set the parent window and ask for player name self.parent = parent self.register() # Function creates a form to get a player name def register(self): self.form = tk.Toplevel(None) self.form.geometry('+340+200') self.form.title('Player Name') self.form.configure(padx=10, pady=10) self.name_label = tk.Label(self.form, text='Enter Player Name', anchor='w', fg='blue', width=25) self.name_label.grid(column=0, row=0, sticky='nw', pady=5, columnspan=2) self.name_entry = tk.Entry(self.form, width=25) self.name_entry.grid(column=0, row=1, columnspan=2) self.name_entry.focus() self.quit_btn = tk.Button(self.form, text='Cancel', fg='red', command=os.sys.exit) self.quit_btn.grid(column=0, row=2, pady=5, sticky='w') self.btn = tk.Button(self.form, fg='green', text='Submit', command=partial(self.getname)) self.btn.grid(column=1, row=2, pady=5, sticky='e') # Some bind keys player can use the enter keys instead of clicking buttons self.form.bind('<Return>', self.getname) self.form.bind('<KP_Enter>', self.getname) self.form.bind('<Escape>', close) self.form.protocol('WM_DELETE_WINDOW', os.sys.exit) self.parent.withdraw() self.form.mainloop() # Handles the form processing def getname(self, event): # Convert the form entry to a simple variable name = self.name_entry.get() # Check to see if the name is empty. If empty throw an error. if not name: msg = messagebox.showwarning(title='No Name Entered', message='You must enter a name to play.') # See if the name is greater than 8 characters. If true throw an error. elif len(name) > 8: msg = messagebox.showwarning(title='Name is too long.', \ message='Names must be 1 - 8 charcters in length.') # This is just to clear the form self.form.destroy() self.register() # Every thing ok go to the game else: # Setup player instances self.player = Player() self.player.player_name = name.strip().title() self.computer = Player() self.computer.player_name = 'Computer' # Pull the root window back up, destroy the form window, and initiate the game board self.parent.deiconify() self.form.destroy() self.board() # This function get the percentages of wins. def get_percentage(self, num1, num2, num3): try: total = num1 / (num1 + num2 + num3) return format(total, '.0%') except ZeroDivisionError: return format(0, '.0%') # Defines the game play def play(self, player_choice): # Player choices options = ['rock', 'paper', 'scissors'] # declare empty variable for later use msg = '' # Get the computers choice computer_choice = rnd.choice(options) # Get the players choice player_choice = player_choice # Do the comparison and get the winner. Display messages and update the win/losses if player_choice == 'rock' and computer_choice == 'scissors': self.player.player_wins += 1 self.players_wins['text'] = f'{self.player.player_wins} / {self.get_percentage(self.player.player_wins, self.player.player_loss, self.player.player_ties)}' self.msgbox['text'] = f'Status: {self.player.player_name.title()} wins! Rock Crushes Scissors.' self.computer.player_loss += 1 self.computers_loss['text'] = f'{self.computer.player_loss} / {self.get_percentage(self.computer.player_loss, self.computer.player_wins, self.computer.player_ties)}' print('player wins') elif player_choice == 'paper' and computer_choice == 'rock': self.player.player_wins += 1 self.players_wins['text'] = f'{self.player.player_wins} / {self.get_percentage(self.player.player_wins, self.player.player_loss, self.player.player_ties)}' self.msgbox['text'] = f'Status: {self.player.player_name.title()} wins! Paper Covers Rock.' self.computer.player_loss += 1 self.computers_loss['text'] = f'{self.computer.player_loss} / {self.get_percentage(self.computer.player_loss, self.computer.player_wins, self.computer.player_ties)}' print('player wins') elif player_choice == 'scissors' and computer_choice == 'paper': self.player.player_wins += 1 self.players_wins['text'] = f'{self.player.player_wins} / {self.get_percentage(self.player.player_wins, self.player.player_loss, self.player.player_ties)}' self.msgbox['text'] = f'Status: {self.player.player_name.title()} wins! Scissors Cut Paper.' self.computer.player_loss += 1 self.computers_loss['text'] = f'{self.computer.player_loss} / {self.get_percentage(self.computer.player_loss, self.computer.player_wins, self.computer.player_ties)}' print('player wins') elif computer_choice == 'rock' and player_choice == 'scissors': self.msgbox['text'] = f'Status: Computer wins! Rock crushes Scissors' self.computer.player_wins += 1 self.computers_wins['text'] = f'{self.computer.player_wins} / {self.get_percentage(self.computer.player_wins, self.computer.player_loss, self.computer.player_ties)}' self.player.player_loss += 1 self.players_loss['text'] = f'{self.player.player_loss} / {self.get_percentage(self.player.player_loss, self.player.player_wins, self.player.player_ties)}' elif computer_choice == 'paper' and player_choice == 'rock': self.msgbox['text'] = f'Status: Computer wins! Paper Covers Rock' self.computer.player_wins += 1 self.computers_wins['text'] = f'{self.computer.player_wins} / {self.get_percentage(self.computer.player_wins, self.computer.player_loss, self.computer.player_ties)}' self.player.player_loss += 1 self.players_loss['text'] = f'{self.player.player_loss} / {self.get_percentage(self.player.player_loss, self.player.player_wins, self.player.player_ties)}' elif computer_choice == 'scissors' and player_choice == 'paper': self.msgbox['text'] = f'Status: Computer wins! Scissors Cuts Paper.' self.computer.player_wins += 1 self.computers_wins['text'] = f'{self.computer.player_wins} / {self.get_percentage(self.computer.player_wins, self.computer.player_loss, self.computer.player_ties)}' self.player.player_loss += 1 self.players_loss['text'] = f'{self.player.player_loss} / {self.get_percentage(self.player.player_loss, self.player.player_wins, self.player.player_ties)}' else: self.computer.player_ties += 1 self.player.player_ties += 1 self.msgbox['text'] = f'Status: {self.player.player_name.title()} and Computer have tied. No winner.' print('tie game') # Keep track of played games self.player.games_played += 1 self.played_games['text'] = f'Games Played: ( {self.player.games_played} )' # Define the game window # This sets up all the frames and widget for the game window def board(self): try: mainframe = tk.Frame(self.parent) mainframe.grid(column=0, row=0, sticky='new') headerframe = tk.Frame(mainframe) headerframe['padx'] = 8 headerframe['pady'] = 5 headerframe['relief'] = 'ridge' headerframe['borderwidth'] = 2 headerframe.grid(column=0, row=0) header = tk.Label(headerframe, anchor='n') header['text'] = 'Rock Paper Scissors' header['font'] = 'serif 18 bold' header['fg'] = 'indianred' header['relief'] = 'ridge' header['padx'] = 2 header['pady'] = 2 header['width'] = 21 header.grid(column=0, row=0, ipady=3, ipadx=8) dataframe = tk.Frame(mainframe) dataframe['padx'] = 2 dataframe['pady'] = 2 dataframe['relief'] = 'ridge' dataframe['borderwidth'] = 2 dataframe['width'] = 21 dataframe.grid(column=0, row=1, sticky='new') data_header_player = tk.Label(dataframe, anchor='w') data_header_player['text'] = 'Player Name' data_header_player['font'] = 'serif 10 bold' data_header_player['fg'] = 'navy' data_header_player['relief'] = 'ridge' data_header_player['padx'] = 7 data_header_player['pady'] = 0 data_header_player['borderwidth'] = 1 data_header_player['width'] = 11 data_header_player.grid(column=0, row=0, ipady=3, ipadx=8) data_header_wins = tk.Label(dataframe, anchor='w') data_header_wins['text'] = 'Wins / %' data_header_wins['font'] = 'serif 10 bold' data_header_wins['fg'] = 'navy' data_header_wins['relief'] = 'ridge' data_header_wins['padx'] = 7 data_header_wins['pady'] = 0 data_header_wins['borderwidth'] = 1 data_header_wins['width'] = 11 data_header_wins.grid(column=1, row=0, ipady=3, ipadx=8, sticky='nw') data_header_loss = tk.Label(dataframe, anchor='w') data_header_loss['text'] = 'Loose / %' data_header_loss['font'] = 'serif 10 bold' data_header_loss['fg'] = 'navy' data_header_loss['relief'] = 'ridge' data_header_loss['padx'] = 7 data_header_loss['pady'] = 0 data_header_loss['borderwidth'] = 1 data_header_loss['width'] = 11 data_header_loss.grid(column=2, row=0, ipady=3, ipadx=8, sticky='nw') computers = tk.Label(dataframe, anchor='w') computers['text'] = self.computer.player_name computers['font'] = 'serif 8 bold' computers['fg'] = 'purple' computers['relief'] = 'ridge' computers['padx'] = 7 computers['pady'] = 1 computers['borderwidth'] = 1 computers.grid(column=0, row=1, ipady=3, ipadx=8, sticky='new') self.computers_wins = tk.Label(dataframe, anchor='w') self.computers_wins['text'] = f'0 / 0%' self.computers_wins['font'] = 'sans 9 normal' self.computers_wins['fg'] = 'purple' self.computers_wins['relief'] = 'ridge' self.computers_wins['padx'] = 7 self.computers_wins['pady'] = 0 self.computers_wins['borderwidth'] = 1 self.computers_wins.grid(column=1, row=1, ipady=3, ipadx=8, sticky='new') self.computers_loss = tk.Label(dataframe, anchor='w') self.computers_loss['text'] = f'0 / 0%' self.computers_loss['font'] = 'sans 9 normal' self.computers_loss['fg'] = 'purple' self.computers_loss['relief'] = 'ridge' self.computers_loss['padx'] = 7 self.computers_loss['pady'] = 0 self.computers_loss['borderwidth'] = 1 self.computers_loss.grid(column=2, row=1, ipady=3, ipadx=8, sticky='new') players = tk.Label(dataframe, anchor='w') players['text'] = self.player.player_name players['font'] = 'serif 8 bold' players['fg'] = 'blue' players['relief'] = 'ridge' players['padx'] = 7 players['pady'] = 0 players['borderwidth'] = 1 players.grid(column=0, row=2, ipady=3, ipadx=8, sticky='news') self.players_wins = tk.Label(dataframe, anchor='w') self.players_wins['text'] = f'0 / 0%' self.players_wins['font'] = 'sans 9 normal' self.players_wins['fg'] = 'blue' self.players_wins['relief'] = 'ridge' self.players_wins['padx'] = 7 self.players_wins['pady'] = 0 self.players_wins['borderwidth'] = 1 self.players_wins.grid(column=1, row=2, ipady=3, ipadx=8, sticky='news') self.players_loss = tk.Label(dataframe, anchor='w') self.players_loss['text'] = f'0 / 0%' self.players_loss['font'] = 'sans 9 normal' self.players_loss['fg'] = 'blue' self.players_loss['relief'] = 'ridge' self.players_loss['padx'] = 7 self.players_loss['pady'] = 0 self.players_loss['borderwidth'] = 1 self.players_loss.grid(column=2, row=2, ipady=3, ipadx=8, sticky='news') messageframe = tk.Frame(mainframe, borderwidth=3, relief='ridge') messageframe.grid(column=0, row=2, sticky='new') messageframe.grid_columnconfigure(0, weight=3) self.msgbox = tk.Label(messageframe, fg='brown', font='sans 9 normal', anchor='w', borderwidth=2, relief='ridge') self.msgbox['text'] ='Status:' self.msgbox.grid(column=0, row=0, padx=2, sticky='ew') self.played_games = tk.Label(messageframe, fg='brown', font='sans 9 normal', anchor='w', borderwidth=2, relief='ridge') self.played_games['text'] = f'Games Played: 0' self.played_games.grid(column=0, row=1, padx=2, sticky='ew') buttonsframe = tk.Frame(mainframe, borderwidth=3, relief='ridge', bg='grey86') buttonsframe.grid(column=0, row=3, sticky='new') rock_btn = tk.Button(buttonsframe, text='Rock', width=7, command=partial(self.play, 'rock')) rock_btn.grid(column=0, row=0, padx=2) paper_btn = tk.Button(buttonsframe, text='Paper', width=7, command=partial(self.play, 'paper')) paper_btn.grid(column=1, row=0, padx=2) scissors_btn = tk.Button(buttonsframe, text='Scissors', width=7, command=partial(self.play, 'scissors')) scissors_btn.grid(column=2, row=0, padx=2) spacer = tk.Frame(buttonsframe, width=74) spacer.grid(column=3, row=0) quit_btn = tk.Button(buttonsframe, text='Quit', fg='red', command=os.sys.exit) quit_btn.grid(column=4, row=0) # os.sys.exit() except ValueError as error: print(f'Error!: {error}') os.sys.exit() def main(): root = tk.Tk() root.title('Rock, Paper, and Scissors') Game(root) root.mainloop() if __name__ == '__main__': main()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts