python loops, 2 player game - python

I'm working on finishing my first simple program in python, a 2 player (user vs computer AI) word/letter guessing game.
I've got the bulk of the code finished, but I'm trying to get my loops sorted out so that the game will properly alternate between the user and the AI. I want to make it so that the game alternates back and forth between user and AI turns, until the world has been fully revealed. At that point, the player to guess the most letters correctly wins a point. The computer moderator picks another word and starts again. The first player to five points wins the game.
I'm not sure where to start with this. I'm still quite new to python/coding in general and I have a difficult time understanding the order in which events occur. I know I need some kind of master loop that remains True as long as the word has yet to be fully revealed, but that's about it.
Also, any other suggestions as to how to optimize the code below or clean it up in anyway would be appreciated!
import random
#set initial values
player1points= 0
ai= 0
userCorrectLetters= ''
aiCorrectLetters=''
wrongLetters=''
wrongPlace= ''
correctLetters = ''
notInWord = ''
endGame = False
allLetters = set(list('abcdefghijklmnopqrstuvwxyz'))
alreadyGuessed = set()
userGuessPosition = 0
availLetters = allLetters.difference(alreadyGuessed)
#import wordlist, create mask
with open('wordlist.txt') as wordList:
secretWord = random.choice(wordList.readlines()).strip()
print (secretWord)
secretWordLength = len(secretWord)
def displayGame():
mask = '_' * len(secretWord)
for i in range (len(secretWord)):
if secretWord[i] in correctLetters:
mask = mask[:i] + secretWord[i] + mask [i+1:]
for letter in mask:
print (letter, end='')
print (' ')
print ('letters in word but not in correct location:', wrongPlace)
print ('letters not in word:', wrongLetters)
##asks the user for a guess, assigns input to variable
def getUserGuess(alreadyGuessed):
while True:
print ('enter your letter')
userGuess = input ()
userGuess= userGuess.lower()
if len(userGuess) != 1:
print ('please enter only one letter')
elif userGuess in alreadyGuessed:
print ('that letter has already been guessed. try again')
elif userGuess not in 'abcdefjhijklmnopqrstuvwxyz':
print ('only letters are acceptable guesses. try again.')
else:
return userGuess
def newGame():
print ('yay. that was great. do you want to play again? answer yes or no.')
return input().lower().startswith('y')
userTurn=True
while userTurn == True:
displayGame ()
print ('which character place would you like to guess. Enter number?')
userGuessPosition = int(input())
slice1 = userGuessPosition - 1
##player types in letter
guess = getUserGuess(wrongLetters + correctLetters)
if guess== (secretWord[slice1:userGuessPosition]):
correctLetters = correctLetters + guess
print ('you got it right! ')
displayGame()
break
elif guess in secretWord:
wrongPlace = wrongPlace + guess
print ('that letter is in the word, but not in that position')
displayGame()
break
else:
wrongLetters = wrongLetters + guess
print ('nope. that letter is not in the word')
displayGame()
break
print ("it's the computers turn")
aiTurn=True
while aiTurn == True:
aiGuessPosition = random.randint(1, secretWordLength)
print (aiGuessPosition)
aiGuess=random.sample(availLetters, 1)
print ('the computer has guessed', aiGuess, "in position", + aiGuessPosition)
if str(aiGuess) == (secretWord[slice1:userGuessPosition]):
correctLetters = correctLetters + guess
print ('this letter is correct ')
break
elif str(aiGuess) in secretWord:
aiCorrectLetters = aiCorrectLetters + guess
correctLetters = correctLetters + guess
print ('that letter is in the word, but not in that position')
break
else:
wrongLetters = wrongLetters + guess
print ('that letter is not in the word')
break
displayGame()
break

It looks like it will only do two turns and then exit?
What is happening is that it hits your first while loop, and starts to evaluate the code inside. It does some stuff, and then hits the break which breaks you out of the loop and execution resume after the end of your first loop. It then does the same thing with the second loop, hits the end of you program and exits.
I would suggest the following refactoring:
put all of the stuff you have under your while loops into two function user_play and computer_play
write a loop something like
this
usr_pts = 0
cmp_pts = 0
while (usr_pts < 5 and cmp_pts < 5):
solved_word = False
# set up word
user_turn = False
user_correct_guess = 0
ai_correct_guess = 0
while not solved_word:
user_turn = not user_turn
if user_turn:
guess = play_user(...)
else:
guess = computer_play(...)
# what ever accounting you need to do
is_guess_in_word = test_guess_in_word(guess, ...)
if is_guess_in_word:
if user_turn:
user_correct_guess += 1
else:
ai_correct_guess += 1
solved_word = sort_out_if_word_solved(...)
if user_correct_guess > ai_correct_guess:
usr_pts += 1
elif user_correct_guess < ai_correct_guess:
cmp_pts +=1
else:
# a tie
pass

