Hangman Player Vs Computer In Python

                              Hangman Player Vs Computer In Python

The Hangman Player Vs Computer is a simple game project developed using python. This game is about guessing letters (A-Z) to form the words. Here, both the computer and human player play the game as opponents. If the player guesses the right letter that is within the word, the letter appears at its correct position. The user has to guess the correct word until a man is hung, then the game is over. 

About the Game

You can use CLI mode to run the game in the console. Here, all the playing methods are the same, all you (users) have to do is to guess the correct letters to form the correct word before the man is hung. If you cannot guess the correct word, you will not be able to see that word again. Also, to start the new game, you can enter yes or y.

Project code

from dataclasses import dataclass

from english_words import word

from random import choice, choices, randint

from json import dump, load

from operator import itemgetter

from datetime import datetime


@dataclass()

class Hangman:

    name = "Player"

    select_difficulty = "Easy"

    lives = 10

    score = 0

    diff_multi = 1

    win_bonus = 100

    secret_word = ""

    letter = ""

    guesses1 = []

    guesses2 = []

    completed = False

    my_turn = False

    comp_alphabet = ['z', 'x', 'c', 'v', 'b', 'n', 'm', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'l', 'q', 'w', 'e', 'r',

                     't', 'y', 'u', 'i', 'o', 'p']


    def hangman_menu(self):

        hangman_text = "HANGMAN vs Computer"

        hangman_text_centered = hangman_text.center(120, "-")

        print(hangman_text_centered)

        print(f"Welcome to Hangman vs Computer!")

        while True:

            try:

                print(f"currently playing as: {self.name}.\nthe difficulty is: {self.select_difficulty}.\n"

                      f"use integers to make your selection."

                      )

                start_game = int(input("\nchoose an option:\n1.start game\n2.change player name\n"

                                       "3.choose difficulty\n4.high scores\n5.quit\n"

                                       )

                                 )

                if start_game == 1:

                    self.hangman_game(computer1)

                elif start_game == 2:

                    self.name = input("write your name:\n")

                elif start_game == 3:

                    self.choose_difficulty()

                elif start_game == 4:

                    self.display_high_score()

                elif start_game == 5:

                    quit()


            except ValueError:

                print("please use integers.")


    def hangman_game(self, computer):

        print(f"{self.name} vs {computer.name}!")

        print("new game begins!\n")


        # refresh the player values from previous run


        self.set_player_values()

        computer.set_player_values()


        # create the secret word


        self.create_secret_word(computer1)


        # deciding turn order


        turn_order = randint(1, 2)

        if turn_order == 1:

            self.my_turn = True

            print(f"{self.name} goes first!")

        elif turn_order == 2:

            computer.my_turn = True

            print(f"{computer.name} goes first!")


            # -----------hangman game-----------


            # this next while loop is essentially the entire game, as it will keep looping until a end game condition

            # has been satisfied. It contains both the hangman text display as well as the guess inputs of both players.


            # display the secret word


        while not self.completed or not computer.completed:


            print(f"{computer.name}'s word: ", end="")

            computer_check_complete = ""

            for computer.letter in computer.secret_word:

                if computer.letter.lower() in computer.guesses2:

                    print(f"{computer.letter.upper()}", end=" ")

                    computer_check_complete += computer.letter

                else:

                    print(f"_", end=" ")


            print()


            print(f"{self.name}'s word: ", end="")

            player_check_complete = ""

            for self.letter in self.secret_word:

                if self.letter.lower() in self.guesses1:

                    print(f"{self.letter.upper()}", end=" ")

                    player_check_complete += self.letter

                else:

                    print(f"_", end=" ")


            print()


            if player_check_complete == self.secret_word:

                break

            if computer_check_complete == computer.secret_word:

                break


            # -------------play turns-------------


            # player turn


            if self.my_turn is True:

                guess_input = None

                acceptable_answer = False

                while acceptable_answer is False:

                    guess_input = input(

                        f"type 'letters' to see what letters were attempted so far.\n"

                        f"type 'quit' to quit game. attempts left: {self.lives}.\n"

                        f"guess a letter:\n"

                        ).lower()


                    if guess_input.isalpha():

                        acceptable_answer = True


                if guess_input not in self.guesses1 and guess_input != "letters":

                    print(f"{self.name} guessed the letter: {guess_input[0]}")

                    self.guesses1.append(guess_input[0])

                    self.my_turn = False

                    computer.my_turn = True

                if guess_input == "letters":

                    print(f"letters used so far: {self.guesses1}")

                if guess_input == "quit":

                    exit()

                elif guess_input[0] not in self.secret_word and guess_input != "letters":

                    self.lives -= 1

                    if self.lives == 0:

                        break

                    else:

                        self.my_turn = False

                        computer.my_turn = True


            # computer turn


            if computer.my_turn is True:


                comp_guess = computer.computer_makes_choice()

                while comp_guess in computer.guesses2:

                    comp_guess = computer.computer_makes_choice()

                print(f"{computer.name} guesses the letter: {comp_guess}")

                if comp_guess not in computer.guesses2:

                    computer.guesses2.append(comp_guess)

                    self.my_turn = True

                    computer.my_turn = False

                elif comp_guess not in computer.secret_word:

                    self.my_turn = True

                    computer.my_turn = False


            self.completed = True

            for letter in self.secret_word:

                self.score += 5

                if letter.lower() not in self.guesses1:

                    self.score -= 5

                    self.completed = False

            computer.completed = True

            for letter in computer.secret_word:

                computer.score += 5

                if letter.lower() not in computer.guesses2:

                    computer.score -= 5

                    computer.completed = False


        print()


        self.calculate_score(computer1)


        # calculate score and end message


    def create_secret_word(self, other):


        if self.select_difficulty == "Easy":

            self.secret_word = choice(word).lower()

            other.secret_word = choice(word).lower()

            while len(self.secret_word) >= 5:

                self.secret_word = choice(word).lower()

                other.secret_word = choice(word).lower()

        if self.select_difficulty == "Normal":

            self.secret_word = choice(word).lower()

            other.secret_word = choice(word).lower()

            while len(self.secret_word) < 5:

                self.secret_word = choice(word).lower()

                other.secret_word = choice(word).lower()

        if self.select_difficulty == "Hard":

            self.secret_word = choice(word).lower()

            other.secret_word = choice(word).lower()

            while len(self.secret_word) < 7:

                self.secret_word = choice(word).lower()

                other.secret_word = choice(word).lower()

        if self.select_difficulty == "Test":

            self.secret_word = choice(word).lower()

            other.secret_word = choice(word).lower()

            while len(self.secret_word) < 7:

                self.secret_word = choice(word).lower()

                other.secret_word = choice(word).lower()


    def calculate_score(self, other):


        if self.completed is False and other.completed is True:

            self.score = (self.lives * 10 + self.score) * self.diff_multi

            print(f"Game Over, {self.name}! the word was '{self.secret_word.upper()}'!\n"

                  f"total score: {self.score}\non difficulty: {self.select_difficulty}"

                  )


        if self.completed is True and other.completed is False:

            self.score = (self.lives * 10 + self.score) * self.diff_multi + self.win_bonus

            print(f"Congratulations, {self.name}, you completed the word '{self.secret_word.upper()}'!\n"

                  f"total score: {self.score}\non difficulty: {self.select_difficulty}"

                  )


        if self.completed is False and other.completed is False:

            self.score = (self.lives * 10 + self.score) * self.diff_multi + self.win_bonus

            print(f"Game ends! {self.name}, your word was '{self.secret_word.upper()}'!\n"

                  f"total score: {self.score}\non difficulty: {self.select_difficulty}"

                  )


        if other.completed is False:

            other.score = (other.lives * 10 + other.score) * self.diff_multi


        if other.completed is True:

            other.score = (other.lives * 10 + other.score) * self.diff_multi + self.win_bonus


        print(f"{self.name} : {self.score}\n"

              f"{other.name} : {other.score}\n"

              )


        if self.score > other.score:

            print(f"{self.name} wins!")

        if self.score < other.score:

            print(f"{other.name} wins!")

        if self.score == other.score:

            print("it's a tie!")


        self.update_high_scores()


    def computer_makes_choice(self):


        comp_pick = choices(self.comp_alphabet, weights=(0.27, 0.29, 1.00, 4.53, 1.00, 2.07, 6.65, 3.01, 8.49,

                                                         5.73, 1.81, 2.47, 3.00, 0.19, 5.48, 0.19, 1.28,

                                                         11.16, 7.58, 6.95, 1.77, 3.63, 7.54, 7.16, 3.16), k=1)

        comp_pick = "".join(comp_pick)

        return comp_pick


    def update_high_scores(self):

        """

        Attempts to load the highscore.txt and append the new score, datetime included.

        :return:

        """


        try:

            with open('highscore.txt', 'r') as f:

                highscores = load(f)

                now = datetime.now()

                now_string = now.strftime("%d/%m/%Y %H:%M:%S")


                highscores.append((self.name, self.score, self.select_difficulty, now_string))

                highscores = sorted(highscores, key=itemgetter(1), reverse=True)[:10]


                with open('highscore.txt', 'w') as f1:

                    dump(highscores, f1)


        except FileNotFoundError:

            print("\ncreating high score...")

            highscores = [["Bubbleboy", 500], ["Salami", 600], ["Riskitforabiscuit", 700],

                          ["Champ", 800], ["MasterNitroBlaster", 900], ["Omegasimp", 1000]]


            now = datetime.now()

            now_string = now.strftime("%d/%m/%Y %H:%M:%S")


            highscores.append((self.name, self.score, self.select_difficulty, now_string))

            highscores = sorted(highscores, key=itemgetter(1), reverse=True)[:10]


            with open('highscore.txt', 'w') as f:

                dump(highscores, f)


        input("\npress Enter to continue...\n")


    def choose_difficulty(self):


        while True:

            try:

                self.select_difficulty = int(input("choose difficulty:\n1.Easy (10 lives, small words)"

                                                   "\n2.Normal (7 lives, average size words)"

                                                   "\n3.Hard (5 lives, large size words only)\n"))

                if self.select_difficulty == 1:

                    self.select_difficulty = "Easy"

                elif self.select_difficulty == 2:

                    self.select_difficulty = "Normal"

                elif self.select_difficulty == 3:

                    self.select_difficulty = "Hard"

                elif self.select_difficulty == 9:

                    self.select_difficulty = "Test"


            except ValueError:

                print("please use an integer.")


            break


        self.set_player_values()


    def set_player_values(self):

        if self.select_difficulty == "Easy":

            self.lives = 10

            self.score = 0

            self.diff_multi = 0.5

            self.win_bonus = 100


        elif self.select_difficulty == "Normal":

            self.lives = 7

            self.score = 0

            self.diff_multi = 1

            self.win_bonus = 200


        elif self.select_difficulty == "Hard":

            self.lives = 5

            self.score = 0

            self.diff_multi = 2

            self.win_bonus = 300


        elif self.select_difficulty == "Test":

            self.lives = 99999

            self.score = -99999

            self.diff_multi = -99999

            self.win_bonus = -99999


        self.guesses1 = []

        self.guesses2 = []

        self.completed = False

        self.my_turn = False


    def display_high_score(self):

        """

        Attempts to read the highscore.txt file for printing.

        If unable to find, triggers create_high_score() method.

        :return:

        """

        high_score_title = "HIGH SCORE:"

        print(f"{high_score_title:>50}\n")

        try:

            with open('highscore.txt', 'r') as readf:

                highscores = load(readf)

                for index, sco in enumerate(highscores):

                    string_sco = f"{index + 1}.{str(sco[0])} : {str(sco[1]).zfill(4)}"

                    print(f"{string_sco:>50}")

                    if index == 10:

                        break


            input("\nPress Enter to continue...")


        except FileNotFoundError:

            print("file not found. creating...\n")

            self.create_high_score()


    @staticmethod

    def create_high_score():

        """

        Upon not finding a highscore.txt file, this method will create it.

        :return:

        """


        try:

            highscores = [["Bubbleboy", 500], ["Salami", 600], ["Riskitforabiscuit", 700],

                          ["ghostwiththemost", 800], ["MasterNitroBlaster", 900], ["OmegaSimp", 1000]]

            highscores = sorted(highscores, key=itemgetter(1), reverse=True)[:10]

            with open('highscore.txt', 'w') as writef:

                dump(highscores, writef)


            with open('highscore.txt', 'r') as readf:

                highscores = load(readf)

                for index, sco in enumerate(highscores):

                    string_sco = f"{index + 1}.{str(sco[0])} : {str(sco[1]).zfill(4)}"

                    print(f"{string_sco:>50}")

                    if index == 10:

                        break

        except PermissionError:

            print("you don't have permission to create this file!")

        except FileExistsError:

            print("file already exists.\n")


        print("created new high score file!")



