Sep-11-2022, 08:34 AM
(This post was last modified: Sep-12-2022, 07:42 PM by menator01.
Edit Reason: Updated code to use a words list from internet instead of ocal file
)
hangman/word guessing game with tkinter
words.txt:
https://my-python.org/files/python/words.txt
words.txt:
https://my-python.org/files/python/words.txt
#! /usr/bin/env python3 import random as rnd import tkinter as tk from tkinter import messagebox import os import sys import requests class Stats: wins = 0 loss = 0 games = 0 tries = 0 remaining = 0 def __str__(self): return f'Stats: Wins: {Stats.wins} / Loss: {Stats.loss} / Games Played: {Stats.games} / Tries Left: {Stats.tries}' class Model: url = 'https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt' response = requests.get(url) words = response.text.split('\r\n') def __init__(self): self.wordlist = Model.words def random_word(self): word = self.wordlist.pop(rnd.randint(0, len(self.wordlist)-1)) return word def find(self, letter, word, letters): match = [i for i, x in enumerate(word) if x == letter] if match: for i in match: letters[i] = letter Stats.remaining -= 1 return ' '.join(letters) class View: def __init__(self, parent): self.parent = parent self.parent.columnconfigure(0, weight=1) self.parent.rowconfigure(0, weight=0) self.parent.rowconfigure(1, weight=0) self.parent.rowconfigure(2, weight=0) self.parent.rowconfigure(3, weight=1) # Setup the header header_box = tk.Frame(self.parent) header_box.grid(column=0, row=0, sticky='new', padx=5, pady=5) header_box.grid_columnconfigure(0, weight=3) header = tk.Label(header_box, text='Tkinter Word Game') header['font'] = (None, 28, 'bold') header.grid(column=0, row=0, sticky='new') # Setup stats row stats_box = tk.Frame(self.parent) stats_box['highlightbackground'] = 'black' stats_box['highlightcolor'] = 'black' stats_box['highlightthickness'] = 1 stats_box.grid(column=0, row=1, sticky='new', padx=5, pady=5) stats_box.grid_columnconfigure(0, weight=3) self.stats = tk.Label(stats_box, anchor='w') self.stats['font'] = (None, 10, 'bold') self.stats['text'] = Stats() self.stats.grid(column=0, row=0, sticky='new', padx=5, pady=5) word_box = tk.Frame(self.parent) word_box['highlightbackground'] = 'black' word_box['highlightcolor'] = 'black' word_box['highlightthickness'] = 1 word_box.grid(column=0, row=2, sticky='new', padx=5, pady=5) word_box.grid_columnconfigure(0, weight=0) word_box.grid_columnconfigure(1, weight=3) label = tk.Label(word_box, text='Random Word: ', anchor='w') label['font'] = (None, 10, 'bold') label.grid(column=0, row=0, sticky='new', padx=2.5, pady=5) self.word = tk.Label(word_box, anchor='w') self.word['font'] = (None, 10, 'normal') self.word.grid(column=1, row=0, sticky='new', padx=(2.5,5), pady=5) # Letter/Button row btn_box = tk.Frame(self.parent) btn_box['highlightbackground'] = 'black' btn_box['highlightcolor'] = 'black' btn_box['highlightthickness'] = 1 btn_box.grid(column=0, row=3, sticky='new', padx=5, pady=5) btn_box.grid_columnconfigure(0, weight=1, uniform='btn') btn_box.grid_columnconfigure(2, weight=1, uniform='btn') btn_box.grid_columnconfigure(3, weight=1, uniform='btn') btn_box.grid_columnconfigure(1, weight=3) self.letter_btn = tk.Button(btn_box, text='Submit Letter', bg='powderblue') self.letter_btn['cursor'] = 'hand2' self.letter_btn['activebackground'] = 'skyblue' self.letter_btn['activeforeground'] = 'blue' self.letter_btn.grid(column=0, row=0, sticky='new', pady=5, padx=(5,2.5)) self.entry = tk.Entry(btn_box) self.entry['font'] = (None, 14, 'normal') self.entry.grid(column=1, row=0, sticky='new', pady=5, padx=2.5) self.entry.focus() self.btn_new = tk.Button(btn_box, text='New Word', bg='powderblue') self.btn_new['cursor'] = 'hand2' self.btn_new['activebackground'] = 'skyblue' self.btn_new['activeforeground'] = 'blue' self.btn_new.grid(column=2, row=0, sticky='new', pady=5, padx=2.5) self.exit_btn = tk.Button(btn_box, text='Quit', bg='tomato') self.exit_btn['activebackground'] = 'red' self.exit_btn['activeforeground'] = 'white' self.exit_btn['cursor'] = 'hand2' self.exit_btn.grid(column=3, row=0, sticky='new', pady=5, padx=(2.5, 5)) class Controller: def __init__(self, view, model): self.view = view self.model = model self.word = self.model.random_word() self.letters = ['-']*len(self.word) self.view.word['text'] = self.letters Stats.tries = len(self.word) - round(len(self.word)/2) Stats.remaining = len(self.word) self.view.stats['text'] = Stats() # Buttons self.view.letter_btn['command'] = lambda: self.find(self.view.entry.get()) self.view.btn_new['command'] = self.new self.view.exit_btn['command'] = self.view.parent.destroy # Button Binds self.view.parent.bind('<Return>', lambda letter: self.find(letter=self.view.entry.get())) self.view.parent.bind('<KP_Enter>', lambda letter: self.find(letter=self.view.entry.get())) def new(self): Stats.alist = [] self.view.letter_btn['state'] = 'normal' self.view.entry['state'] = 'normal' self.word = self.model.random_word() self.letters = ['-']*len(self.word) self.view.word['text'] = self.letters Stats.tries = len(self.word) - round(len(self.word)/2) Stats.remaining = len(self.word) self.view.stats['text'] = Stats() self.view.entry.delete(0, tk.END) def find(self, letter): done = False if not letter or letter.isdigit(): messagebox.showerror('Error', 'You must enter a letter') self.view.entry.delete(0, tk.END) Stats.tries += 1 if len(letter) > 1: messagebox.showerror('Error!', 'Only one character can be entered at a time.') self.view.entry.delete(0, tk.END) Stats.tries += 1 letter = letter.lower() found = self.model.find(letter, self.word, self.letters) if letter not in found: Stats.tries -= 1 self.view.entry.delete(0, 'end') if Stats.tries == 0: self.view.letter_btn['state'] = 'disabled' self.view.entry['state'] = 'disabled' Stats.games += 1 done = True self.game_over() else: self.view.entry.delete(0, 'end') if Stats.remaining == 0: self.view.letter_btn['state'] = 'disabled' self.view.entry['state'] = 'disabled' Stats.games += 1 self.game_win() self.view.stats['text'] = Stats() if done: self.view.word['text'] = self.word else: self.view.word['text'] = found def game_over(self): messagebox.showinfo('Game Over!', 'You are out of guesses.') Stats.loss += 1 def game_win(self): messagebox.showinfo('Congradulations!', 'You got the word!') Stats.wins += 1 if __name__ == '__main__': root = tk.Tk() root.title('Word Guessing Game') root.geometry('+300+300') controller = Controller(View(root), Model()) root.mainloop()
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