Related

Why does my code ignore my if statement for my hangman game? (python)

I just had a question about the code that I wrote below. I was just wondering about the if statement that I wrote with the "if guess not in secret_word:". When I run it as it's currently written, the condition doesn't even run or appear. However, when I swap it with the for statement which I wrote above, it runs just fine. I'm a bit new to programming, and I was just wondering if anyone could help me out with this. Why does the order of conditions matter here?
'''
import random
from words import words
secret_word = random.choice(words)
secret_letters = list(secret_word)
blanks = " _ " * len(secret_word)
already_guessed = []
lives = 10
print(blanks)
def valid_guess(): # function to make sure the letter guessed is valid (ie, not previously guessed)
is_letter = True
lives = 10
while True:
guess = (input("\nGuess a letter:"))
if guess in already_guessed:
print("You have already guessed this letter")
elif len(guess) != 1:
print("Please guess a single letter:")
is_letter = False
elif guess not in "abcdefghijklmnopqrstuvwxyz":
print("Please guess a LETTER:")
is_letter = False
if is_letter:
already_guessed.append(guess)
for guess in secret_word:
if guess in already_guessed:
print(guess + " ", end = "")
else:
print(" - ", end = "")
if guess not in secret_word:
lives -= 1
print(f"You lost a life! You only have {lives}/10 left!")
while True:
valid_guess()
'''
You could try this:
if guess in secret_word:
if guess in already_guessed:
print(guess + " ", end = "")
else:
print(" - ", end = "")
elif guess not in secret_word:
lives -= 1
print(f"You lost a life! You only have {lives}/10 left!")

First condition of an if-block is getting skipped

I'm writing code with Python 2.7 that checks if a character is present in a input string but Python keeps skipping part of my if-statement.
Each time I run the code and enter a guess character value, the execution goes straight to the else statement and never executes the if(guess in PuzzleSetter) == True block at all.
What am I doing wrong?
PuzzleSetter = " "
List = []
def setPuzzle():
PuzzleSetter = raw_input("Puzzle setter set your word: ")
PuzzleSetter = PuzzleSetter.replace(" ", "")
print("Guessing player try guessing: "+PuzzleSetter.upper())
time.sleep(5)
print(chr(27) + "[2J")
List = [' __ ']*len(PuzzleSetter)
print("\n")
print(List)
while(True):
guess = raw_input("\nGuessing player make your guess: ")
if len(guess) != 1:
print("You are meant to enter a single letter")
continue
else:
guess = guess.upper()
print(guess)
if(guess in PuzzleSetter) == True:
finder = PuzzleSetter.find(guess)
print(PuzzleSetter+" contains "+str(PuzzleSetter.count(guess))+" "+guess+"'s")
for count in range(PuzzleSetter.count(guess)):
List[finder] = guess.upper()
finder = PuzzleSetter.find(guess, finder+1)
print(List)
if List.count("__") == 0:
print("Guessing player wins!")
break
else:
HangerMan()
enter += 1
if enter == 7:
print("Guessing player lost!")
print("\nPlayer two becomes the puzzle setter")
setPuzzle()
As I thought, you're leaving PuzzleSetter as input and not converting it to upper case like you are guess. If it contains any lower case letters they will never be found. Try this:
PuzzleSetter = raw_input("Puzzle setter set your word: ")
PuzzleSetter = PuzzleSetter.replace(" ", "")
PuzzleSetter = PuzzleSetter.upper()
print("Guessing player try guessing: "+PuzzleSetter)

Debugging a "guess the word " game

