NIM game - re-running the game - python

I have to do a small game called NIM. The game is a human vs. computer game where each player removes a number of straws (1,2 or 3) and the player who removes the last straw looses. I got the game to work properly but the problem is that it doesn't want to re-run if the player wants to play again. Any help would be apprecieted. :)
import random
print("""************ NIM GAME ***********
************ Game Start ***********
************ The rules ***********
-----------------------------------------------------
You need to remove from 1 to 3 straws from the pile.
The player that removes the final straw is the loser.
-----------------------------------------------------""")
player1=str(input("Enter your name. "))
player2="Computer"
howMany=0
gameover=False
strawsNumber=random.randint(10,20)
if (strawsNumber%4)==1:
strawsNumber+=1
def removingStrawsComputer():
removedNumber=random.randint(1,3)
global strawsNumber
while removedNumber>strawsNumber:
removedNumber=random.randint(1,3)
strawsNumber-=removedNumber
return strawsNumber
def removingStrawsHuman():
global strawsNumber
strawsNumber-=howMany
return strawsNumber
def humanLegalMove():
global howMany
legalMove=False
while not legalMove:
print("It's your turn, ",player1)
howMany=int(input("How many straws do you want to remove?(from 1 to 3) "))
if howMany>3 or howMany<1:
print("Enter a number between 1 and 3.")
else:
legalMove=True
while howMany>strawsNumber:
print("The entered number is greater than a number of straws remained.")
howMany=int(input("How many straws do you want to remove?"))
return howMany
def checkWinner(player):
if strawsNumber==0:
print(player," wins.")
global gameover
gameover=True
return gameover
def resetGameover():
global gameover
gameover=False
return gameover
def game():
while gameover==False:
print("It's ",player2,"turn. The number of straws left: ",removingStrawsComputer())
checkWinner(player1)
if gameover==True:
break
humanLegalMove()
print("The number of straws left: ",removingStrawsHuman())
checkWinner(player2)
def playAgain():
answer=input("Do you want to play again?(y/n)")
resetGameover()
while answer=="y":
game()
else:
print("Thanks for playing the game")
game()
playAgain()

You forgot to reset the number of straws at the start of each game. After def game():, you should insert:
global strawsNumber
strawsNumber=random.randint(10,20)
Note: you also need to put answer=input("Do you want to play again?(y/n)") at the end of your while answer=="y": loop. This will ask the user for a replay every time, instead of just after the first game.

Related

paper scissors rock python game

