Make while loop inaccessible - python

I'm trying to make a simple game to practice what I've been learning in class. But I'm unable to fix a while loop that is doing something I don't want it to do.
If player_one_range_counter is identical to one of the spots (spot_1, spot_2, spot_3, etc.) the loop should be False and inaccessible. The same thing should happen if player_two_range_counter is identical to one of the spots.
If both are identical to one or any of the spots, that means their respective loops become False and the game is over. The problem is even when they're both identical to one or any of the spots the game continues. It shouldn't.
Could someone enlighten me on what I've done wrong?
continue_game = True
while continue_game:
player_one_play = True
player_two_play = True
while player_one_play:
print(user_1_name)
x = steps_to_move() # returns int from steps_to_move()
player_one_range_counter += x # updates the range for palyer one
user_1_turtle.fd(x) # turtle move x amount of pixels forward
if player_one_range_counter == spot_1 or player_one_range_counter == spot_2 or player_one_range_counter == spot_3 or player_one_range_counter == spot_4 or player_one_range_counter == spot_5:
print("\n" + user_1_name, "stepped on a mine! \n")
player_one_play = False
else:
break
while player_two_play:
print(user_2_name)
y = steps_to_move()
player_two_range_counter += y
user_2_turtle.fd(y)
if player_two_range_counter == spot_1 or player_two_range_counter == spot_2 or player_two_range_counter == spot_3 or player_two_range_counter == spot_4 or player_two_range_counter == spot_5:
print("\n" + user_2_name, "stepped on a mine! \n")
player_two_play = False
else:
break
if player_one_play == False and player_two_play == False:
continue_game = False

I believe the primary problem is that this is inside the while loop:
player_one_play = True
player_two_play = True
when it should be before the while loop. How I might approach your code logic:
spots = [spot_1, spot_2, spot_3, spot_4, spot_5]
player_one_playing = True
player_two_playing = True
while True:
if player_one_playing:
print(user_1_name)
steps = steps_to_move() # returns int from steps_to_move()
user_1_turtle.fd(steps) # turtle move x amount of pixels forward
player_one_range_counter += steps # updates the range for player one
if player_one_range_counter in spots:
print("\n" + user_1_name, "stepped on a mine!\n")
player_one_playing = False
if player_two_playing:
print(user_2_name)
steps = steps_to_move()
user_2_turtle.fd(steps)
player_two_range_counter += steps
if player_two_range_counter in spots:
print("\n" + user_2_name, "stepped on a mine! \n")
player_two_playing = False
if not (player_one_playing or player_two_playing):
break
The inner while loops in your original code are effectively if statements so I have made them such in my code.

Related

where do i incorporate that no body has won, in my tic-tac-toe game

