I guess this must be some simple fix, but I am still becoming familiar with coding, so every once in a while I get stuck in some silly things (will catch up, eventually lol)
I have been trying to stop my Tic Tac Toe game once a winning condition is met (horizontal, vertical or diagonal), and I successfully have the message of the winner printed on the screen once one of conditions is met.
The thing is that after showing the message, I still can't stop the game. I would like to know what's the problem with my interruption.
This is the code I am using for the function that sets the symbols and that identifies the winner:
def player_char():
marker = ''
player1 = ''
player2 = ''
# Keep asking Player 1 to choose X or O, until entry is correct:
while marker != ('x').lower() and marker != ('o').lower():
marker = input("\n PLAYER 1 - CHOOSE X OR O : ")
# Assign opposite marker to Player 2
player1 = marker.upper()
if player1 == 'X':
player2 = 'O'
else:
player2 = 'X'
print (f"\n P1 playing with: {player1}" + f"\n P2 playing with: {player2}")
markers = [player1, player2]
return markers
def check_victory(board, markers):
player1_win = False
player2_win = False
draw = False
# Check if players win the game in one of the lines, columns or diagonals available
for n in range(len(markers)):
if board[7] == board[8] == board[9] == markers[n]:
if n == 0:
player1_win = True
else:
player2_win = True
break
(I HAVE IMPLEMENTED ALL THE OTHER LINES AND COLUMNS THAT COULD BE A WIN. DID NOT PASTE THEM HERE TO MAKE QUESTION SHORTER, BUT THEY ALL FOLLOW THE LOGIC ABOVE)
I call the function while players are placing their markers and once one winning condition is met, I have the message printed:
if player1_win:
print("\n >>> GAME FINISHED! PLAYER 1 WINS!")
if player2_win:
print("\n >>> GAME FINISHED! PLAYER 2 WINS!")
But then the game is not interrupted (I was guessing it would be, due to my "break" after each condition). What could be going on within my IF ? As I said, guessing it must be pretty simple, but got stuck for now.
So this is my function that executes the game.
"display_board" was implemented to print the board, so I didn't add it here, because I am simply calling it and printing the board, it doesn't return anything else. "free" is a parameter to print a second board next to the actual game board, showing available slots for a play
def play_game(board, markers, winner):
moves = 1
while winner[0] or winner[1] or winner[2] != True:
if moves % 2 == 1:
display_board(game_board, free)
print(game_board)
p1 = (input("\n >>> ( P1 ) Enter number for your move: "))
board[position_p1] = markers[0]
moves += 1
check_victory(board, markers)
(Next play follows same format for player 2, when "moves" is a pair number. I can verify if player 2 wins, but obviously game does not stop too)
break in the inner if condition will just break out of that if condition.
Instead, you can have one more condition at the end which will check if any of the following condition is True, then break out of the for loop.
player1_win = True or player2_win = True or draw = True
Related
I've been working on a python game where the objective is to move x//2 Ts from the left to the right, and x//2 Fs from the right to the left. x is a user inputted odd integer.
There is a dash - between the two groups. The user is supposed to enter a number, n
and the program should move the F or T in place n to the empty space, the one with a dash. the Ts can only move 1 or 2 spaces to the right, and the Fs can only move 1 or 2 spaces to the left.
If the 2 spaces the F or T can move to are both occupied, the program will print "Invalid entry!" and will ask for n again. Now the place where the problem is is the undo option.
The game should be able to undo to the beginning. I created the list record. Now when I added the part where it gets the item, instead it created a new string (or something). I changed the program to print record but there's nothing wrong with it. Does anybody know whats happening? My code's below.
boardsize = int(input())
board = "T"*(boardsize//2)+"-"+"F"*(boardsize//2)
finish = "F"*(boardsize//2)+"-"+"T"*(boardsize//2)
record = [board]
moves = 0
shouldpass = False
print("\n"+board, end = "")
while board != finish:
move = int(input())-1
if move == -1 and moves>0:
board = record[moves-1]
moves -= 2
shouldpass = True
while (move<0 or move>=boardsize) or (board[move]=="T" and move+1!=board.find("-") and move+2!=board.find("-")) or (board[move]=="F" and move-1!=board.find("-") and move-2!=board.find("-")) or (board[move]=="-"):
if shouldpass:
break
move = int(input("\nInvalid entry!\n"))-1
moves+=1
board = list(board)
board[board.index("-")] = board[move]
board[move] = "-"
board = "".join(board)
print("\n")
print(board)
print("Number of moves:\n"+str(moves))
record.append(board)
print("\nYou win!")
I recently started taking a python class and we are currently working on a project based off the game Connect Four. I have almost everything done except for 2 bugs I can not seem to find a solution to. The following code should allow 2 players (Red and Yellow) to drop a "coin" or pop a "coin". However, Red player always goes first (which my code already does allow) but when the player is asked if they want to drop(d) or pop(p) a coin and they mistype "d" or "p" the program skips the current players turn BUT when the coin is dropped(d) the other color is still reflected.
Also when one of the players has won, the program keeps going and would ask the following player to drop or pop a coin and then it will end.
In this picture, you can see how its yellows turn and they drop(d) in column 2 the coin(Y) drops. Then its player Reds turn and they mistype drop(d) it gives them a warning and then when asked the same question the player name is skipped to Yellow BUT when the player drops(d) a coin it is still reds coin(r). Then, after the coin is dropped technically it would be player Yellow but the name appears to red but the coin will still drop in "Y".
Here is a section of my program. This is the section of my program is where I am struggling in:
def play(game: GameState, col_len: int) -> None:
while winner(game) == 0:
while True:
for player in itertools.cycle(['Red', 'Yellow']):
move = input(player + ' Drop (D) or Pop(P): ')
if move.upper() == 'D':
try:
col = int(input(f'Column(1-{col_len}): '))
game = drop(game, col - 1)
print(f'Success! Drop column {col}')
display_board(game.board)
except ValueError:
print('Invalid! Out of range.')
col = int(input(f'try again! Column(1-{col_len}): '))
elif move.upper() == 'P':
try:
col = int(input(f'Column(1-{col_len}): '))
game = pop(game, col - 1)
print(f'Success! Pop column {col}')
display_board(game.board)
except ValueError:
print('Invalid! Out of range.')
col = int(input(f'try again! Column(1-{col_len}): '))
else:
print('Wrong movement! Try again.')
print('Winner Red' if winner(game) == 1 else 'Winner Yellow' if winner(game) == 2 else 'Empty')
I was requested to improve my player vs. player tic-tac-toe to an AI tic-tac-toe in which the player plays against the computer:
to do this I need to write two functions:
one that gets the board and the symbol of the current player and returned a list of all possible future boards - each future board is a list that contains two elements: one is the place that the symbol was placed in and the other is the board after placing the symbol - the board after one turn (I am using a nested list board as can be seen in the code below (in which I received help, here)
The second function I need is a function which does the computers turn - it uses the first function and picks an optimal move in one of the following ways:
picks a random move (just for the beginning, if the computer goes first) and plays it
OR
if the computer can win in the next turn he picks and plays this option
AND
if the player can win in the next turn the computer should "block" him.
what I have is a player vs player tic-tac-toe
code:
def get_move(whoseturn, board):
rowloc=int(input(f'{whoseturn},insert the deserved row to place your symbol: '))
coloc=int(input(f'{whoseturn} insert the deserved column to place your symbol: '))
while True:
if not (0 <= rowloc < 3 and 0 <= coloc < 3):
print('row and column must be 0, 1, or 2')
rowloc = int(input(f'{whoseturn},insert the deserved row to place your symbol: '))
coloc = int(input(f'{whoseturn} insert the deserved column to place your symbol: '))
elif board[rowloc][coloc] !='e':
print("The deserved place is taken, choose again ")
rowloc = int(input(f'{whoseturn},insert the deserved row to place your symbol: '))
coloc = int(input(f'{whoseturn} insert the deserved column to place your symbol: '))
else:
board[rowloc][coloc] = whoseturn
break
return rowloc, coloc
def display_board(board):
print('\n'.join([' '.join(board[i]) for i in range(3)]))
def win(board, whoseturn, x, y):
if board[0][y] == board[1][y] == board [2][y] == whoseturn:
return True
if board[x][0] == board[x][1] == board [x][2] == whoseturn:
return True
if x == y and board[0][0] == board[1][1] == board [2][2] == whoseturn:
return True
if x + y == 2 and board[0][2] == board[1][1] == board [2][0] == whoseturn:
return True
return False
def isfull(board):
for i in range(0,3):
for j in range(0,3):
if board[i][j]=='e':
return False
return True
def main():
board = [['e','e','e']
,['e','e','e']
,['e','e','e']]
print("Welcome to the great tic tac toe game!")
player1=input("Player 1, select your symbol (X/O): ")
if player1 =='O':
print('X is player 2s symbol')
player2 = 'X'
else:
print('O is player 2s symbol')
player2 = 'O'
print("Player 1 will start")
whoseturn=player1
while True:
display_board(board)
rowloc, coloc = get_move(whoseturn, board)
if win(board,whoseturn, rowloc, coloc):
print(f'{whoseturn} wins!')
display_board(board)
break
if isfull(board):
print('Tied')
break
if whoseturn=='O':
whoseturn='X'
else:
whoseturn='O'
if __name__ == '__main__':
main()
and a start of the future boards function
code:
def futuremove(board,whoseturn):
newboard=copy.deepcopy(board)
place = []
copyboard = []
arrangement=[]
final=[]
for i in range(3):
for j in range(3):
if newboard[i][j]=='e':
newboard[i][j]=whoseturn
if win(newboard,whoseturn,i,j)==True:
loctup=[i,j]
place.append(loctup)
copyboard.append(newboard)
arrangement.append(place)
arrangement.append(copyboard)
final.append(arrangement)
print(final)
else:
break
please help me get a working player vs. computer tic-tac-toe game!
any help will be very much appreciated!
There are a lot of different ways you can approach it, one fairly simple approach you might take would be to utilize the Minimax Algorithm
In a simple example, where your program looks only one turn ahead, after the play makes a move, your AI would generate a board for every possible move it could make, and from those moves, every possible counter move that the player could make.
Now you want to assign a score to each of the AI's possible moves, how you want to define the scoring algorithm is up to you, but it should represent how good or bad a particular game state is for your AI.
The score of each of the AI's potential moves should be equal to the worst score of all the player's counter moves, because we want to assume that the player will act in their best interest.
As such you'll be able to determine which of the AI's potential moves puts it in the best chance of winning the game from the current state. I highly recommend reading the attached article for implementation details and a deeper understanding.
Hy guys i have the following problem - Write a program to play the following simple game. The player starts with $100. On each
turn a coin is flipped and the player has to guess heads or tails. The player wins $9 for each
correct guess and loses $10 for each incorrect guess. The game ends either when the player
runs out of money or gets to $200.
My program is actually running. However when players points go bellow zero my program still runs and that is not what i expected. I need to know if there is something that i can do in my if sentences or if there is an easier way to make statements when i have to much conditions.
import random
list=['heads','tails']
def game():
p1=100
p2=100
while (p1>0 or p2>0)and(p1<200 or p2<200):
x=random.choice(list)
x1=input('digit your guess player1 - ')
x2=input('digit your guess player2 - ')
if x1==x:
p1+=30
else:
p1=p1-40
if x2==x:
p2+=30
else:
p2=p2-40
return p1,p2
print(game())
I expect the program to return the scores and end if any player points goes above 200 or bellow 0
If I consider your original problem, the problem is that you are returning whatever current value the player has, instead you should remember the last score and if the condition you want the game to stop on happens, return the last score. This will ensure only valid scores are returned
import random
list=['heads','tails']
def game():
player=100
last_score = 0
#Conditions to break while loop
while player > 0 and player < 200:
#Keep track of last score
last_score = player
#Get choice from player, and increase/decrease score
x=random.choice(list)
x1=input('digit your guess player1 - ')
if x1 == x:
player += 9
else:
player -= 10
#Return last score
return last_score
print(game())
Extending this idea to the 2 player game will solve your issue as well!
import random
list=['heads','tails']
def game():
p1=100
p2=100
last_scores = 0,0
# Conditions to break while loop
while (0<p1<200) and(0<p2<200):
# Keep track of last score
last_scores = p1,p2
# Get choice from player, and increase/decrease score
x=random.choice(list)
x1=input('digit your guess player1 - ')
x2=input('digit your guess player2 - ')
if x1==x:
p1+=30
else:
p1=p1-40
if x2==x:
p2+=30
else:
p2=p2-40
return last_scores
print(game())
Change the while condition to:
while p1>0 and p2>0 and p1<200 and p2<200
but it is more readable if:
while 0<p1<200 and 0<p2<200
I am simulating a game in python. It involves two players, each has a set of turns. Based on a hit or a miss, we decide if that player will get another turn.
I not able to craft this logic programmatically, here is what I have so far:
Let's simulate each player separately for the sake of simplicity
for coordinate in list_of_player1_moves:
result = fire(coordinate[0], coordinate[1])
#result is either a 'Hit' or a 'Miss'
for coordinate in list_of_player2_moves:
result = fire(coordinate[0], coordinate[1])
#result is either a 'Hit' or a 'Miss'
Now, in order to have individual turns for each player, I did:
turns = len(list_of_player2_moves) if len(list_of_player2_moves) > len(list_of_player1_moves) else len(list_of_player1_moves)
for turn in range(0, turns):
r = move_player1(turn) #move player inturn calls fire()
if(r == 'Hit'):
break #start over, giving them another turn
r = move_player2(turn)
if r == 'Hit':
#how do give player 2 another turn?
I am out of ideas on how to approach this further. Please suggest. Also please advice on alternative/better approaches.
Thanks!
Edit:
Sample Output for better understanding,
Player1 fires got miss
Player2 fires which got hit
Player2 fires which got miss
Player1 fires which got hit
Player1 fires which got hit
Player1 fires which got miss
Player2 fires which got miss
Player1 has no more missiles left to launch
Player2 fires which got hit
Player2 fires which got miss
Player1 has no more missiles left to launch
Player2 fires which got miss
Player1 has no more missiles left to launch
Player2 fires which got hit
Player2 fires which got miss
Player1 no more missiles left to launch
Player2 fires which got hit
Player2 won the battle
Your problem description is a bit ambiguous, so I am assuming that
Every time a player hits another player, he gets 1 more move
The game doesn't terminate until both of the players run out of moves
Thus I rewrote the function
counter = 0
no_of_player1_moves = len(list_of_player1_moves)
no_of_player2_moves = len(list_of_player2_moves)
while counter < no_of_player1_moves or counter < no_of_player2_moves:
# won't terminate until both players run out of turns
r = move_player1(turn)
if(r == 'Hit'):
no_of_player1_moves += 1 #if player1 hits, player1 gets 1 more turn
r = move_player2(turn)
if(r == 'Hit'):
no_of_player2_moves += 1 #if player2 hits, player2 gets 1 more turn
counter += 1
P.S:
Instead of your long statement
turns = len(list_of_player2_moves) if len(list_of_player2_moves) > len(list_of_player1_moves) else len(list_of_player1_moves)
You can simply use
turns = max(len(list_of_player2_moves),len(list_of_player1_moves))
Edit:
no_of_player1_moves = len(list_of_player1_moves)
no_of_player2_moves = len(list_of_player2_moves)
while no_of_player1_moves>0 or no_of_player2_moves>0:
# won't terminate until both players run out of turns
while move_player1(turn)=="Hit" and no_of_player1_moves!=0:
no_of_player1_moves -= 1
while move_player2(turn)=="Hit" and no_of_player2_moves!=0:
no_of_player2_moves -= 1
This would probably solve your problem, but the design doesn't scale well (imagine if you have 10 players, you wouldn't want to write it 10 times).
For that, I would suggest creating a Player object, and placing them in a list, then keep cycling through the list (nested while loop) until all players run out of moves. There is probably a better solution out there too (even compared to this), but that would at least be scalable.