player1 = Hangman()

computer1 = Hangman()

computer1.name = "Computer"


if __name__ == "__main__":

    while True:

        player1.hangman_menu()

Output

Welcome to Hangman vs Computer!

currently playing as: Player.

the difficulty is: Easy.

use integers to make your selection.


choose an option:

1.start game

2.change player name

3.choose difficulty

4.high scores

5.quit

1

Player vs Computer!

new game begins!


Computer goes first!

Computer's word: _ _ _ _ _ 

Player's word: _ _ _ _ 

Computer guesses the letter: l

Computer's word: _ _ _ _ _ 

Player's word: _ _ _ _ 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 10.

guess a letter:

s

Player guessed the letter: s

Computer guesses the letter: g

Computer's word: _ _ _ _ _ 

Player's word: _ _ _ S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 10.

guess a letter:

w

Player guessed the letter: w

Computer guesses the letter: r

Computer's word: _ _ _ _ _ 

Player's word: _ _ _ S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 9.

guess a letter:

m

Player guessed the letter: m

Computer guesses the letter: u

Computer's word: _ _ _ _ _ 

Player's word: _ _ _ S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 8.

guess a letter:

r

Player guessed the letter: r

Computer guesses the letter: e

Computer's word: _ _ _ _ _ 

Player's word: _ _ _ S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 7.

guess a letter:

t

Player guessed the letter: t

Computer guesses the letter: t

Computer's word: _ _ _ _ T 

Player's word: _ _ T S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 7.

guess a letter:

h

Player guessed the letter: h

Computer guesses the letter: o

Computer's word: _ O _ _ T 

Player's word: _ _ T S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 6.

guess a letter:

k

Player guessed the letter: k

Computer guesses the letter: a

Computer's word: _ O A _ T 

Player's word: _ _ T S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 5.

guess a letter:

a

Player guessed the letter: a

Computer guesses the letter: m

Computer's word: _ O A _ T 

Player's word: _ A T S 

type 'letters' to see what letters were attempted so far.

type 'quit' to quit game. attempts left: 5.

guess a letter:

c

Player guessed the letter: c

Computer guesses the letter: i

Computer's word: _ O A _ T 

Player's word: C A T S 


Congratulations, Player, you completed the word 'CATS'!

total score: 167.5

on difficulty: Easy

Player : 167.5

Computer : 80.0


Player wins!


press Enter to continue...

No comments

Powered by Blogger.