I am new to coding and has recently started learning python. My first challenge is to build a tic tac toe game. Below are my codes for the game, everything worked fine except that when there is no winner(i.e. game draw); i want to display no body has won the game. I've tried to incorporate an else in various places. but, they didn't help. Here is my code.
# a dictionary to display the grid
grid = {
'1':'1', '2':'2', '3':'3',
'4':'4', '5':'5', '6':'6',
'7':'7', '8':'8', '9':'9'
}
# a list to store the values that has already been entered
used_places = []
# players and their symbols
player_1 = 'x'
player_2 = 'o'
# to store result
result = None
def grid_display():
#this function displays the grid
print('\n\n')
print(grid['1'], '\t|\t', grid['2'], '\t|\t', grid['3'])
print(''.rjust(19,'*'))
print(grid['4'], '\t|\t', grid['5'], '\t|\t', grid['6'])
print(''.rjust(19, '*'))
print(grid['7'], '\t|\t', grid['8'], '\t|\t', grid['9'])
def win_the_game():
# this function checks for result and returns true or false
if(
(grid['1'] == grid['2'] == grid['3']) or (grid['4'] == grid['5'] == grid['6']) or
(grid['7'] == grid['8'] == grid['9']) or (grid['1'] == grid['4'] == grid['7']) or
(grid['2'] == grid['5'] == grid['8']) or (grid['3'] == grid['6'] == grid['9']) or
(grid['1'] == grid['5'] == grid['9']) or (grid['3'] == grid['5'] == grid['7'])
):
return True
else:
return False
def taking_turns(turn):
#this function asks user for input
print("its turn of ", turn)
choice = input("enter your choice")
while not (choice.isdecimal() and choice in grid and (choice not in used_places)):
# taking proper input by checkin it with already entered numbers
# and if it is a number
# and if number is in between 1 and 9
choice = input("\nenter your choice properly:")
player_move(choice, turn)
def player_move(move, assign):
# this function fills the entered numbers into used_places list
# and replaces numbers in grid with user input
used_places.append(move)
grid[move] = assign
print("player 1 : 'X'")
print("player 2 : 'O'")
for i in range(0,10): # loops 9 times to play the game
if i % 2 == 0: # giving turns. if i is even, player 1 gets turn and odd, player 2
grid_display() # displaying complete grid
turn = player_1 # to display whose turn it is; refer the function
taking_turns(turn)
if win_the_game() == True: # if the called function returns true in this 'if'
result = turn # player 1 wins
break
else:
grid_display() # same code as above
turn = player_2
taking_turns(turn)
if win_the_game() == True:
result = turn
break
print('\n\n',result, "won the game!!") # printing result
Instead of setting result = None, set result = 'Nobody'.
Looking at your logic, you only set result if somebody wins, this would leave the default of result to nobody.
-- edit --
Sorry, I kinda got carried away and re-wrote the logic of your game in proving my solution. Take it or leave it, but it works great now and maybe you can use it as an example to fix your own.
import os
# a dictionary to display the grid
grid = {
'1':'1', '2':'2', '3':'3',
'4':'4', '5':'5', '6':'6',
'7':'7', '8':'8', '9':'9'
}
# a list to store the values that are available
places = ['1','2','3','4','5','6','7','8','9']
# to store result
result = 'Nobody'
# starting player
turn = 'O'
# display a game grid
def grid_display():
os.system('cls' if os.name == 'nt' else 'clear')
#this function displays the grid
print
print(grid['1'], '|', grid['2'], '|', grid['3'])
print(''.rjust(25,'*'))
print(grid['4'], '|', grid['5'], '|', grid['6'])
print(''.rjust(25, '*'))
print(grid['7'], '|', grid['8'], '|', grid['9'])
# check to see if anyone has won or are we out of moves
def win_the_game():
# this function checks for result and returns true or false
if(
(grid['1'] == grid['2'] == grid['3']) or (grid['4'] == grid['5'] == grid['6']) or
(grid['7'] == grid['8'] == grid['9']) or (grid['1'] == grid['4'] == grid['7']) or
(grid['2'] == grid['5'] == grid['8']) or (grid['3'] == grid['6'] == grid['9']) or
(grid['1'] == grid['5'] == grid['9']) or (grid['3'] == grid['5'] == grid['7'])
):
return True
# checks if there are any moves left
elif not places:
return False
else:
return False
# input / grid update function
def taking_turns():
# this function asks user for input
# use RAW_INPUT to make it a string
print
print map(str, places)
choice = raw_input("\nEnter "+turn+"'s choice: ")
if choice in places:
# this removes the number from the available list
# and replaces numbers in grid with user input
places.remove(choice)
grid[choice] = turn
# Logic loop
while places:
grid_display() # always display the grid
if turn == "O": # giving turns.
turn = 'X'
taking_turns()
if win_the_game() == True: # if the called function returns true in this 'if'
result = turn # player 1 wins
grid_display() # Winners GRID
break
else:
turn = 'O'
taking_turns()
if win_the_game() == True:
result = turn
grid_display() # Winners GRID
break
# results
print
print(result, "won the game!!") # printing result
print