There is one small problem with my code , after I get all the letters correct, I had to enter another letter only it will show that I got it right. What is the problem?
import random
import string
import sys
def split(word):
return list(word)
alphabet = 'abcdefghijklmnopqrstuvwxyz'
list(alphabet)
words = ['hat','pop' ,'cut' , 'soup' , 'you' , 'me' , 'gay' , 'lol' ]
guess_word = []
wrong_letters_storage = []
secret_word = random.choice(words)
word_length = print("the length of the word is " + str(len(secret_word)))
correct_letters = split(secret_word)
def words():
for letter in secret_word:
guess_word.append("-")
return print("the words that you are guessing is " + str(guess_word))
def guessing():
while True:
c = 0
b = 7
while c <= 7:
print("")
hide = ""
print("you have " + str(b) + " guess left")
print("Wrong letters : " + str(wrong_letters_storage))
command = input("guess: ").lower()
if not '-' in guess_word:
print("you win!")
break
elif command == 'quit':
print("thank you for playing my game")
break
else:
if not command in alphabet :
print("pick an alphabet")
elif command in wrong_letters_storage:
print("you have picked this word")
else :
if command in secret_word :
print("right")
c += 1
b -= 1
for x in range(0, len(secret_word)):
if correct_letters[x] == command:
guess_word[x] = command
print(guess_word)
elif not command in secret_word :
print("wrong")
wrong_letters_storage.append(command)
c += 1
b -= 1
else :
print("error")
print("*"*20)
return print("Thank you for playing my game")
words()
guessing()
print("the words that you are guessing is " + secret_word )
Your code has several "problems":
you check if the current solution has no more '-' in it, after you ask for the next character input()
return print("whatever") returns None because the print function prints and returns None
you use variables with single_letter_names that make it hard to know what they are for
you use list's instead of set()'s for lookups (its fine here, but not optimal)
You can fix your problem by moving the test statement before the input() command:
# your code up to here
while True:
c = 0
b = 7
while c <= 7:
if not '-' in guess_word:
print("you win!")
break
print("")
hide = ""
print("you have " + str(b) + " guess left")
print("Wrong letters : " + str(wrong_letters_storage))
command = input("guess: ").lower()
if command == 'quit':
print("thank you for playing my game")
break
else:
# etc.
It would probably be better to do some more refaktoring:
import random
import string
import sys
def join_list(l):
return ''.join(l)
def guessing():
# no need to put all this in global scope
alphabet = frozenset(string.ascii_lowercase) # unchangeable set of allowed letters
words = ['hat', 'pop', 'cut', 'soup', 'you', 'me', 'beautiful', 'lol']
secret = random.choice(words) # your random word
secret_word = list(secret.lower()) # your random word as lowercase list
wrong = set() # set of wrongly guessed characters
right = set() # set of already correctly guessed characters
correct = frozenset(secret_word) # set of letters in your word, not changeable
guess_word = ['-' for k in correct] # your guessed letters in a list
guesses = 7
guessed = 0
print("The length of the word is ", len(secret))
# loop until breaked from (either by guessing correctly or having no more guesses)
while True:
print("")
print(f"you have {guesses-guessed} guess left")
if wrong: # only print if wrong letters guessed
print(f"Wrong letters : {wrong}")
# print whats know currently:
print(f"Guess so far: {join_list(guess_word)}")
command = input("guess: ").strip().lower()
try:
if command != "quit":
command = command[0]
except IndexError:
print("Input one letter")
continue
if command == 'quit':
print("thank you for playing my game")
break
else:
if command not in alphabet:
print("pick an alphabet")
continue
elif command in (wrong | right):
print("you already picked this letter")
continue
else :
guessed += 1
# always lookup in set of lowercase letters
if command in correct:
right.add(command)
for i,letter in enumerate(secret_word):
if command == letter:
# use the correct capitalisation from original word
guess_word[i] = secret[i]
else:
print("wrong")
wrong.add(command)
print("*"*20)
# break conditions for win or loose
if join_list(secret_word) == join_list(guess_word):
print("You won.")
break
elif guessed == guesses:
print(f"You lost. Word was: {join_list(secret_word)}")
break
guessing()

Question about dictionary items addition in Python (Guess the word game)

