how to get rid of duplicate lette in wordle - python

so I created this wordle version
one things that triggers me is for example the secret word is 'brawl'
and if I guessed hello for example the two L will be in yellow but the case is one only should be in yellow and the other in grey.
#class to verify that the player print word contain 5 letter and exist in english
#the main function to check if the player guessed the word if the letter in right position we colored it to green if the letter in the secret word but not in the right postion we color it to yellow else color it to grey
from collections import Counter
import sys
from termcolor import colored, cprint
from colorama import Fore, Back, Style
from colored import fg, bg, attr
import time
from random import choice
#class to verify that the player print word contain 5 letter and exist in english
class Player():
#staticmethod
def read_content(value):
with open('words.txt','r') as f:
contents=f.read()
if value.lower() in contents:
return True
else:
return False
def check_word(self):
valid_word=False
while not valid_word:
val=input()
if len(val)>5:
print("You have given a word that exceeds 5 letters")
continue
elif len(val)<5:
print("You have given a word less than 5 letters")
continue
elif len(val)==5 and not self.read_content(val):
print("you give a word with 5 letter that doesn't exist in dictionnary")
elif len(val)==5 and self.read_content(val):
return val
valid_word=True
#class of the game to read to select random word from a file txt and the rules of the game
class Wordle():
def __init__(self):
self.word=self.today_word()
#staticmethod
def today_word():
with open('words.txt','r') as f:
contents=f.readlines()
return choice(contents)
#staticmethod
def game_rules():
print("\tYou have five attempts to guess today word\n")
print(f"when the color is {colored('GREEN','green',attrs=['bold'])} that means the letter in the right postion\n"
+f"when the color is {colored('YELLOW','yellow',attrs=['bold'])} that means the letter is in the wrong position\n"
+f"when the color is {colored('GREY','grey',attrs=['bold'])} that means the letter doesn't exist in the word")
print("please print the word that's in your mind")
def play_wordle(game,player):
game.game_rules()
todays_word=game.word
attempt=1
while attempt<6:
player_word=player.check_word()
for index,letter in enumerate(player_word):
if player_word[index] == todays_word[index]:
print(colored(letter.upper(),'red','on_green',attrs=['bold']),end='')
print(' ',end='')
elif letter in todays_word:
print(colored(letter.upper(),'red','on_yellow',attrs=['bold']),end='')
print(' ',end='')
else:
print(colored(letter.upper(),'red','on_grey',attrs=['bold']),end='')
print(' ',end='')
time.sleep(0.8)
if player_word != todays_word:
attempt=attempt+1
elif player_word == todays_word:
print(f"\nCongratulation you've guessed the word of today:{game.word} ")
break
if player_word != todays_word:
print(f"\nSorry you lost today's word is :{todays_word.upper()}")

When importing Counter with
from collections import Counter
The for-loop to color the letters must be rewritten as two loops to process positional matches before the rest:
tw_count = Counter(todays_word)
greens = [False] * len(player_word)
for index,letter in enumerate(player_word):
if player_word[index] == todays_word[index]:
greens[index] = True
tw_count.subtract((letter,))
for index,letter in enumerate(player_word):
if greens[index]:
print(colored(letter.upper(),'red','on_green',attrs=['bold']),end='')
print(' ',end='')
elif tw_count[letter] > 0:
print(colored(letter.upper(),'red','on_yellow',attrs=['bold']),end='')
print(' ',end='')
tw_count.subtract((letter,))
else:
print(colored(letter.upper(),'red','on_grey',attrs=['bold']),end='')
print(' ',end='')
tw_count.subtract((letter,))
time.sleep(0.8)

Related

Python Urllib game of guessing words

I've been struggling as I wanted to try the hanged man game on python :
For those who don't know the game, you basically need to guess all the letters of a word (with a limited number of attempts previously announced).
What's difficult, is that I want each guessed letters to appear on the spare parts of the word to guess and the already used letters to be mentionned as well.
And as we've already decided the number of attempts allowed (let's say 10), I want to try to show the remaining attempts left !!
Here's what I've done already (the generate random words) but I'm stuck :
import urllib
response = urllib.request.urlopen('https://random-word-api.herokuapp.com/word?number=1')
word =response.read().decode('utf-8').strip('[\"]')
print(word)
Many thanks for your help.
This worked fine!
import requests
from typing import List
def get_random_word() -> str:
url:str = 'https://random-word-api.herokuapp.com/word?number=1'
response:requests.Response = requests.get(url)
if response.status_code == 200:
word = response.text.strip('[\"]')
return word
else:
print("Impossible to connect!")
def open_letters_in_hidden_word(word:str, hidden_word:str, letter:str) -> str:
hidden_word:List[str] = list(hidden_word)
for index, word_letter in enumerate(word):
if word_letter == letter:
hidden_word[index] = word_letter
hidden_word:str = ''.join(hidden_word)
return hidden_word
def start_game():
# Loading word from server
word:str = get_random_word()
attempts:int = 10
hidden_word:str = '-' * len(word)
while attempts:
print(f"Attempts left: {attempts}")
print(f"Word: {hidden_word}")
letter:str = input("Enter letter: ")
if letter in word:
hidden_word:str = open_letters_in_hidden_word(word, hidden_word, letter)
else:
print("Failed attempt!")
attempts -= 1
if not attempts:
print(f"You lose! Word: {word}")
return
if word == hidden_word:
print(f"You won! Word: {word}")
return
if __name__ == "__main__":
start_game()

