i wrote a "tic tac toe" game in python(pycharm). At the end of the game i asked the user if he wants to play again: if he pressed 'y' the game began again, and if he pressed 'n' the game/code stopped. do you know how can i show him an error massege like: "you entered a wrong answer! please try again:" when he doesn't press any of this letters but somthing else? for example:
"Would you like to play again? "fnj"(his answer). And show this massage until he enter a correct answer?
class color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
def playTicTacToe():
rows,cols = 3,3
winLength = 3
board = makeNewBoard(rows, cols)
moves = 0
player = 1
while moves < rows*cols:
row,col = getMove(board, player)
board = setPiece(board, row, col, player)
if (didWin(board, player, winLength)):
printBoard(board)
print ""
#print '%s The Player %s color.GREEN + color.Bold + "-->" + color.END, """ IS THE WINNER OF THE GAME!!!""" + color.END % (color.GREEN,getPieceLabel(player),
print color.RED + color.BOLD + "The Player" + color.END, getPieceLabel(player), color.RED + color.BOLD + "IS THE WINNER OF THE GAME!!! " + color.END
return
player = otherPlayer(player)
moves += 1
print color.RED + color.BOLD + "TIE GAME!" + color.END
def makeNewBoard(rows, cols):
return [([0]*cols) for row in xrange(rows)]
def getRows(board):
return len(board)
def getCols(board):
return len(board[0])
def getPiece(board, row, col):
return board[row][col]
def setPiece(board, row, col, value):
board[row][col] = value
return board
def isEmpty(board, row, col):
return (getPiece(board, row, col) == 0)
def isOnBoard(board, row, col):
rows = getRows(board)
cols = getCols(board)
return ((row >= 0) and (row < rows) and
(col >= 0) and (col < cols))
def getPieceLabel(piece):
if (piece == 1):
return "|" + color.PURPLE + color.BOLD + "X" + color.END + "|"
elif (piece == 2):
return "|" + color.BLUE + color.BOLD + "O" + color.END + "|"
else:
return color.BOLD + "|_|" + color.END
def printBoard(board):
print "\n-----------------------------------------------------------------------------------------------------------"
rows = getRows(board)
cols = getCols(board)
for row in xrange(rows):
for col in xrange(cols):
piece = getPiece(board, row, col)
label = getPieceLabel(piece)
print label,
print
def didWin(board, player, winLength):
rows = getRows(board)
cols = getCols(board)
for startRow in xrange(rows):
for startCol in xrange(cols):
if (didWin1(board, player, winLength, startRow, startCol)):
return True
return False
def didWin1(board, player, winLength, startRow, startCol):
for drow in xrange(-1,+2):
for dcol in xrange(-1,+2):
if ((drow != 0) or (dcol != 0)):
if (didWin2(board, player, winLength,
startRow, startCol, drow, dcol)):
return True
return False
def didWin2(board, player, winLength,
startRow, startCol, drow, dcol):
rows = getRows(board)
cols = getCols(board)
for step in xrange(winLength):
row = startRow + step*drow
col = startCol + step*dcol
if (not isOnBoard(board, row, col)):
return False
elif (getPiece(board, row, col) != player):
return False
return True
def otherPlayer(player):
return 1 if (player == 2) else 2
def oops(msg):
print " ", msg, color.RED + color.BOLD + "Try again." + color.END
def readInt(prompt):
while True:
try:
return int(raw_input(prompt))
except:
oops(color.RED + color.BOLD + "Input must be an integer." + color.END)
def getMove(board, player):
while True:
printBoard(board)
print "Enter move for player:" + getPieceLabel(player)
row = readInt(" Row --> ") - 1
col = readInt(" Col --> ") - 1
if (not isOnBoard(board, row, col)):
oops(color.RED + color.BOLD + """\n \n Out of range (not on the board)!""" + color.END)
elif (not isEmpty(board, row, col)):
oops(color.RED + color.BOLD +"""\n Already occupied!""" + color.END)
else:
return (row, col)
def finish():
answer = raw_input(color.PURPLE + color.BOLD + """Would you like to play again?! (press \'y\' for yes and \'n\' for no):""" + color.END)
if answer.lower() == "n":
print ""
print color.BLUE + color.BOLD + "Bye Bye! See you next time! :)" + color.END
return True
if answer.lower() == "y":
print (color.BLUE + color.BOLD + """\nGreat choice! The game will start again""" + color.END)
return False
def main():
while True:
playTicTacToe()
if finish():
break
if __name__ == '__main__':
main()
You can modify the finish function as follows:
def finish():
while True:
answer = raw_input(color.PURPLE + color.BOLD + """Would you like to play again?! (press \'y\' for yes and \'n\' for no):""" + color.END)
if answer.lower() == "n":
print ""
print color.BLUE + color.BOLD + "Bye Bye! See you next time! :)" + color.END
return True
elif answer.lower() == "y":
print (color.BLUE + color.BOLD + """\nGreat choice! The game will start again""" + color.END)
return False
else:
print 'Not valid input...'
By this way the program ignores invalid inputs and asks the user again.
PS. I would suggest to insert a mechanism for exiting before the completion of the game in the case the user wants to terminate the game.
if answer.lower() == "n":
print color.BLUE + color.BOLD + "Bye Bye! See you next time! :)" + color.END
return True
elif answer.lower() == "y":
print (color.BLUE + color.BOLD + """\nGreat choice! The game will start again""" + color.END)
return False
else:
print (color.BLUE + color.BOLD + """\nyou entered a wrong answer! please try again:""" + color.END)
return False
Related
I'm a beginner (somewhat) in Python. In my Tic Tac Toe Game, I'm stuck at the winner(board) function, because whenever I run the program and place an X anywhere, it immediately says "Y O U W O N !" When I removed the code under the make_computer_move(board) to try and debug my winner(board) function, the diagonal from the top right to bottom left doesn't work, but the top left to bottom right winner determination code works. Here is my code below:
"""
Author: Victor Xu
Date: Jan 12, 2021
Description: An implementation of the game Tic-Tac-Toe in Python,
using a nested list, and everything else we've learned this quadmester!
"""
import random
def winner(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
If there is no winner, the function will return the empty string "".
If the user has won, it will return 'X', and if the computer has
won it will return 'O'."""
# Check rows for winner
for row in range(3):
if (board[row][0] == board[row][1] == board[row][2]) and \
(board[row][0] != " "):
return board[row][0]
# COMPLETE THE REST OF THE FUNCTION CODE BELOW
for col in range(3):
if (board[0][col] == board[1][col] == board[2][col]) and \
(board[0][col] != " "):
return board[0][col]
# Check diagonal (top-left to bottom-right) for winner
if (board[0][0] == board[1][1] == board[2][2]) and \
(board[0][0] != " "):
return board[0][0]
# Check diagonal (bottom-left to top-right) for winner
if (board[0][2] == board[1][1] == board[2][0]) and \
(board[0][0] != " "):
return board[0][0]
# No winner: return the empty string
return ""
def display_board(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will print the Tic-Tac-Toe board grid (using ASCII characters)
and show the positions of any X's and O's. It also displays
the column and row numbers on top and beside the board to help
the user figure out the coordinates of their next move.
This function does not return anything."""
print(" 0 1 2")
print("0: " + board[0][0] + " | " + board[0][1] + " | " + board[0][2])
print(" ---+---+---")
print("1: " + board[1][0] + " | " + board[1][1] + " | " + board[1][2])
print(" ---+---+---")
print("2: " + board[2][0] + " | " + board[2][1] + " | " + board[2][2])
print()
def make_user_move(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will ask the user for a row and column. If the row and
column are each within the range of 0 and 2, and that square
is not already occupied, then it will place an 'X' in that square."""
valid_move = False
while not valid_move:
row = int(input("What row would you like to move to (0-2):"))
col = int(input("What col would you like to move to (0-2):"))
if (0 <= row <= 2) and (0 <= col <= 2) and (board[row][col] == " "):
board[row][col] = 'X'
valid_move = True
else:
print("Sorry, invalid square. Please try again!\n")
def make_computer_move(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will randomly pick row and column values between 0 and 2.
If that square is not already occupied it will place an 'O'
in that square. Otherwise, another random row and column
will be generated."""
computer_valid_move = False
while not computer_valid_move:
row = random.randint(0, 2)
col = random.randing(0, 2)
if (0 <= row <= 2) and (0 <= col <= 2) and (board[row][col] == " "):
board[row][col] = 'O'
computer_valid_move = True
def main():
"""Our Main Game Loop:"""
free_cells = 9
users_turn = True
ttt_board = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
while not winner(ttt_board) and (free_cells > 0):
display_board(ttt_board)
if users_turn:
make_user_move(ttt_board)
users_turn = not users_turn
else:
make_computer_move(ttt_board)
users_turn = not users_turn
free_cells -= 1
display_board(ttt_board)
if (winner(ttt_board) == 'X'):
print("Y O U W O N !")
elif (winner(ttt_board) == 'O'):
print("I W O N !")
else:
print("S T A L E M A T E !")
print("\n*** GAME OVER ***\n")
# Start the game!
main()
TL;DR
Please check out the top right to bottom left diagonal win determination code and the issue whenever I place down an X and it says "YOU WON!"
Your bottom-left to top-right diagonal check is wrong. You're checking that the correct diagonal elements are equal to each other, but then you check the wrong corner element to see if it's not a space. It should be:
# Check diagonal (bottom-left to top-right) for winner
if (board[0][2] == board[1][1] == board[2][0]) and \
(board[0][2] != " "):
return board[0][2]
First: I see you have a typo ("randing", I guess it was randint again as the previous line?
Second: The code runs fine here up until the point where I have placed my first X where everything crashes (AttributeError: 'module' object has no attribute 'randing' due to the randing error)
Third: After changing the typo for you, I finished the game and won against the machine (luckily, until you/someone (hehe I might have once) implement AI in the game).
Best of luck ahead with Python, it's such a fun language but hard when something goes wrong.
Regards
For a class project, my groupmates and I are to code a tic tac toe program. So far, this is what we have. All of us have 0 experience in python and this is our first time actually coding in python.
import random
import colorama
from colorama import Fore, Style
print(Fore.LIGHTWHITE_EX + "Tic Tac Toe - Below is the key to the board.")
Style.RESET_ALL
player_1_pick = ""
player_2_pick = ""
if (player_1_pick == "" or player_2_pick == ""):
if (player_1_pick == ""):
player_1_pick = "Player 1"
if (player_2_pick == ""):
player_2_pick = "Player 2"
else:
pass
board = ["_"] * 9
print(Fore.LIGHTBLUE_EX + "0|1|2\n3|4|5\n6|7|8\n")
def print_board():
for i in range(0, 3):
for j in range(0, 3):
if (board[i*3 + j] == 'X'):
print(Fore.RED + board[i*3 + j], end = '')
elif (board[i*3 + j] == 'O'):
print(Fore.BLUE + board[i*3 + j], end = '')
else:
print(board[i*3 + j], end = '')
print(Style.RESET_ALL, end = '')
if j != 2:
print('|', end = '')
print()
print_board()
while True:
x = input('Player 1, pick a number from 0-8: ') #
x = int(x)
board[x] = 'X'
print_board()
o = input('Player 2, pick a number from 0-8:')
o = int(o)
board[o] = 'O'
print_board()
answer = raw_input("Would you like to play it again?")
if answer == 'yes':
restart_game()
else:
close_game()
WAYS_T0_WIN = ((0,1,2)(3,4,5)(6,7,8)(0,3,6)(1,4,7)(2,5,8)(0,4,8)(2,4,6))
We're stuck on how to have the program detect when someone has won the game and then have it print "You won!" and also having the program detect when it's a tie and print "It's a tie!". We've looked all over the internet for a solution but none of them work and we can't understand the instructions. No use asking the teacher because they don't know python or how to code.
I have changed your code in such a way that first of all "save players choices" and in second "check if a player won and break the loop":
import random
import colorama
from colorama import Fore, Style
print(Fore.LIGHTWHITE_EX + "Tic Tac Toe - Below is the key to the board.")
Style.RESET_ALL
player_1_pick = ""
player_2_pick = ""
if (player_1_pick == "" or player_2_pick == ""):
if (player_1_pick == ""):
player_1_pick = "Player 1"
if (player_2_pick == ""):
player_2_pick = "Player 2"
else:
pass
board = ["_"] * 9
print(Fore.LIGHTBLUE_EX + "0|1|2\n3|4|5\n6|7|8\n")
def print_board():
for i in range(0, 3):
for j in range(0, 3):
if (board[i*3 + j] == 'X'):
print(Fore.RED + board[i*3 + j], end = '')
elif (board[i*3 + j] == 'O'):
print(Fore.BLUE + board[i*3 + j], end = '')
else:
print(board[i*3 + j], end = '')
print(Style.RESET_ALL, end = '')
if j != 2:
print('|', end = '')
print()
def won(choices):
WAYS_T0_WIN = [(0,1,2), (3,4,5), (6,7,8), (0,3,6), (1,4,7), (2,5,8), (0,4,8), (2,4,6)]
for tpl in WAYS_T0_WIN:
if all(e in choices for e in tpl):
return True
return False
print_board()
turn = True
first_player_choices = []
second_player_choices = []
while True:
if turn:
x = input('Player 1, pick a number from 0-8: ') #
x = int(x)
if board[x] == '_':
board[x] = 'X'
first_player_choices.append(x)
turn = not turn
print_board()
if won(first_player_choices):
print('Player 1 won!')
break
else:
print('Already taken! Again:')
continue
else:
o = input('Player 2, pick a number from 0-8: ') #
o = int(o)
if board[o] == '_':
board[o] = 'O'
second_player_choices.append(o)
turn = not turn
print_board()
if won(second_player_choices):
print('Player 2 won!')
break
else:
print('Already taken! Again:')
continue
# answer = input("Would you like to play it again?")
# if answer == 'yes':
# restart_game()
# else:
# close_game()
I also added a condition to check if players choice is already taken! By the way, you can do it way much better. :)
EDIT: there was a little problem with spaces in my answer here and I solve it in edit. Now you can directly copy it in a py file and run it!
Firstly, you need a condition which doesn't allow the same space to be allocated twice, when test running I could type space 3 as much as I wanted for example without it stopping me. You need some sort of check for this.
Secondly, for the actual win system, you made it easy because you already have the co-ordinates for all of the winning games, I recommend something along the lines of:
def checkwin(team):
for i in WAYS_TO_WIN:
checked = False
while not checked:
k = 0
for j in i:
if board[j] == team:
k+=1
if k == 3:
return True
checked = True
This way is checks if any of the co-ordinates have all 3 of any set. You might have to adjust this code, but this looks like a solution.
Note: I'm still a beginner at coding and I stumbled upon your thread, this is an idea not necessarily a working solution
tl;dr output all is in blue for tic tac toe, only want x as blue and o as red
In class we're trying to make a tic tac toe game and currently we're trying to modify the code in such a way that only X is blue and O is red however when we import colorama it colors all of the output. I am aware that all of the text will print in blue. So essentially it should look like:
I've also provided the code for the game.
import random
import colorama
from colorama import Fore, Style
print(Fore.BLUE + "Hello World")
player_1_pick = ""
player_2_pick = ""
if (player_1_pick == "" or player_2_pick == ""):
if (player_1_pick == ""):
player_1_pick = "Player 1"
if (player_2_pick == ""):
player_2_pick = "Player 2"
else:
pass
board = ["_"] * 9
def print_board():
print(board[0] + '|' + board[1] + '|' + board[2])
print(board[3] + '|' + board[4] + '|' + board[5])
print(board[6] + '|' + board[7] + '|' + board[8])
print_board()
if (random.randint(1,2) == 1):
player_1_pick = input(player_1_pick + ", choose X or O: ").upper()
if (player_1_pick == "X"):
player_2_pick = "O"
while True:
x = input('Pick a number from 0-8')
x = int(x)
board[x] = 'X'
print_board()
Then we decided to open another tab of python (we're using repl.it) to try and fix the problem in an isolated environment, in which we came up with:
import random
import colorama
from colorama import Fore, Style
def getPieceLabel(piece):
if (piece == 1):
return "|" + color.PURPLE + color.BOLD + "X" + color.END + "|"
elif (piece == 2 ):
return "|" + color.BLUE + color.BOLD + "O"
+ "|"
else:
return color.BOLD + "|_|" + color.END
board = ["_"] * 9
def print_board():
print(board[0] + '|' + board[1] + '|' + board[2])
print(board[3] + '|' + board[4] + '|' + board[5])
print(board[6] + '|' + board[7] + '|' + board[8])
print(Style.RESET_ALL)
while True:
x = input('Pick a number from 0-8')
x = int(x)
board[x] = 'X'
print_board()
We need some help figuring this out/what the problem is.
Here is a code that works for printing different color for different items (tested on repl.it too!).
import random
import colorama
from colorama import Fore, Style
print(Fore.BLUE + "Tic Tac Toe")
Style.RESET_ALL
player_1_pick = ""
player_2_pick = ""
if (player_1_pick == "" or player_2_pick == ""):
if (player_1_pick == ""):
player_1_pick = "Player 1"
if (player_2_pick == ""):
player_2_pick = "Player 2"
else:
pass
board = ["_"] * 9
def print_board():
for i in range(0, 3):
for j in range(0, 3):
if (board[i*3 + j] == 'X'):
print(Fore.BLUE + board[i*3 + j], end = '')
elif (board[i*3 + j] == 'O'):
print(Fore.RED + board[i*3 + j], end = '')
else:
print(board[i*3 + j], end = '')
print(Style.RESET_ALL, end = '')
if j != 2:
print('|', end = '')
print() # new line
print_board()
if (random.randint(1,2) == 1):
player_1_pick = input(player_1_pick + ", choose X or O: ").upper()
if (player_1_pick == "X"):
player_2_pick = "O"
while True:
x = input('Pick a number from 0-8: ')
x = int(x)
board[x] = 'X'
print_board()
Why? When you use Back.RED or Fore.RED, it just changes the global output color (and not just that particular print() statement). That means you must change color for every to-be-printed item if you want them in different colors. That's what I did under print_board().
Since you're printing a 3x3 matrix (or 2D array) along with borders between the elements or items, I had to make use of two loops to print each of them in different colors (as required).
Note: The program works, but I think there is some missing logic since the game only works for 1st player; there is no second player (or even a system player). It's out of the scope for this answer.
i have a problem with creating a dict in python.
In my mainloop i call function 1 which should creat an empty dict.
function 1 calls function 2.
function 2 calls itself (loop through a game tree)
but i can not use the dict i created in f1.
and it is not possible to pass it as agrument.
i would like to have the dict globaly accessible
def f1(): # function 1
#test_dict = {} # this needs to be global scope
#test_dict["key"] = "value"
test_dict["key2"] = "value2"
print (test_dict)
f2()
def f2(): # function 2
# here starts a loop that calls f2 again and again -> global dict is needed
# dict needs to be created
print (test_dict)
test_dict = {} # only works without errors when i create it before calling f1
test_dict["key"] = "value"
f1()
Here is my "real" Code :)
The >>MinMaxComputerMove<< need to edit the dict.
but at the end of a nood i cant pass it because the for loop just goes on.
# [] [] []
# [] [] []
# [] [] []
#Input Layer:
#9 Punkte mit -1 (geg.) 0 (leer) 1 (eig.)
from time import sleep
from random import randint
from random import choice
from IPython.display import clear_output
def clearBoard():
board = [0] * 10
return (board)
def drawBoard(board, PlayerSymbol, ComputerSymbol, turn):
turn += 1
#clear_output()
Symbolboard = []
for index, value in enumerate(board):
if value == 1:
Symbolboard.append(PlayerSymbol)
elif value == -1:
Symbolboard.append(ComputerSymbol)
else:
Symbolboard.append(" ")
print ("Turn: " + str(turn))
print ("")
print (str(Symbolboard[7]) + " - " + str(Symbolboard[8]) + " - " + str(Symbolboard[9]))
print ("| \ | / |")
print (str(Symbolboard[4]) + " - " + str(Symbolboard[5]) + " - " + str(Symbolboard[6]))
print ("| / | \ |")
print (str(Symbolboard[1]) + " - " + str(Symbolboard[2]) + " - " + str(Symbolboard[3]))
return (validMoves(board), turn)
def validMoves(board):
#return list with valid indices
validMoveList = []
for index, value in enumerate(board):
if index > 0 and value == 0:
validMoveList.append(index)
return (validMoveList)
def Symbol():
#X always goes first
if randint(0, 1) == 0:
print ("X: YOU")
print ("O: COMPUTER")
return ("X"), ("O")
else:
print ("X: COMPUTER")
print ("O: YOU")
return ("O"), ("X")
def PlayerMove(validMoveList, PlayerSymbol):
PlayerInput = input("Welches Feld? (1-9):")
if int(PlayerInput) in validMoveList:
return (PlayerInput, PlayerSymbol)
else:
print("Falsche Eingabe." + PlayerInput + " kein möglicher Zug")
def ComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, AI):
print("ComputerMove")
if AI == 1:
return RandomComputerMove(validMoveList, ComputerSymbol)
elif AI == 2:
path_dict = {}
return MinMaxComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, depth = 1, firstrun = 1)
# more AIs
# ...
def ComputerThinking():
print("Computer is thinking", end = "")
sleep(0.5)
print(".", end = "")
sleep(0.5)
print(".", end = "")
sleep(0.5)
print(".")
sleep(1)
return
def RandomComputerMove(validMoveList, ComputerSymbol):
ComputerChoice = choice(validMoveList)
ComputerThinking()
print("ComputerChoice: " + str(ComputerChoice))
sleep(1.5)
print("RandomComputerMove Output: " + str((ComputerChoice, ComputerSymbol)))
return (ComputerChoice, ComputerSymbol)
def MinMaxComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, depth, firstrun = 0, start_path = -1):
initial_validMoveList = validMoveList.copy()
initial_board = board.copy()
turns_left = len(initial_validMoveList)
#debug
print("firstrun: " + str(firstrun))
print("depth: " + str(depth))
if firstrun == 1: #first run of function
path_dict = {}
for path, field in enumerate(initial_validMoveList):
path_dict[path] = {}
for extent in range(3):
path_dict[path][extent+1] = 5
#debug
print("---MinMaxComputerMove---")
print("Start MinMaxComputerMove with depth: " + str(depth))
print("validMoveList: " + str(validMoveList) + str(id(validMoveList)))
print("board: " + str(board) + str(id(board)))
print("ComputerSymbol: " + str(ComputerSymbol))
print("start_path: " + str(start_path))
for path, field in enumerate(initial_validMoveList): #(2, 6, 8):
if firstrun == 1:
start_path = path
print("start_path: " + str(start_path))
# for every path in tree diagram create a key in dict with empty list
# goal: dict("path": [field, depth_1_(max)value, depth_2_(min)value, depth_3_(max)value])
#debug
print("depth: " + str(depth))
if depth % 2 == 1: # Computer:
ChoosenIndex = (str(field), ComputerSymbol)
else: # Player
ChoosenIndex = (str(field), PlayerSymbol)
new_board = updateBoard(initial_board.copy(), ChoosenIndex, PlayerSymbol) # copy() or initial_board would change
new_validMoveList = validMoves(new_board)
#debug
print("---For Loop---")
print("ChoosenIndex: " + str(ChoosenIndex) + str(id(ChoosenIndex)))
print("new_validMoveList: " + str(new_validMoveList) + str(id(new_validMoveList)))
print("new_board: " + str(new_board) + str(id(new_board)))
print("path_dict: " + str(path_dict))
print("depth: " + str(depth))
if checkWinner(new_board) == 0 and depth != 3 and turns_left >= 1: # no winner yet and game not over
print ("no winner yet and game not over")
# go deeper
path_dict[start_path][depth] = 0
MinMaxComputerMove(new_validMoveList, new_board, PlayerSymbol, ComputerSymbol, depth + 1, 0, start_path)
elif checkWinner(new_board) == 0 and depth == 3 and turns_left >= 1: # no winner yet and game not over and minmax ends (depth = 3)
print ("checkWinner(new_board) == 0 and depth == 3 and turns_left >= 1")
path_dict[start_path][depth] = 0
elif checkWinner(new_board) == -1: # computer wins
print ("elif checkWinner(new_board) == -1")
if depth % 2 == 1: # Computer -> MIN:
path_dict[start_path][depth] <= -1
else: # Player -> MAX
if path_dict[start_path][depth] > -1:
path_dict[start_path][depth] = -1
elif checkWinner(new_board) == 1: # player wins
print ("elif checkWinner(new_board) == 1")
path_dict[start_path][depth] = 1
elif depth >= 3 or turns_left < 1: # reached depth 3 or no more turns
print ("elif depth >= 3 or turns_left < 1:")
else:
print ("else")
print("--- END FOR PATH ---")
print("--- END FOR LOOP ---")
print(path_dict)
# return choise
return (2, ComputerSymbol)
def updateBoard(board, ChoosenIndex, PlayerSymbol): #[0, 1, -1, 0, ...],[5, "X"], "X"
if PlayerSymbol == ChoosenIndex[1]:
board[int(ChoosenIndex[0])] = 1
return (board)
else:
board[int(ChoosenIndex[0])] = -1
return (board)
def checkWinner(board):
if (board[7] == board[8] == board[9]) and 0 != board[7]: # top row
return board[7]
elif (board[4] == board[5] == board[6]) and 0 != board[4]: # mid row
return board[4]
elif (board[1] == board[2] == board[3]) and 0 != board[1]: # bot row
return board[1]
elif (board[7] == board[4] == board[1]) and 0 != board[7]: # left column
return board[7]
elif (board[8] == board[5] == board[2]) and 0 != board[8]: # mid row
return board[8]
elif (board[9] == board[6] == board[3]) and 0 != board[9]: # right row
return board[9]
elif (board[7] == board[5] == board[3]) and 0 != board[7]: # diagonal \
return board[7]
elif(board[1] == board[5] == board[9]) and 0 != board[1]: # diagonal /
return board[1]
else:
return 0
def GameLoop(AI, turn = 0, winner = 0):
#choose AI difficulty
#...
#...
#set first player (X)
PlayerSymbol, ComputerSymbol = Symbol()
sleep(3)
#init board with list 10 * 0
board = clearBoard()
#debug
board = [0, 1, 0, 1, -1, -1, 0, 1, 0, -1]
PlayerSymbol, ComputerSymbol = ("O", "X") # computer first
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
while winner == 0 and turn <=9:
sleep(1.5)
if turn % 2 == 1: # "X" player move
if PlayerSymbol == "X":
#player move
ChoosenIndex = PlayerMove(validMoveList, PlayerSymbol)
#update current board
board = updateBoard(board, ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else:
#computer move
ChoosenIndex = ComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, AI)
#update current board
board = updateBoard(board,ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else: # "O" player move
if PlayerSymbol == "O":
#player move
ChoosenIndex = PlayerMove(validMoveList, PlayerSymbol)
#update current board
board = updateBoard(board,ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else:
#computer move
ChoosenIndex = ComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, AI)
#update current board
board = updateBoard(board,ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else:
if winner == 1:
print ("YOU WON!")
elif winner == -1:
print ("COMPUTER WON!")
else:
print ("DRAW!")
GameLoop(AI = 2)
The "return value" answer is:
def f1(test_dict): # function 1
#test_dict = {} # this needs to be global scope
#test_dict["key"] = "value"
test_dict["key2"] = "value2"
print ('In f1 {}'.format(test_dict))
f2(test_dict)
return test_dict
def f2(test_dict): # function 2
# here starts a loop that calls f2 again and again -> global dict is needed
# dict needs to be created
print ('In f2 {}'.format(test_dict))
return test_dict
test_dict = {} # only works without errors when i create it before calling f1
test_dict["key"] = "value"
test_dict = f1(test_dict)
which gives output of:
In f1 {'key2': 'value2', 'key': 'value'}
In f2 {'key2': 'value2', 'key': 'value'}
But at some level, you probably want to put some of this into a class and then have test_dict as a variable within the class. That allows f1 and f2 (assuming they are class methods) to access the class variable without passing it as a parameter to the two methods.
class Example:
def __init__(self):
self._test_dict = {}
self._test_dict["key"] = "value"
def f1(self): # function 1
self._test_dict["key2"] = "value2"
print ('In f1 {}'.format(self._test_dict))
self.f2()
def f2(self): # function 2
print ('In f2 {}'.format(self._test_dict))
example = Example()
example.f1()
Below is a very simply version of what your script is attempting. You need to consider what your function parameters should be (what is passed to the function), as well as what your function should be providing at the end of its execution (given to you with the return statement). This way you can manipulate objects without having to keep everything in global scope, and you can avoid having to initialize every conceivable variable at the start of the routine.
Python Functions
Return Statement
def f1():
f1_dict = {}
f1_dict = f2(f1_dict)
return f1_dict
def f2(dict_arg):
f2_dict = {}
for i in range(0,5):
f2_dict[str(i)] = i**i
return f2_dict
dictionary = f1()
print(dictionary)
I've wrote a code for the Tic-Tac-Toe game.
Here's what the code does:
Gets the name of Player 1.
Gets the name of Player 2.
Asks if the Player 1 wants X or O.
If he chooses X then Player 2 gets O and vice versa.
Prints the empty board.
Asks both players to enter the row and column one by one and prints the updated board.
If a player doesn't repeat previous player's spot, everything works fine until the end without any problem.
If a player repeats previous player's spot, a message is displayed saying that the previous player has already taken this spot and makes him guess again.
Now, after this point, if I guess any index other than the one that the previous player has already taken, it overwrites the previous players spot.
Screenshot of the terminal when this occurs:
I'm certain that the problem is in the function enterguess(turncount), but haven't been able to spot it yet. Any idea where the problem is?
<----------------------------------------------[ Demo Without the colors ]-------------------------------------------->
Code:
import termcolor
board = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
vb = termcolor.colored("|", "yellow", None, ['bold'])
s = termcolor.colored("\t+---+---+---+", "yellow", None, ['bold'])
players = {
'player1' : '',
'player2' : ''
}
sym = {
'player1': '',
'player2': ''
}
def rules ():
print("\nWelcome to Tic Tac Toe...")
def printboard():
#boardlist = [[" "," "," "],[" "," "," "],[" "," "," "]]
for row in board:
print s
print "\t" + vb + " " + row[0] + " " + vb + " " + row[1] + " " + vb + " " + row[2] + " " + vb
print s
def playerNames():
p1 = termcolor.colored(raw_input("\nEnter name of Player 1: ").title(), 'red', None, ['underline'])
p2 = termcolor.colored(raw_input("Enter name of Player 2: ").title(), 'blue', None, ['underline'])
sym['player1'] = termcolor.colored(raw_input("\n" + p1 + ', you want X or O? - ').capitalize(), 'red', None, ['bold'])
if sym['player1'] == 'X':
sym['player2'] = termcolor.colored('O', 'blue', None, ['bold'])
else:
sym['player2'] = termcolor.colored('X', 'red', None, ['bold'])
players['player1'] = p1
players['player2'] = p2
return {p1:termcolor.colored('X', 'red', None, ['bold']), p2: termcolor.colored('O', 'blue', None, ['bold'])}
def enterguess(turncount):
def guess(name):
return (int(input("\n" + players[name] + ", Enter row number: ")),
int(input(players[name] + ", Enter column number: ")))
if turncount % 2 == 0:
(row, col) = guess('player1')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player2'] + " already took that spot! Please guess again."
enterguess(turncount)
except:
print "\nPlease enter the indexes between 1 and 3."
enterguess(turncount)
else:
(row, col) = guess('player2')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player1'] + " already took that spot! Please guess again."
enterguess(turncount)
except IndexError:
print "\nPlease enter a number between 1 and 3."
enterguess(turncount)
return (row - 1, col - 1)
def changeboard(row, col, xo, c):
if c % 2 == 0:
board[row][col] = xo[players['player1']]
else:
board[row][col] = xo[players['player2']]
def checkWinner():
for x in range(3):
if board[x][0] == board[x][1] == board[x][2] and board[x][0] != " ":
return [players[n] for n, s in sym.iteritems() if s == board[x][0]][0]
for y in range(3):
if board[0][y] == board[1][y] == board[2][y] and board[0][y] != " ":
return [players[n] for n, s in sym.iteritems() if s == board[0][y]][0]
xx = 0
yy = 2
while True:
if board[xx][xx] == board[1][1] == board[2][yy] and board[xx][xx] != " ":
return [players[n] for n, s in sym.iteritems() if s == board[xx][xx]][0]
xx += 2
yy -= 2
if xx == 2:
break
def main():
rules()
xo = playerNames()
printboard()
turncount = 0
for turn in range(9):
(r, c) = enterguess(turncount)
print (r, c)
changeboard(r, c, xo, turncount)
turncount += 1
winner = checkWinner()
printboard()
if winner:
print("\nCongratulations " + winner + "! You are the winner.\n")
break
if turn == 8:
print ("\n Well! Its a tie.\n")
main()
The issue you have is that although you recall enterguess, you don't return it. So it simply keeps recalling enterguess until a valid input is given, then it just ignores all this and goes to the final return statement which still has the malformed guess.
Add return statements:
def enterguess(turncount):
def guess(name):
return (int(input("\n" + players[name] + ", Enter row number: ")),
int(input(players[name] + ", Enter column number: ")))
if turncount % 2 == 0:
(row, col) = guess('player1')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player2'] + " already took that spot! Please guess again."
return enterguess(turncount)
except:
print "\nPlease enter the indexes between 1 and 3."
return enterguess(turncount)
else:
(row, col) = guess('player2')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player1'] + " already took that spot! Please guess again."
return enterguess(turncount)
except IndexError:
print "\nPlease enter a number between 1 and 3."
return nterguess(turncount)
return (row - 1, col - 1)