How can i add a letter multiple times in the different keys of a dictionary?
I made a guess the word game where the user enters the letter to complete the mysterious word.
Everything works fine with words where letters appears just one time (Ex. Dog) but I have problems when letters occur multiple times (Ex. Employee) because only the first one is filled.
I know this is probably not the most efficient way of doing this but I'm starting programming in python and was experimenting a bit with the concepts learned.
Here's the code, thanks for the help:
import os
word = input('choose the word to play with: ')
os.system('cls')
word_list = list(word)
word_dict = {}
for x in range(len(word_list)):
word_dict[str(x)] = word_list[x]
guess_dict = {}
for x in range(len(word_list)):
guess_dict[str(x)] = '_'
health = 10
victory = False
values = list(guess_dict.values())
print(values)
while victory == False:
letter = input('Choose the letter: ')
if letter in word_dict.values():
guess_dict[list(word_dict.keys())[list(word_dict.values()).index(letter)]] = letter
valori = list(guess_dict.values())
print(valori)
print()
if guess_dict == word_dict:
victory = True
print ('You won')
else:
health -= 1
print('ERROR!! ' + str(health) + ' lives remaining')
if health == 0:
print('You lose')
break
Your problem is exactly the dictionary. The dictionary has only one entry for each key. See here
In my opinion, you should use either a list, or a list of dictionaries.
import os
word = input('choose the word to play with: ')
os.system('cls')
word_list = list(word)
guess_list = [{'character': x, 'guessed': False} for x in word]
health = 10
victory = False
while True:
str = ''
for item in guess_list: #generate the string each iteration once
if False == item['guessed']:
str = str + "'_'"
else:
str = str + "'" + item['character'] + "'"
print(str)
if True == victory: #put the test here, so that the result is printed
print('You won!')
break
else:
letter = input('Choose the letter: ')
hit = False
missed_cnt = 0
for item in guess_list:
if item['character'] == letter: #if letter guessed, set flag
item['guessed'] = True
hit = True
if item['guessed'] == False: #count unguessed letters
missed_cnt +=1
if False == hit:
health -= 1
print('ERROR!! {0} lives remaining'.format(health))
if 0 == health:
print('You lose!')
break
if 0 == missed_cnt: #exit only after printing result
victory = True
Instead of a dictionary, you could use a set(). Since guessing a letter reveals all instances of that letter, removing it from the set corresponds to the same notion.
So you could do something like this:
word = input("hidden word:")
remainingLetters = set(word)
health = 10
while True:
print( "".join( "_" if letter in remainingLetters else letter for letter in word) )
letter = input("guess a letter:")
if letter in remainingLetters:
remainingLetters.remove(letter)
if remainingLetters: continue
print("you Win!")
break
health -= 1
if health == 0:
print("You lose")
break
print('ERROR!! {0} lives remaining'.format(health))
I would simply use a list of letters:
import os
from copy import deepcopy
word = list(input('choose the word to play with: '))
compare = deepcopy(word)
os.system('cls')
guess = []
for index, letter in enumerate(word):
guess.append('_')
health = 10
victory = False
while not victory:
letter = input('Choose the letter: ')
if letter in compare:
guess[compare.index(letter)] = letter
compare[compare.index(letter)] = ' '
print(guess)
print()
if guess == word:
victory = True
print ('You won')
else:
health -= 1
print('ERROR!! ' + str(health) + ' lives remaining')
if health == 0:
print('You lose')
break
The deepcopy in the beginning is because in Python if you do compare = word, compare would become a pointer to word. The variable compare by the way is to remove the already guessed characters from.
You could also check the input letter to make the code more robust:
while not victory:
letter = input('Choose the letter: ')
try:
value = float(letter)
print('Please enter a letter of type (str).')
continue
except ValueError:
pass
if len(letter) != 1:
print('Please enter only one letter!')
continue

If Statement Firing Regardless of Conditions, Variable not Aggregating Past One

Please see my comments. They explain my problems. I have an if statement that is firing no matter what and a variable that is not aggregating properly and I don't know why. Thanks in advance. (The following is a hangman program currently in development. printBody() will eventually print out the whole man.)
import random
words = []
lettersGuessed = []
isGuessed = 0
wordFile = open(r'C:\Users\Sarah\PycharmProjects\hangman\words.txt')
for word in wordFile:
words.append(word.strip())
limbCount = 0
def printBody(limbCount):
limbCount += 1
if limbCount == 1:
print("\n0")
elif limbCount == 2:
print("\n0")
print("\n |")
return limbCount
mysteryWord = random.choice(words)
while len(mysteryWord) <= 1:
mysteryWord = random.choice(words)
for letter in mysteryWord:
print("?", end = "")
print("\n")
def isWon(mysteryWord, lettersGuessed):
#win conditions
count = 0
for letter in mysteryWord:
if letter in lettersGuessed:
count += 1
if count == len(mysteryWord):
isGuessed = 1
return isGuessed
count = 0
victory = 0
while not victory:
guess = input("Guess a letter \n")
if guess.upper() or guess.lower() in mysteryWord:
lettersGuessed.append(guess)
for letter in mysteryWord:
if letter in lettersGuessed:
print(letter, end ='')
else:
print("?", end = '')
#this statement is firing no matter what and I don't know why
if guess.upper() or guess.lower() not in mysteryWord:
#when I call printBody() limbCount increases to one but then stays there. It won't go up to two or three.
printBody(limbCount)
print("\n")
count = 0
victory = isWon(mysteryWord, lettersGuessed)
print("Congratulations, you correctly guessed ", mysteryWord)
try:
guess.upper() not in mysteryWord or guess.lower() not in mysteryWord
I believe you are having this problem since it is checking "is guess.upper() truthy", and since it is a string (which is truthy) it will enter that if statement

Categories