Why won't my function activate when I call it?

import random
def main():
num_guesses = 4
instruction_file=open('instructions.txt', 'r')
list_of_words = ['apple', 'banana', 'watermelon', 'kiwi', 'pineapple', 'mango']
answer=random.choice(list_of_words)
puzzle=['_'] * len(answer)
def display_instructions(instruction_file):
file_contents=instruction_file.read()
instruction_file=instruction_file.close()
print(file_contents)
def get_guess(num_guesses):
print('The number of guesses remaining is ' + str(num_guesses)+ '.')
letter_input = input("Guess a letter ")
return letter_input
def update_puzzle_string(letter_input,puzzle,answer):
if get_guess(num_guesses) in answer:
for i,x in enumerate(answer):
if x is get_guess:
puzzle[i]=letter_input
return True
def display_puzzle_string(puzzle):
print('The current state of the puzzle is '+str(puzzle))
def is_word_found(puzzle,answer):
is_word_found=True
puzzle_string=print(''.join(puzzle))
if puzzle_string == answer:
return False
def play_game(answer,puzzle):
while True:
display_puzzle_string(puzzle)
get_guess(num_guesses)
update_puzzle_string(get_guess,puzzle,answer)
print(str(puzzle))
is_word_found(puzzle,answer)
display_instructions(instruction_file)
play_game(answer,puzzle)
main()
Sorry for formatting issues. The goal of this program is to collect a guess from a user then compare it to a randomly selected word from a list after doing so it updates a puzzle that has blanks where the letter belongs, if all letters of the word are guessed, user is told they are correct. User gets 4 guesses. It is basically hangman. When I execute this program it just prints the instructions, the initial puzzle state, requests a guess then keeps asking for guesses. I don't understand why this isn't working. I'll implement the number of guesses after I get help with this.
import random
def main():
num_guesses = 4
instruction_file=open('instructions.txt', 'r')
list_of_words = ['apple', 'banana', 'watermelon', 'kiwi', 'pineapple', 'mango']
answer=random.choice(list_of_words)
puzzle=['_'] * len(answer)
def display_instructions(instruction_file):
file_contents=instruction_file.read()
instruction_file=instruction_file.close()
print(file_contents)
def get_guess(num_guesses):
print('The number of guesses remaining is ' + str(num_guesses)+ '.')
letter_input = input("Guess a letter: ")
return letter_input
def update_puzzle_string(letter_input,puzzle,answer):
for i,x in enumerate(answer):
if x is letter_input:
puzzle[i]=letter_input
return
def display_puzzle_string(puzzle):
print('The current state of the puzzle is '+str(puzzle))
def is_word_found(puzzle,answer):
is_word_found=True
puzzle_string=print(''.join(puzzle))
if puzzle_string == answer:
return False
def play_game(answer,puzzle):
while True:
display_puzzle_string(puzzle) #display '_ _ _ _ _'
guess = get_guess(num_guesses)
update_puzzle_string(guess,puzzle,answer)
#print(str(puzzle)) #this statement is causing the repetitive puzzle prints
is_word_found(puzzle,answer)
display_instructions(instruction_file)
play_game(answer,puzzle)
main()
After fixing your formatting issues, the code now repeatedly asks for a guess and takes input. I think the issue mostly existed in formatting because I get no errors now. Also, did you have random imported before? Cheers
EDIT:
See changes to both update_puzzle_string() and play_game. You repeatedly called the get_guess function rather than using its initial return value.
EDIT 2: (refer to comments of this answer)
See update_puzzle_string() for the change regarding "multiple of the same letter in the answer"
So your error was not being able to stop the software?
You can use is_word_found inside play_game and then break if found.
Like this:
def play_game(answer,puzzle):
while True:
display_puzzle_string(puzzle)
get_guess(num_guesses)
update_puzzle_string(get_guess,puzzle,answer)
if is_word_found(puzzle, answer):
print("You won!")
break
print(str(puzzle))
Break will stop while True infinite loop