python Scopage of a function output within gameloop not evaluating

My problem is, after calling the function check_win in the gameloop,
even though the function evaluates false(I've checked so this is the
case), I assign this false value to gamePlaying inside the loop,
however the game loop gamePlaying conditional still evaluates true
and keeps going.
def check_win(): #function checks for three in a row across, down, and diagonals
for x in range (0, 3) :
y = x*3
if (board[y] == board[(y + 1)] and board[y] == board[(y + 2)]):
gamePlaying = False
else:
gamePlaying = True
if (board[x] == board[(x + 3)] and board[x] == board[(x + 6)]):
gamePlaying = False
else:
gamePlaying = True
if((board[0] == board[4] and board[0] == board[8]) or
(board[2] == board[4] and board[4] == board[6])):
gamePlaying = False
else:
gamePlaying = True
return(gamePlaying)
currentPlayer = [first_player,second_player] #creates list to iterate over turns
gamePlaying = True #bool for gameloop
while gamePlaying: #main game loop
for i in currentPlayer: #iterates over current player to switch turns
draw_board()
place_move = int(input(first_move + ' what is your move? ')) #inputs then places move for first_player
board[place_move] = first_player
gamePlaying = check_win() #should take bool output of check_win and store to cont or end gameloop
draw_board()
place_move = int(input(second_move + ' what is your move? ')) #inputs then places move for second_player
board[place_move] = second_player
gamePlaying = Check_win() #should take bool output of check_win and store to cont or end gameloop
The issue is that you are using if statements when you mean to use elif. See the docs.
However, what you probably want to do is return False at those points since that would allow the function to exit early and you would have to worry that gamePlaying gets set back to True by later if statements.

python tic tac toe problems

I am new to coding and has recently started learning python. My first challenge is to build a tic tac toe game. Below are my codes for the game, everything worked fine except that when I want to restart the game or end the game, the loop won't break or the game cannot start.Could anyone figure out whats wrong with my codes. thank you!
Matrix = [[' ' for i in range(3)]for j in range(3)]
for i in Matrix:
print(i) #this is the 3x3 board
def check_done(value): #this is to check if the player has won the game
for a in range(0,3):
if Matrix[0][a]==Matrix[1][a]==Matrix[2][a]==value\
or Matrix[a][0]==Matrix[a][1]==Matrix[a][2]==value:
print ('won')
return True
#when the vertical column or horizontal row is equal, the
player won the game
if Matrix[0][0]==Matrix[1][1]==Matrix[2][2]==value\
or Matrix[2][0]==Matrix[1][1]==Matrix[0][2]==value:
print('won')
return True
#when the diagonal rows are equal, the player won the game
if ' ' not in Matrix[0] and ' ' not in Matrix[1] and ' ' not in
Matrix[2]:
print('draw')
return True
#when every grid is filled in the board and no win criteria is
fulfilled, it is a draw
return False
def replay(): #this is to determine if the player wants to restart or
end the game
command =input('Enter r to restart, or e to end game: ')
while True:
if command == 'r':
player1_input()
if command == 'e':
return
break
else:
print('Invalid command.')
def player1_input(): #this is an input function to allow players to
position their next move
print('Player 1 insert your name here')
name1=input()
print('player 2 insert your name here')
name2=input()
while True:
inputValid = False
while inputValid == False:
print(name1,'please place x coordinates')
xinput=int(input())
print(name1,'please place y coordinates')
yinput=int(input())
if yinput >= 0 & yinput <= 2 & xinput >=0 & xinput <= 2:
if Matrix[yinput][xinput] == ' ':
Matrix[yinput][xinput] = 'X'
for i in Matrix:
print(i)
if check_done('X'):
print(name1,'won')
replay()
inputValid = True
inputValid = False
while inputValid == False:
print(name2,'please place x coordinates')
xinput=int(input())
print(name2,'please place y coordinates')
yinput=int(input())
if yinput >= 0 & yinput <= 2 & xinput >=0 & xinput <= 2:
if Matrix[yinput][xinput] == ' ':
Matrix[yinput][xinput] = 'O'
for i in Matrix:
print(i)
if check_done('O'):
print(name2,'won')
replay()
inputValid = True
return True
The while loop for the main gameplay is running infinite.
To solve that, you can use a continue_game flag.
A simple example:
def player1_input():
# rest of the code
continue_game = True
while continue_game:
# logic for the game
continue_game = replay()
def replay():
# Returns true or false on user input.
while True:
command = raw_input('...')
if command == 'r':
return True
elif command == 'e':
return False
else:
print ('Invalid command')
The method replay can return a boolean as approriate based on user input.
Further, note that you have to re-initialize the matrix with empty values, if the game is supposed to be restarted.
It is difficult to read the code as it is posted. But it seems to me that your while True is an infinite cycle. I dont see any break that allows you to exit the while