This is my attempt to create paper, rock and scissors game
There seems to be an error with while loop, "roundNum is not defined", please help?
import random
options = ['rock','paper','scissors']
def game(rounds):
roundNum = 1
playerScore = 0
computerScore = 0
while roundNum <= rounds:
print('Round Number '+ str(roundNum))
Player = input('Please choose rock, paper or scissors')
computer = options[random.randint(0,2)]
print(computer)
How do I create code to ask the payer if he wants to play again? and if so to run the code again?
Make sure your indentation is correct.
import random
options = ['rock','paper','scissors']
def game(rounds):
roundNum = 1
playerScore = 0
computerScore = 0
while roundNum <= rounds:
print('Round Number '+ str(roundNum))
Player = input('Please choose rock, paper or scissors')
computer = options[random.randint(0,2)]
print(computer)
The issue is with the indentation of while loop.
As function game and while are at same level any object declared inside the game function will be out of scope/unreachable for while loop.
A simple tab will resolve the issue in this case as follow :
import random
options = ['rock','paper','scissors']
def game(rounds):
roundNum = 1
playerScore = 0
computerScore = 0
while roundNum <= rounds:
print('Round Number '+ str(roundNum))
Player = input('Please choose rock, paper or scissors')
computer = options[random.randint(0,2)]
print(computer)
The reason you are getting the error RoundNum is not defined is because you are defining variables inside of a function, this means that you will have to call the function game() to define the three variables roundNum, playerScore and computerScore. To solve this, we remove the game() function and define the three variables in the main script like this:
import random
options = ['rock', 'paper', 'scissors']
roundNum = 1 # Defines the roundNum variable
playerScore = 0
computerScore = 0
def game(rounds):
while roundNum <= rounds:
print('Round Number ' + str(roundNum)
Option = input('Please choose rock, paper, or scissors > ')
Computer = options[random.randint(0, 2)]
# After all the rounds are finished, ask if the player wants to play again
x = input("Do you want to play again? ")
# If they say yes, start a new round of Rock, paper, Scissors
if x.lower() == "yes":
game(1)
# If they don't want to play then exit the program
if x.lower() == "no":
print("Bye")
exit()
game(1)
Edit: if you want to ask whether the player wants to play again, just call the input function inside a variable, then check what the player said, if they say yes then start a new game of Rock, Paper Scissors, if they don't then exit the program

Guessing game against the computer Python

I wrote this code for a guessing game against the computer using the random method. The programme work but when it turns to the user for the second round it can not continue. Can you help, please?
import random
global rand_val
rand_val=random.randint(10,50)
def start():
ans=int(input("Enter a number between 10 and 50: "))
if ans>=10 and ans<=50:
new_rand_val=rand_val-ans
if new_rand_val<=0:
print("You guessed too far, try again\n")
main()
else:
print("Amount left is,",new_rand_val," Now its the Computer turn\n")
comput_turn(new_rand_val)
def comput_turn(new_rand_val):
comp_guess=random.randint(0,new_rand_val) #the comupter is playing by guessing a number
checking(comp_guess, new_rand_val)
def checking(comp_guess, new_rand_val):
print("\n The computer chose:", comp_guess)#this is for me to follow up
remain_rand_val=new_rand_val-comp_guess
if remain_rand_val<=0:
print("Computer guessed too far, now its trying again:")
comput_turn(new_rand_val)
userturn(remain_rand_val)
print("Amount left is:", remain_rand_val," \n\n Now its your turn\n")
userturn(remain_rand_val)
def userturn(remain_rand_val):
ans=int(input("Enter a number between 0 and"))
print(remain_rand_val)
if ans>=10 and ans<=remain_rand_val:
user_rand_val=remain_rand_val-ans
print("Amount left is,",user_rand_val," Now its the Computer turn\n")
comput_turn(user_rand_val)
def main():
start()

Updating local variables inside a function in Python

I'm learning python and about to complete a program to run a rock, paper, scissors game between two players for three rounds and update player scores at the end of each round and display it on screen:
import random
"""This program plays a game of Rock, Paper, Scissors between two Players,
and reports both Player's scores each round."""
moves = ['rock', 'paper', 'scissors']
"""#!/usr/bin/env python3
import random
"""This program plays a game of Rock, Paper, Scissors between two Players,
and reports both Player's scores each round."""
moves = ['rock', 'paper', 'scissors']
"""The Player class is the parent class for all of the Players
in this game"""
class Player:
def move(self):
return 'rock'
def learn(self, my_move, their_move):
pass
def beats(one, two):
return ((one == 'rock' and two == 'scissors') or
(one == 'scissors' and two == 'paper') or
(one == 'paper' and two == 'rock'))
class RandomPlayer(Player):
def move(self):
return random.choice(moves)
class Game:
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def keep_p1_score(self, p1_Score):
return p1_Score
def play_round(self):
move1 = self.p1.move()
move2 = self.p2.move()
p1_Score = 0
p2_Score = 0
print(f"Player One played: {move1} Player Two played: {move2}")
if beats(move1, move2) == True:
print('**Player One wins**')
p1_Score += 1
elif beats(move2, move1) == True:
print('**Player Two wins**')
p2_Score += 1
else:
print('**TIE**')
print(f'Score: Player One: {p1_Score} Player Two: {p2_Score}')
self.p1.learn(move1, move2)
self.p2.learn(move2, move1)
def play_game(self):
print("Game start!")
for round in range(3):
print(f"Round {round + 1}:")
self.play_round()
print("Game over!")
if __name__ == '__main__':
game = Game(RandomPlayer(), RandomPlayer())
game.play_game()
The problem is when I run the code it doesn't update players scores. As you can see in this picture of the output even though player two won rounds two and three, his score at the end of run three is still 1 instead of 2. I know that's because for each iteration of play_round function in the for loop inside the play_game function the values of p1_score and p2_score resets to zero but I do not know how to stop that from happening. Any suggestion will be greatly appreciated.
program output
The problem is that p1_Score and p2_Score are local variables in play_round. So every time you call this function, you get a new instance of these variables. Moreover, you always set
p1_Score = 0
p2_Score = 0
in play_round. So at the end of the function no score will ever be larger than 1.
To rememdy this, use self.p1_Score and self.p2_Score to make these variables instance variables and also move the 0-initialization into the __init__ function of the game class. Alternatively, make the score a class variable of the Player class.

Unable to break a python while loop inside a function

This program is a snakes and ladders program for my GCSE computer science (don't worry, this is just practice), and I'm having trouble breaking a while loop with a function that exists inside the loop. Here's the code:
win = False
while win == False:
print("Player 1 goes first.")
def dice():
roll = random.randint(1,6)
return roll
roll = dice()
print("They roll a...",roll)
player1+=roll
def check():
if player1 in ladders or player2 in ladders:
print("A ladder has moved the player to a new position.")
elif player1 in snakes or player2 in snakes:
print("A snake has moved the player to a new position.")
elif player1 >= 36:
print("Congratulations. Player 1 has won the game.")
win = True
elif player2 >= 36:
print("Congratulations. Player 2 has won the game.")
win = True
check()
print("Player 1 is on square",player1)
It's obviously not finished yet, and that's not all the code. After that bit, it does the same but with player2. There's a tuple above it that the check function checks to see if the player landed on a snake or a ladder, but I haven't added the code which actually moves the player up/down the ladder/snake.
The error is that the while loop is an infinite loop.
I've tried changing the whole win = False or True thing to just while True and then using break where I say win = True, but then it returns an error of 'break outside loop' even though the break is obviously inside the loop. I wonder if it's because I need to return something from the function, but I'm not quite sure how to do that. Simply putting 'return win' below both win = True doesn't change anything, and the while loop still continues indefinitely.
I've looked here and here for answers but neither worked for me; I think my situation is slightly different.
Perhaps this is what you are looking for? Note how I took the functions out of the loop. Then I ditched using a boolean variable altogether, as there is cleaner ways around it. You can use while True and then simply break if a certain condition is met. If you want the loop go back to starting point when a certain condition is met, you can use continue.
def dice():
return random.randint(1,6)
def check():
if player1 in ladders or player2 in ladders:
print("A ladder has moved the player to a new position.")
elif player1 in snakes or player2 in snakes:
print("A snake has moved the player to a new position.")
elif player1 >= 36:
print("Congratulations. Player 1 has won the game.")
return True
elif player2 >= 36:
print("Congratulations. Player 2 has won the game.")
return True
while True:
print("Player 1 goes first.")
roll = dice()
print("They roll a...",roll)
player1 += roll
if check():
break
print("Player 1 is on square",player1)
I didn't really touch the logic but it would make sense to pass the player score into check.
It happened because when you are assign variable in function it used local variable. So, for a fast fix you can add global win in check function:
def check():
global win
if player1 in ladders or player2 in ladders:
print("A ladder has moved the player to a new position.")
elif player1 in snakes or player2 in snakes:
print("A snake has moved the player to a new position.")
elif player1 >= 36:
print("Congratulations. Player 1 has won the game.")
win = True
elif player2 >= 36:
print("Congratulations. Player 2 has won the game.")
win = True
You can read more about type of variables here - http://www.python-course.eu/python3_global_vs_local_variables.php
Also it's not a good idea to store function inside while because it will create function on each iteration which is not good. So better is define them outside of loop.

Adding scoring system to a number guessing game including play again

I have my game working fine now but I still want to take it further. I want to have a point scoring system included. I want the player to score 5 points if they have 1 live left when they win, 10 if they have 2 and 15 if they have all 3. But I don't want the score to be reset if they play again I just want it to say when the quit the game you have scored " " points. I have tried to do this in many different ways but I can seem to get it work it resets the score every time press y on the play again. I've included my base game code below please try and help. Any other recomendations for this game are very welcome.
**My apologies I don't know if I made this clear enough before. I don't want the score to be stored after the programs closed just until the player presses n when asked to play again **
#imports required modules
import random
#correct number variable created
num = 0
#generates number at random
comp_num = random.randint(1,10)
print('I\'m thinking of a number guess what it is...\n')
#main game code
def main():
#generates number at random
comp_num = random.randint(1,10)
#set num as a global variable
global num
#lives created
lives = 3
while lives >= 1:
#player guesses
guess = int(input('Guess: '))
if comp_num == guess:
#if correct says well done
print('\nWell Done! You guessed Correctly!\n')
break
elif comp_num >= guess:
#if guess is too low tells player
#one live taken for incorrect guess
lives = lives -1
print('\nToo low!\n')
#player is told how many lives they have left
print('You guessed incorrectly. You have',lives,'live(s) remaining.\n')
if lives == 0:
#if player guesses incorrectly they get told the correct awnser
print('The number I was thinking of was...',comp_num,'!\n')
elif comp_num <= guess:
#if guess is too high tells player
#one live taken for incorrect guess
lives = lives -1
print('\nToo high!\n')
#player is told how many lives they have left
print('You guessed incorrectly. You have',lives,'live(s) remaining.\n')
if lives == 0:
#if player guesses incorrectly they get told the correct awnser
print('The number I was thinking of was...',comp_num,'!\n')
def end():
#asks player if they want to play again
play_again = input('Would you like to play again?[Y/N] ')
while play_again.lower() == 'y':
#if they do game resets and plays again
if play_again.lower() == 'y':
comp_num = random.randint(1,10)
print('\nI\'m thinking of a number guess what it is...\n')
main()
play_again = input('Would you like to play again?[Y/N] ')
if play_again.lower() == 'n':
break
if play_again.lower() == 'n':
#if they don't game ends
input('Ok, Press enter to exit')
exit()
#calls main section of game
main()
#calls end of game to give option of playing again and reseting game
end()
Use this pattern:
def game(): # Play a single game.
lives = 3
...
return 5 * lives # Return the score of the game.
def ask_again():
print 'Play again?'
answer = ...
return answer == 'y' # Return True iff the user wants to play again.
def main():
score = game()
while ask_again():
score += game()
print score
main()
You should use global variable for storing the amount of scored points.
So I added code for adding points and printing the message:
#imports required modules
import random
#correct number variable created
num = 0
score = 0
#generates number at random
comp_num = random.randint(1,10)
print('I\'m thinking of a number guess what it is...\n')
#main game code
def main():
#generates number at random
comp_num = random.randint(1,10)
#set num as a global variable
global num
global score
#lives created
lives = 3
while lives >= 1:
#player guesses
guess = int(input('Guess: '))
if comp_num == guess:
#if correct says well done
print('\nWell Done! You guessed Correctly!\n')
# add score
if lives == 3:
score += 15
elif lives == 2:
score += 10
elif lives == 1:
score += 5
break
elif comp_num >= guess:
#if guess is too low tells player
#one live taken for incorrect guess
lives -= 1
print('\nToo low!\n')
#player is told how many lives they have left
print('You guessed incorrectly. You have',lives,'live(s) remaining.\n')
if lives == 0:
#if player guesses incorrectly they get told the correct awnser
print('The number I was thinking of was...',comp_num,'!\n')
elif comp_num <= guess:
#if guess is too high tells player
#one live taken for incorrect guess
lives -= 1
print('\nToo high!\n')
#player is told how many lives they have left
print('You guessed incorrectly. You have',lives,'live(s) remaining.\n')
if lives == 0:
#if player guesses incorrectly they get told the correct awnser
print('The number I was thinking of was...',comp_num,'!\n')
def end():
global score
#asks player if they want to play again
play_again = input('Would you like to play again?[Y/N] ')
while play_again.lower() == 'y':
#if they do game resets and plays again
if play_again.lower() == 'y':
comp_num = random.randint(1,10)
print('\nI\'m thinking of a number guess what it is...\n')
main()
play_again = input('Would you like to play again?[Y/N] ')
if play_again.lower() == 'n':
break
if play_again.lower() == 'n':
#if they don't game ends
print("You scored " + str(score) + " amazing points!")
input('Ok, Press enter to exit')
exit()
#calls main section of game
main()
#calls end of game to give option of playing again and reseting game
end()

Categories

Resources