The code will not run nor will it show an error message

The following code will not run nor will it show an error message. Please help. Also, how would I add a function to display only the output of this code?
def main():
s= ""
phrase=""
programdescription(s)
userinput(phrase)
#This function displays the program description
def programdescription(s):
s = print("This program determines if a word, phrase, or sequence can be read the same backward as forward.")
#This function requests user input for analysis
def userinput(phrase):
phrase = input("Enter a word or phrase: ")
def s_phrase(phrase):
phrase = phrase.upper()
strippedPhrase = ""
for char in phrase:
if (48 <= ord(char) <= 57) or (65 <= ord(char) <= 90):
strippedPhrase += char
flag = True
n = len(strippedPhrase)
for j in range(int(n / 2)):
if strippedPhrase[j] != strippedPhrase[n - j - 1]:
flag = False
break
if flag:
print(phrase, "is a palindrome.")
else:
print(phrase, "is not a palindrome.")
main()
Ok, problem 1 is you never call s_phrase.
Problemo 2 is that the phrase variable can't be seen by s_phrase.
Problem numero C is that your indentation is messed up.
Issue 4 is more the fact that this seems like a very 'C' way of tackling the challenge. Borrowing from Spade, here is a more succinct way of doing it that is formatted to your original program.
def main():
s= ""
phrase=""
programdescription(s)
s_phrase(phrase)
#This function displays the program description
def programdescription(s):
s = print("This program determines if a word, phrase, or sequence can be read the same backward as forward.")
#This function requests user input for analysis
def s_phrase(phrase):
phrase = input("Enter a word or phrase: ")
phrase = phrase.upper()
r_phrase = phrase[::-1]
print(r_phrase)
if phrase == r_phrase:
print(phrase, "is a palindrome.")
else:
print(phrase, "is not a palindrome.")
main()

infinite loop in Hangman game in Python