Monty Hall simulation not working as intended

I've been trying out to solve the monty hall problem in Python in order to advance in coding, which is why I tried to randomize everything. The thing is: I've been running into some trouble. As most of you probably know the monty problem is supposed to show that changing the door has a higher winrate (66%) than staying on the chosen door (33%). For some odd reason though my simulation shows a 33% winrate for both cases and I am not really sure why.
Here's the code:
from random import *
def doorPriceRandomizer():
door1 = randint(0,2) #If a door is defined 0, it has a price in it
door2 = randint(0,2) #If a door is defined either 1 or 2, it has a goat in it.
door3 = randint(0,2)
while door2 == door1:
door2 = randint(0,2)
while door3 == door2 or door3 == door1:
door3 = randint(0,2)
return door1,door2,door3 #This random placement generator seems to be working fine.
while True:
loopStart = 0
amountWin = 0
amountLose = 0
try:
loopEnd = int(input("How often would you like to run this simulation: "))
if loopEnd < 0:
raise ValueError
doorChangeUser = int(input("[0] = Do not change door; [1] = Change door: "))
if doorChangeUser not in range(0,2):
raise ValueError
except ValueError:
print("Invalid input. Try again.\n")
else:
while loopStart != loopEnd:
gameDoors = doorPriceRandomizer()
inputUser = randint(0,2)
if doorChangeUser == 0:
if gameDoors[inputUser] == 0:
amountWin += 1
loopStart += 1
else:
amountLose += 1
loopStart += 1
elif doorChangeUser == 1:
ChangeRandom = 0
while gameDoors[ChangeRandom] == gameDoors[inputUser]:
ChangeRandom = randint(0,2)
if gameDoors[ChangeRandom] == 0:
amountWin += 1
loopStart += 1
else:
amountLose += 1
loopStart += 1
print("Win amount: ",amountWin,"\tLose amount: ",amountLose)
What am I doing wrong? I really appreciate all help! Thanks in advance!
ChangeRandom = 0
while gameDoors[ChangeRandom] == gameDoors[inputUser]:
ChangeRandom = randint(0,2)
This doesn't do what you think it does. Instead of checking if the ChangeRandom door is the same as the inputUser door, this checks if the ChangeRandom door and the inputUser door have the same value -- that is to say they're either both winners or both losers.
That said, that's not even what you want to do. What you want to do is to find a door that's not the user's input that IS a loser door, then switch to the OTHER one that isn't the user's input. This could be implemented with minimal change to your code as:
other_wrong_door = next(c for c, v in enumerate(gameDoors) if v != 0 and c != inputUser)
new_door = next(c for c, _ in enumerate(gameDoors) if c != inputUser and c != other_wrong_door)
But honestly this merits a re-examining of your code's structure. Give me a few minutes to work something up, and I'll edit this answer to give you an idea of how I'd implement this.
import random
DOORS = [1, 0, 0]
def runonce(switch=False):
user_choice = random.choice(DOORS)
if user_choice == 1:
# immediate winner
if switch:
# if you won before and switch doors, you must lose now
return False
else:
new_doors = [0, 0] # remove the user-selected winner
new_doors = [0] # remove another loser
return bool(random.choice(new_doors))
# of course, this is always `0`, but
# sometimes it helps to show it. In production you
# wouldn't bother writing the extra lines and just return False
else:
if switch:
new_doors = [1, 0] # remove the user-selected loser
new_doors = [1] # remove another loser
return bool(random.choice(new_doors))
# as above: this is always True, but....
else:
return False # if you lost before and don't switch, well, you lost.
num_trials = int(input("How many trials?"))
no_switch_raw = [run_once(switch=False) for _ in range(num_trials)]
switch_raw = [run_once(switch=True) for _ in range(num_trials)]
no_switch_wins = sum(1 for r in no_switch_raw if r)
switch_wins = sum(1 for r in switch_raw if r)
no_switch_prob = no_switch_wins / num_trials * 100.0
switch_prob = switch_wins / num_trials * 100.0
print( " WINS LOSSES %\n"
f"SWITCH: {switch_wins:>4} {num_trials-switch_wins:>6} {switch_prob:.02f}\n"
f"NOSWITCH:{no_switch_wins:>4} {num_trials-no_switch_wins:>6} {no_switch_prob:.02f}")
You have gotten the mechanics of the problem wrong so you are getting the wrong result. I have rewritten the choice mechanics, but I am leaving the user input stuff to you so that you can continue to learn python. This is one of many ways to solve the problem, but hopefully it demonstrates some things to you.
def get_choices():
valid_choices = [0, 1, 2] # these are the values for a valid sample
shuffle(valid_choices) # now randomly shuffle that list
return valid_choices # return the shuffled list
def get_door(user_choice):
return user_choice.index(0)
def monty_sim(n, kind):
"""
:param n: number of runs in this simulation
:param kind: whether to change the door or not, 0 - don't change, 1 = change door
:return: (win_rate, 1 - win_rate)
"""
wins = 0
for i in range(0, n):
game_doors = get_choices()
user_choice = get_door(get_choices()) # use the same method and find user door choice
# so there are two branches.
# In both, a door with a goat (game_door = 1) is chosen, which reduce the result to
# a choice between two doors, rather than 3.
if kind == 0:
if user_choice == game_doors.index(0):
wins += 1
elif kind == 1:
# so now, the user chooses to change the door
if user_choice != game_doors.index(0):
wins += 1
# Because the original choice wasn't the right one, then the new
# must be correct because the host already chose the other wrong one.
win_rate = (wins / n) * 100
return win_rate, 100 - win_rate
if __name__ == '__main__':
n = 1000
kind = 1
wins, loses = monty_sim(n, kind)
print(f'In a simulation of {n} experiments, of type {kind} user won {wins:02f} of the time, lost {loses:02f} of the time')

Monty Hall-Not Running

I'm not sure what seems to be the problem with my code, I need some help. When I try running my program, it says invalid syntax next to my first if, I thought I may be an indentation error but nothing is working.
Here is my code:
import random
def montyHall():
car = random.randint(1,3)
guess1 = random.randint(1,3)
for i in range(1,3):
if ((not(i == car) and not(i == guess1)):
return i
newGuess = not(i) and not(guess1)
if (newGuess == car):
stay = True
elif (guess1 == car):
switch = False
return strategyOne
NUM_OF_TRIALS = 1000
stay = 0
switch = 0
for i in range(NUM_OF_TRIALS):
if(montyHall()):
stay += 1
else:
switch += 1
print("Staying wins", stay/NUM_OF_TRIALS, "% of the time")
print("Switching wins", switch/NUM_OF_TRIALS, "% of the time")
To many brackets and you do not need brackets in python.
Try changing:
if ((not(i == car) and not(i == guess1)):
to
if i != car and i != guess1:

Categories

Resources