I am trying to build a simple Hangman game, but the following program is creating an infinite loop when the letter entered by the user is not part of the word to guess (it's printing "*" indefinitely). What is missing here? Any advice would be appreciated.
import re
import random
folder = open("datas.txt","r")
data = folder.read()
word_list = re.sub("[^\w]"," ", data).split()
chosen_word = random.choice(word_list)
letter_player = input('enter a letter pls:\n')
continue_game = False
masked_word = []
for letter in chosen_word:
masked_word.append("*")
found_letters = []
def guess_letter():
for letter in range(0,len(chosen_word)):
if letter_player == chosen_word[letter]:
found_letters.append(letter_player)
masked_word[letter] = letter_player
else:
masked_word[letter] = '*'
print(masked_word[letter])
return found_letters
str_found_letters = ''.join(found_letters)
print(str_found_letters)
if(str_found_letters != chosen_word):
continue_game = True
while continue_game:
guess_letter()
As there are others answering, why not hand out another try, from where the OP could continue? So here another version fixing also the overwrite error of previous found letters in subsequent iterations.Note also, that the append of letters found in a list may be what one wants, or maybe not, as the o in foo would be appended twice.
# Python 3/2, imports and a literal:
from __future__ import print_function
import re
import random
MASK_CHAR = '*'
# Read words from file and select randomly:
def read_game_data(source="datas.txt"):
"""Randomly select a word from source data."""
with open(source, "r") as f_data:
return random.choice(re.sub("[^\w]", " ", f_data.read()).split())
# Build sequences (here lists) of letters that constitute a word or "mask"
def build_word_seq(a_word, a_mask=None):
return [letter if not a_mask else a_mask for letter in a_word]
# the core evaluation function (previously named guess_letter)
def evaluate_letter(chosen_word, masked_word, letter_player, found=None):
if found is None:
found = set()
for pos in range(len(chosen_word)):
if letter_player == chosen_word[pos]:
found.add(letter_player)
masked_word[pos] = letter_player
return masked_word, found
# The function that replaces the continue_game variable:
def not_ready(chosen_word, masked_word):
"""Evaluate."""
return True if masked_word != chosen_word else False
# Put the business in a main function, minimize globals:
def main():
"""Do the game."""
chosen_word = build_word_seq(read_game_data())
mask = build_word_seq(chosen_word, a_mask=MASK_CHAR)
found_letters = set()
while not_ready(chosen_word, mask):
letter_player = input('enter a letter pls:\n')
mask, found_letters = evaluate_letter(
chosen_word, mask, letter_player, found_letters)
print(''.join(mask))
if found_letters:
print("LettersFound: %s" % (sorted(found_letters),))
if __name__ == '__main__':
main()
A typical run based on a datas.txt file with:
foo bar baz
yes
no
yields e.g:
$ python3 hangman_again_inf_loop.py
enter a letter pls:
f
***
enter a letter pls:
y
***
enter a letter pls:
b
b**
LettersFound: ['b']
enter a letter pls:
a
ba*
LettersFound: ['a', 'b']
enter a letter pls:
r
bar
LettersFound: ['a', 'b', 'r']
The loop again may be infinite (if you do not guess right ;-)
For a hangman game, there should be some equivalent counting logic, where the guessing competes against a line by line drawn hangman ...
Above code still needs replacement of input() by raw_input() when python v2 is being used ... but the OP used print() without future import, thus it is plausible, a Python v3 solution is good nuff.
Happy hacking!
So, the biggest issue was the scope of the continue_game variable. Since it was declared outside of the function. "while continue_game" always evaluates the same.
To fix, add global continue_game in the method definition.
below is code that will break out of the loop. to test I created a datas.txt file with one word and with the current logic, you have to type the word in that order for the str_found_letters != chosen_word to hit the else condition
import re
import random
folder = open("datas.txt","r")
data = folder.read()
word_list = re.sub("[^\w]"," ", data).split()
chosen_word = random.choice(word_list)
found_letters = []
continue_game = True
masked_word = []
for letter in chosen_word:
masked_word.append("*")
def guess_letter():
global continue_game, chosen_word, found_letters, masked_word
letter_player = raw_input('enter a letter pls: ')
for letter in range(0,len(chosen_word)):
if letter_player == chosen_word[letter]:
found_letters.append(letter_player)
masked_word[letter] = letter_player
else:
masked_word[letter] = '*'
print(masked_word[letter])
str_found_letters = ''.join(found_letters)
print(str_found_letters)
if(str_found_letters != chosen_word):
continue_game = True
else:
continue_game = False
while continue_game:
guess_letter()

How can you hide letters in a word with an asterisk?

I am currently working on a hangman project. I am having problems with hiding characters in words with asterisks - like, "word" would be ****, then when the player makes a guess and it's correct, the letter would appear where it should be, instead of the asterisk, like if you guessed 'o', *o**. How can I do this?
This is my current code.
import random
start = 1
class hangman():
def __init__(self):
self.__word = word
self.__incorrectg = none
word = random.choice(open(input("please type the file you wish to open ")).readlines())
print (word)
lettercount = len([ltr for ltr in word if ltr.isalpha()])
print (lettercount)
If you stored the players guesses in a list for instance:
used_letters = [] # and append guesses to this, both right and wrong
so as soon as the user inputs a guess, you append it to used_letters.
with open(filepath) as f: # this might be a better way to open the file
word = random.choice(f.readlines()) # after this statement the file is auto closed, and frees up the memory
and you have the actual word stored as a list as in:
word = list(word) #made into a list of the letters in the word
then you could do something like:
guessed_string = ''.join(letter if letter in used_letters else '*' for letter in the_word)
EDIT:
#prints out the starred string. i.e. unguessed letters are '*' and guessed letters that appear in the word appear as normal letters.
print guessed_string
let me know if this works for you.
Example:
if word = 'arbitrary'
word = list(word) gives:
['a','r','b','i','t','r','a','r','y']
if the user has so far guessed:
used_letters = ['a', 'b', 'e', 'r']
then
guessed_string = ''.join(letter if letter in used_letters else '*' for letter in word)
print guessed_string
will give:
'arb**rar*'
value="C9T1573518"
new_value=value[0:3]
new_value+="".join(value[l].replace(value[l],"*") for l in range(3,len(value),1))
print(
new_value
)
#!/usr/bin
def password(word):
class __password:
def __repr__(self):
return "*" * len(word)
return __password()
word = password("Mypassword123")
print word
Took a while but I was finally able to get it:
#!/usr/bin
def password(word):
external_repr = set()
class __password:
def __repr__(self):
return ''.join(word[i] if word[i] in external_repr else '*' for i in xrange(len(word)))
def __eq__(self, somestring):
return word == somestring
def guess(self, letter):
external_repr.add(letter[0])
def encrypt(self):
return "*" * len(word)
return __password()
word = password("Mypassword123")
if word == "Mypassword123": print "Passwords match!"
print "The encrypted password is", word.encrypt()
word.guess('s')
print "After your guess, the word is now", word

Categories