How can I check for matching rows and columns with Python? - python

I am building a ticTacToe game and I have everything figured out but how to check for three in a row or three down a column. I think there is something simple missing, but I could have it wrong entirely. Here is the code:
def isWin(gameBoard):
#check for row matches
for row in range(0, 3):
if gameBoard[row][0] == gameBoard[row][1] and gameBoard[row][0] == gameBoard[row][2]:
return True

Maybe you can consider to use set? Something like:
def isWin(gameBoard):
for row in gameBoard:
if len(set(row)) == 1:
return true

I think I figured it out!
def isWin(gameBoard):
#check for row and column matches
for row in range(0, 3):
if gameBoard[row][0] == "X" and gameBoard[row][1] == "X" and gameBoard[row][2] == "X":
return True
if gameBoard[row][0] == "O" and gameBoard[row][1] == "O" and gameBoard[row][2] == "O":
return True
if gameBoard[0][row] == "X" and gameBoard[1][row] == "X" and gameBoard[2][row] == "X":
return True
if gameBoard[0][row] == "O" and gameBoard[1][row] == "O" and gameBoard[2][row] == "O":
return True

So I figured it out and am super excited! I am new to coding so thank you all for the support! Please let me know if you think it could be more efficient. :)
Here is the full code:
import sys
def main():
gameBoard = [[" ", " ", " "],
[" ", " ", " "],
[" ", " ", " "]]
printBoard(gameBoard)
while True:
#
playerXturn(gameBoard)
printBoard(gameBoard)
if isWin(gameBoard):
print("Player X wins!")
sys.exit()
elif boardFull(gameBoard):
print("Draw. No more plays left.")
sys.exit()
playerOturn(gameBoard)
printBoard(gameBoard)
if isWin(gameBoard):
print("Player O wins!")
sys.exit()
elif boardFull(gameBoard):
print("Draw. No more plays left.")
sys.exit()
def printBoard(gameBoard):
print("---------")
print(gameBoard[0][0], "|", gameBoard[0][1], "|", gameBoard[0][2])
print("---------")
print(gameBoard[1][0], "|", gameBoard[1][1], "|", gameBoard[1][2])
print("---------")
print(gameBoard[2][0], "|", gameBoard[2][1], "|", gameBoard[2][2])
print("---------")
def playerXturn(gameBoard):
playerXrow = int(input("Enter a row (0, 1, or 2) for player X: "))
playerXcolumn = int(input("Enter a column (0, 1, or 2) for player X: "))
while gameBoard[playerXrow][playerXcolumn] == "X" or gameBoard[playerXrow][playerXcolumn] == "O":
print("This spot is already taken. Try again:")
playerXrow = int(input("Enter a row (0, 1, or 2) for player X: "))
playerXcolumn = int(input("Enter a column (0, 1, or 2) for player X: "))
gameBoard[playerXrow][playerXcolumn] = "X"
return gameBoard
def playerOturn(gameBoard):
playerOrow = int(input("Enter a row (0, 1, or 2) for player O: "))
playerOcolumn = int(input("Enter a column (0, 1, or 2) for player O: "))
while gameBoard[playerOrow][playerOcolumn] == "X" or gameBoard[playerOrow][playerOcolumn] == "O":
print("This spot is already taken. Try again:")
playerOrow = int(input("Enter a row (0, 1, or 2) for player O: "))
playerOcolumn = int(input("Enter a column (0, 1, or 2) for player O: "))
gameBoard[playerOrow][playerOcolumn] = "O"
return gameBoard
#check for empty spaces on the board
def boardFull(gameBoard):
for i in range(3):
for j in range(3):
if gameBoard[i][j] == " ":
return False
return True
#check for 3 in a row
def isWin(gameBoard):
#check for row matches
for row in range(0, 3):
if gameBoard[row][0] == "X" and gameBoard[row][1] == "X" and gameBoard[row][2] == "X":
return True
if gameBoard[row][0] == "O" and gameBoard[row][1] == "O" and gameBoard[row][2] == "O":
return True
if gameBoard[0][row] == "X" and gameBoard[1][row] == "X" and gameBoard[2][row] == "X":
return True
if gameBoard[0][row] == "O" and gameBoard[1][row] == "O" and gameBoard[2][row] == "O":
return True
#check for diagonal matches
if gameBoard[1][1] != " " and gameBoard[0][0] == gameBoard [1][1] and gameBoard[0][0] == gameBoard [2][2]:
return True
if gameBoard[1][1] != " " and gameBoard[0][2] == gameBoard [1][1] and gameBoard[0][2] == gameBoard [2][0]:
return True
return False
main()

Related

Not recognizing tie in Tic Tac Toe AI

I am building a Tic Tac Toe AI. Here are the rules for the AI:
If there is a winning move, play it.
If the opponent has a winning move, block it.
Otherwise, play randomly.
Here's the code:
# main.py
# Prorities:
# - If there is a winning move, play it
# - If the opponent has a winning move, block it.
# - If nothing to block, make a random move.
import random
import time
import copy
boxes = []
for i in range(3):
row = []
for j in range(3):
row.append(" ")
boxes.append(row)
def printBoard():
to_print = ""
to_print += " " + boxes[0][0] + " | " + boxes[0][1] + " | " + boxes[0][2] + " \n"
to_print += "---+---+---\n"
to_print += " " + boxes[1][0] + " | " + boxes[1][1] + " | " + boxes[1][2] + " \n"
to_print += "---+---+---\n"
to_print += " " + boxes[2][0] + " | " + boxes[2][1] + " | " + boxes[2][2] + " \n"
return to_print
turn = random.randint(1, 2)
if turn == 1:
coin = "you (X)"
else:
coin = "the AI (O)"
print("The coin flip shows", coin, "will go first!")
input("Press Enter to begin! ")
def checkWin(boxes):
win = False
who = " "
for i in range(3):
if boxes[i][0] == boxes[i][1] and boxes[i][1] == boxes[i][2]:
who = boxes[i][0]
if who != " ":
win = True
for i in range(3):
if boxes[0][i] == boxes[1][i] and boxes[2][i] == boxes[1][i]:
who = boxes[0][i]
if who != " ":
win = True
if boxes[0][0] == boxes[1][1] and boxes[1][1] == boxes[2][2]:
who = boxes[0][0]
if who != " ":
win = True
if boxes[0][2] == boxes[1][1] and boxes[1][1] == boxes[2][0]:
who = boxes[0][2]
if who != " ":
win = True
return win, who
def checkTie(boxes):
for row in boxes:
for box in boxes:
if box != "X" and box != "O":
return False
return True
def checkMove(boxes, player):
for i in range(3):
for j in range(3):
if boxes[i][j] != "X" and boxes[i][j] != "O":
boxCopy = copy.deepcopy(boxes)
boxCopy[i][j] = player
win, who = checkWin(boxCopy)
if win:
return True, i, j
return False, 0, 0
while True:
print("Check 1")
win, who = checkWin(boxes)
if win and who == "X":
print("Player X has won.")
print(" ")
print(printBoard())
break
elif win and who == "O":
print("Player O has won.")
print(" ")
print(printBoard())
break
elif checkTie(boxes) == True:
print("It has been concluded as a tie.")
break
print("Check 2")
if turn == 1:
print("")
print(printBoard())
row = (int(input("Pick a row to play: ")) -1)
col = (int(input("Pick a column to play: ")) -1)
if ((row < 4 and row > -1) and (col < 4 and col > -1)) and (boxes[row][col] == " "):
boxes[row][col] = "X"
turn = 2
else:
print("Sorry, that is not allowed.")
print(" ")
# Prorities:
# - If there is a winning move, play it
# - If the opponent has a winning move, block it.
# - If nothing to block, make a random move.
else:
print("")
print(printBoard())
print("[*] AI is choosing...")
time.sleep(1)
row = random.randint(0, 2)
col = random.randint(0, 2)
winMove, winRow, winCol = checkMove(boxes, "O")
lossMove, lossRow, lossCol = checkMove(boxes, "X")
if winMove and (boxes[winRow][winCol] != "X" and boxes[winRow][winCol] != "O"):
boxes[winRow][winCol] = "O"
turn = 1
print("Statement 1: Win play")
elif lossMove and (boxes[lossRow][lossCol] != "X" and boxes[lossRow][lossCol] != "O"):
boxes[lossRow][lossCol] = "O"
turn = 1
print("Statement 2: Block play")
elif boxes[row][col] != "X" and boxes[row][col] != "O":
boxes[row][col] = "O"
turn = 1
print("Statement 3: Random play")
else:
print("Statement 4: None")
print("Check 3")
The problem occurs when there is a tie. Either the function checkTie(), or the if statement isn't working. You might see a couple print('Check #') every once in a while. When you run the code and it's a tie, it shows all the checks going by. Which means it is passing through the check. When there is a tie, it just keeps doing the loop and repeating its turn but not making a move.
What is the mistake and how can I do this correctly?
I think your function should be
def checkTie(boxes):
for row in boxes:
for box in row:
if box != "X" and box != "O":
return False
return True
You mistyped ( I think) boxes for row in the second for statement.
def checkTie(boxes):
if any(" " in box for box in boxes):
return False
return True
Change your checkTie function to this
The rest is all good.

My tic tac toe game is getting a TypeError I don't understand

Can anyone tell me where the errors are in this? I have been going around in circles for over a week trying to figure it out. I am getting the error
"TypeError: list indices must be integers or slices, not list"
for the line of code in the playerXturn() function that is trying to put an "X" where the player chooses the indices.
def main():
gameBoard = [[" ", " ", " "],
[" ", " ", " "],
[" ", " ", " "]]
printBoard(gameBoard)
playerXturn(gameBoard)
while boardFull(gameBoard) is False:
if diagonalWin(gameBoard) is False and rowWin(gameBoard) is False:
playerOturn(gameBoard)
if diagonalWin(gameBoard) is False and rowWin(gameBoard) is False:
playerXturn(gameBoard)
else:
print("Player X wins!")
else:
print("Player O wins!")
printBoard(gameBoard)
def printBoard(gameBoard):
print("---------")
print(gameBoard[0][0], "|", gameBoard[0][1], "|", gameBoard[0][2])
print("---------")
print(gameBoard[1][0], "|", gameBoard[1][1], "|", gameBoard[1][2])
print("---------")
print(gameBoard[2][0], "|", gameBoard[2][1], "|", gameBoard[2][2])
print("---------")
def playerXturn(gameBoard):
playerXrowChoice = input("Enter a row (0, 1, or 2) for player X: ")
playerXrow = [eval(x) for x in playerXrowChoice]
playerXcolumnChoice = input("Enter a column (0, 1, or 2) for player X: ")
playerXcolumn = [eval(x) for x in playerXcolumnChoice]
if gameBoard[playerXrow][playerXcolumn] != "X" and gameBoard[playerXrow][playerXcolumn] != "O":
gameBoard[playerXrow, playerXcolumn] = "X"
else:
print("This spot is already taken.")
return gameBoard
def playerOturn(gameBoard):
playerOrowChoice = input("Enter a row (0, 1, or 2) for player X: ")
playerOrow = [eval(x) for x in playerOrowChoice]
playerOcolumnChoice = input("Enter a column (0, 1, or 2) for player X: ")
playerOcolumn = [eval(x) for x in playerOcolumnChoice]
if gameBoard[playerXrow][playerXcolumn] != "X" and gameBoard[playerXrow][playerXcolumn] != "O":
gameBoard[playerOrow, playerOcolumn] = "O"
else:
print("This spot is already taken.")
return gameBoard
#check for empty spaces on the board
def boardFull(gameBoard):
for i in range(len(gameBoard)):
for j in range(len(gameBoard[i])):
if j != " ":
return True
else:
return False
#check for diagonal match
def diagonalWin(b):
while b[1][1] != " ":
if b[1][1] == b[0][0] == b[2][2] or b[1][1] == b[0][2] == b[2][0]:
return True
else:
return False
#check for 3 in a row
def rowWin(b):
for row in range(0, 3):
if b[row][0] == b[row][1] == b[row][2] == 'X':
return True
else:
return False
main()
The error is on this line:
gameBoard[playerXrow, playerXcolumn] = "X"
I think you meant:
gameBoard[playerXrow][playerXcolumn] = "X"
I'm quite new to python so I don't know what eval() does, but I figured out where is the error.
def playerXturn(gameBoard):
playerXrowChoice= input("Enter a row (0, 1, or 2) for player X: ")
playerXrow = [eval(x) for x in playerXrowChoice]
playerXcolumnChoice= input("Enter a column (0, 1, or 2) for player X: ")
playerXcolumn = [eval(x) for x in playerXcolumnChoice]
if gameBoard[playerXrow][playerXcolumn] != "X" and gameBoard[playerXrow][playerXcolumn] != "O":
gameBoard[playerXrow, playerXcolumn] = "X"
else:
print("This spot is already taken.")
return gameBoard
Here on line:
gameBoard[playerOrow, playerOcolumn] = "X"
here you need to target a specific cell of like this: gameBoard[row][column] in this case:
gameBoard[playerOrow][playerOcolumn] = "X"
and I tried to run the code after this change and I got another error, but I solved it.
As I said I don't know what lines:
playerXcolumn = [eval(x) for x in playerXcolumnChoice]
playerXcolumn = [eval(x) for x in playerXcolumnChoice]
do so I removed them and where you ask for user input:
playerXrowChoice= input("Enter a row (0, 1, or 2) for player X: ")
playerXcolumnChoice= input("Enter a column (0, 1, or 2) for player X: ")
You need to convert input from string to int, so you can target the correct cell of the gameBoard.

Tic Tac Toe nested-list issues

My Tic tac toe code works fine except for a few issues. When marking a spot on the board the user can override and place their own mark in the same spot. Even though I have code that is supposed to fix this. Here is my code. Please fix any other errors as you see fit. I am almost failing a class on this.
board = [['-','-','-']
,['-','-','-']
,['-','-','-']]
player1 = 'X'
player2 = 'O'
win = False
turns = 0
player1= str(input("Whats ur name+"))
player2= str(input("Whats ur name"))
def checkwin(player):
for c in range(0,3):
if board[c][0] == player and board[c][1] == player and board[c][2] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
elif board[0][c] == player and board[1][c] == player and board[2][c] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
#check for diagonal win
elif board[0][0] == player and board[1][1] == player and board[2][2] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
#check for diagonal win (right to left)
elif board[0][2] == player and board[1][1] == player and board[2][0] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
else:
playerwin = False
return playerwin
def playerturn(player):
print "%s's turn" % player
turn = 1
while(turn):
print "Select column [1-3]: ",
col = int(raw_input()) - 1
print "Select row [1-3]: ",
row = int(raw_input()) - 1
if board[row][col] == "X" or board[row][col] == "O":
print "Already taken!"
else:
board[row][col] = player
turn = 0
def printboard():
print board[0]
print board[1]
print board[2]
printboard()
while(win == False):
playerturn(player1)
turns += 1
printboard()
if checkwin(player1) == True: break
if turns == 9:
print "This game is a draw!"
break
playerturn(player2)
turns += 1
printboard()
checkwin(player2)
if checkwin(player2) == True: break
Your problem is that you've put the player name in the array and checked whether there is an "X" or an "O" in the array. A simple solution would be changing the if condition to ... == player1 instead of "X".
If you do so, you also have to adjust the draw function.
board = [['-','-','-']
,['-','-','-']
, ['-','-','-']]
#player1 = 'X'
#player2 = 'O'
win = False
turns = 0
player1= raw_input("Whats ur name+")
player2= raw_input("Whats ur name")
def checkwin(player):
for c in range(0,3):
if board[c][0] == player and board[c][1] == player and board[c][2] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
elif board[0][c] == player and board[1][c] == player and board[2][c] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
#check for diagonal win
elif board[0][0] == player and board[1][1] == player and board[2][2] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
#check for diagonal win (right to left)
elif board[0][2] == player and board[1][1] == player and board[2][0] == player:
print "*********\n\n%s wins\n\n*********" % player
playerwin = True
return playerwin
else:
playerwin = False
return playerwin
def playerturn(player):
print "%s's turn" % player
turn = 1
while(turn):
print "Select column [1-3]: ",
col = int(raw_input()) - 1
print "Select row [1-3]: ",
row = int(raw_input()) - 1
if board[row][col] == player1 or board[row][col] == player2:
print "Already taken!"
else:
board[row][col] = player
turn = 0
def printboard():
print ["X" if x == player1 else "O" if x == player2 else "-" for x in board[0]]
print ["X" if x == player1 else "O" if x == player2 else "-" for x in board[1]]
print ["X" if x == player1 else "O" if x == player2 else "-" for x in board[2]]
printboard()
while(win == False):
playerturn(player1)
turns += 1
printboard()
if checkwin(player1) == True: break
if turns == 9:
print "This game is a draw!"
break
playerturn(player2)
turns += 1
printboard()
checkwin(player2)
if checkwin(player2) == True: break
I also replaced the str(input()) to raw_input() to allow a string as name.

Difficulties with my python tic-tac-toe

I am following Charles Dierbach's book, Introduction to Computer Science using Python.
I am on chapter 5. I am trying to do this exercise on tic-tac-toe automate play.
I am having difficulties creating a function for the pc to select an empty box ([]).
Here is my code
import re
import random
def template():
mylst = list()
for i in range(0, 3):
my_temp = []
for j in range(0, 3):
my_temp.append([])
mylst.append(my_temp)
return mylst
def template_2(alst):
print()
al = ("A", "B", "C")
for a in al:
if a == "A":
print (format(a, ">6"), end="")
if a == "B":
print (format(a, ">5"), end="")
if a == "C":
print (format(a, ">5"), end="")
print()
for j in range(len(alst)):
print(str(j + 1), format( " ", ">1"), end="")
print(alst[j])
print()
def print_template(alst):
print()
al = ("A", "B", "C")
for a in al:
if a == "A":
print (format(a, ">6"), end="")
if a == "B":
print (format(a, ">4"), end="")
if a == "C":
print (format(a, ">3"), end="")
print()
for j in range(len(alst)):
print(str(j + 1), format( " ", ">1"), end="")
print(alst[j])
print()
def first_player(lst):
print()
print ("Your symbol is 'X'. ")
alpha = ("A", "B", "C")
#check it was entered correctly
check = True
temp_lst1 = []
while check:
correct_entry = False
while not correct_entry:
coord = input("Please enter your coordinates ")
player_regex = re.compile(r'(\w)(\d)')
aSearch = player_regex.search(coord)
if aSearch == None:
correct_entry = False
if aSearch.group(1) != "A" or aSearch.group(1) != "B" or aSearch.group(1) != "C" or aSearch.group(2) != 1 or aSearch.group(2) == 2 or aSearch.group(3) != 3:
correct_entry = False
if aSearch.group(1) == "A" or aSearch.group(1) == "B" or aSearch.group(1) == "C" or aSearch.group(2) == 1 or aSearch.group(2) == 2 or aSearch.group(3) == 3:
correct_entry = True
else:
correct_entry = True
blank = False
while not blank:
if lst[(int(coord[-1])) - 1][alpha.index(coord[0])] == []:
lst[(int(coord[-1])) - 1][alpha.index(coord[0])] = "X"
temp_lst1.append((int(coord[-1])-1))
temp_lst1.append((alpha.index(coord[0])))
blank = True
else:
blank = True
correct_entry = False
if blank == True and correct_entry == True:
check = False
return True
def pc_player(lst):
print()
print ("PC symbol is 'O'. ")
alpha = ("A", "B", "C")
num_list = (0, 1, 2)
for i in range(0, len(lst)):
for j in range(0, len(lst[i])):
if lst[i][j] ==[]:
lst[i][j] = "O"
break
break
return True
def check_1st_player(lst):
if lst[0][0] == "X" and lst[0][1] == "X" and lst[0][2] == "X":
return True
elif lst[1][0] == "X" and lst[1][1] == "X" and lst[1][2] == "X":
return True
elif lst[2][0] == "X" and lst[2][1] == "X" and lst[2][2] == "X":
return True
elif lst[0][0] == "X" and lst[1][0] == "X" and lst[2][0] == "X":
return True
elif lst[0][1] == "X" and lst[1][1] == "X" and lst[2][1] == "X":
return True
elif lst[0][2] == "X" and lst[1][2] == "X" and lst[2][2] == "X":
return True
elif lst[0][0] == "X" and lst[1][1] == "X" and lst[2][2] == "X":
return True
elif lst[2][0] == "X" and lst[1][1] == "X" and lst[0][2] == "X":
return True
else:
return False
def check_pc_player(lst):
if lst[0][0] == "O" and lst[0][1] == "O" and lst[0][2] == "O":
return True
elif lst[1][0] == "O" and lst[1][1] == "O" and lst[1][2] == "O":
return True
elif lst[2][0] == "O" and lst[2][1] == "O" and lst[2][2] == "O":
return True
elif lst[0][0] == "O" and lst[1][0] == "O" and lst[2][0] == "O":
return True
elif lst[0][1] == "O" and lst[1][1] == "O" and lst[2][1] == "O":
return True
elif lst[0][2] == "O" and lst[1][2] == "O" and lst[2][2] == "O":
return True
elif lst[0][0] == "O" and lst[1][1] == "O" and lst[2][2] == "O":
return True
elif lst[2][0] == "O" and lst[1][1] == "O" and lst[0][2] == "O":
return True
else:
return False
def play_game():
ask = input("Do you want to play a two player game of Tic-Tac-Toe game? (y/n) ")
if ask in yes_response:
# contruct the template for tic-tac-toe
print()
print("How many rounds do you want to play? " )
print("Please enter only odd integers" )
print("Please enter your coordinates", end="")
print(" using format A1 or B2")
print("New Round")
return True
def play_again():
tell_me = input("Do you want you play a game ? (y/n)")
if tell_me == "Y" or "y":
return True
else:
return False
def is_full(lst):
count = 0
for i in lst:
for j in i:
if j != []:
count += 1
if count == 9:
return True
#
#-- main
print("Welcome to Awesome 2 Player Tic-Tac-Toe Game? ")
print()
answer = False
yes_response =("Y", "y")
no_response = ("N", "n")
while not answer:
print("Enter an even integer to exit")
ask = int(input("How many matches do you want to play? (odd integers only)? " ))
game = play_game()
structure = template()
print_template(structure)
if ask % 2 == 1:
score_player1 = 0
score_pc = 0
count = 0
while count < ask:
pc_lst = []
if count >= 1:
structure = template()
print_template(structure)
while game:
check_pc = True
while check_pc:
pc_player(structure)
template_2(structure)
check_pc = False
check_pc_winner = True
while check_pc_winner:
game_pc = check_pc_player(structure)
check_pc_winner = False
if game_pc == True:
print("Congratulations PC won")
score_pc += 1
game = False
break
check_player1 = True
while check_player1:
first_player(structure)
template_2(structure)
check_player1 = False
check_first_winner = True
while check_first_winner:
game_first = check_1st_player(structure)
check_first_winner = False
if game_first == True:
print("Congratulations Player 1 won")
score_player1 += 1
game = False
break
board_full = False
while not board_full:
check_board = is_full(structure)
board_full = True
if check_board == True:
print("This round was a tie.")
game = False
print("Player 1 : ", score_player1, " PC : ", score_pc)
count += 1
game = True
if score_player1 > score_pc:
print("Player 1 won")
elif score_player1 < score_pc:
print("PC won")
if play_again() == False:
answer = True
else:
answer = False
The problem I have is at def pc_player():
I would like to know how to loop the list and sublists so that AI can select an empty box as its choice to place an "O"
My current for loop does not work. AI only selects the first box.
My current for loop does not work. AI only selects the first box.
I suppose you refer to this part:
def pc_player(lst):
print()
print ("PC symbol is 'O'. ")
alpha = ("A", "B", "C")
num_list = (0, 1, 2)
for i in range(0, len(lst)):
for j in range(0, len(lst[i])):
if lst[i][j] ==[]:
lst[i][j] = "O"
break
break
return True
The break instructions together with the way you initialize the for loops will only attempt to set lst[0][0]. Other cells are not considered.
To make an evenly distributed random choice, it is essential to gather the possibilities first. For this, it is convenient to have all cells in a plain list first:
from itertools import chain
all_cells = list(chain.from_iterable(lst))
Then, you can filter out non-empty cells:
empty_cells = filter(lambda l: len(l) == 0, all_cells)
# empty_cells = filter(lambda l: not l, all_cells)
# empty_cells = [cell for cell in all_cells if not cell]
Based on this you can now trigger your random selection and symbol placement:
import random
cell_to_place = random.choice(empty_cells)
cell_to_place.append('O')
If you need the index of the cell being modified, you can do the following:
import itertools
indices = list(itertools.product(range(3), range(3)))
indexed_cells = zip(indices, map(lambda (i, j): lst[i][j], indices))
indexed_cells = filter(lambda (_, l): not l, indexed_cells) # filter non-empty
(i,j), cell_to_place = random.choice(indexed_cells)
# ...
These code samples do not take into account that there could be no empty cell left. Also, your code has some general design issues. For example:
Why do you use lists as cell items in the first place? You could simply use None, 'X' and 'O' as the elements of the 2-dimensional list.
check_pc_player and check_1st_player can be easily generalized by making the symbol to check for a parameter of the function.
Why is this a while-loop?
while check_first_winner:
game_first = check_1st_player(structure)
check_first_winner = False
Start by finding all empty boxes:
empty= [(i,j) for i in range(len(lst)) for j in range(len(lst[i])) if lst[i][j]==[]]
Then choose a random one:
import random
chosen_i, chosen_j= random.choice(empty)
And finally put an O there:
lst[chosen_i][chosen_j]= 'O'

Im getting an error in the shell whenever enter is pressed when I'm changing the board size

Have a look at ChangeBoardSize()
It'll be part of the while loop that I have to change but I'm not sure what to change or what to change it to.
I would appreciate any help for this to be done in anyway.
Ignore this but now because I am just trying to get the character count up so that I can post this.
import random
def SetUpGameBoard(Board, Boardsize, PlayerInitials, ComputerInitials):
for Row in range(1, BoardSize + 1):
for Column in range(1, BoardSize + 1):
if (Row == (BoardSize + 1) // 2 and Column == (BoardSize + 1) // 2 + 1) or (Column == (BoardSize + 1) // 2 and Row == (BoardSize + 1) // 2 + 1):
Board[Row][Column] = ComputerInitials
elif (Row == (BoardSize + 1) // 2 + 1 and Column == (BoardSize + 1) // 2 + 1) or (Column == (BoardSize + 1) // 2 and Row == (BoardSize + 1) // 2):
Board[Row][Column] = PlayerInitials
else:
Board[Row][Column] = " "
def ChangeInitials(PlayerName):
print("Enter the initials for", PlayerName, "'s piece")
PlayerInitials = input()
PlayerInitials = PlayerInitials.upper()
print("Enter the initials for the computer's piece")
ComputerInitials = input()
ComputerInitials = ComputerInitials.upper()
return ComputerInitials, PlayerInitials
def ChangeBoardSize():
BoardSize = int(input("Enter a board size (between 4 and 9): "))
while not(BoardSize >= 4 and BoardSize <= 9):
BoardSize = int(input("Enter a board size (between 4 and 9): "))
if BoardSize != [4, 5, 6, 7, 8, 9]:
ChangeBoardSize()
elif BoardSize == " ":
ChangeBoardSize()
return BoardSize
def GetHumanPlayerMove(PlayerName):
print(PlayerName, "enter the coodinates of the square where you want to place your piece: ", end="")
Coordinates = input()
if Coordinates.isdigit():
MoveValid = True
return int(Coordinates)
def GetComputerPlayerMove(BoardSize):
return random.randint(1, BoardSize) * 10 + random.randint(1, BoardSize)
def GameOver(Board, BoardSize):
for Row in range(1 , BoardSize + 1):
for Column in range(1, BoardSize + 1):
if Board[Row][Column] == " ":
return False
return True
def GetPlayersName():
PlayerName = input("What is your name? ")
return PlayerName
def CheckIfMoveIsValid(Board, Move):
Row = Move % 10
Column = Move // 10
MoveIsValid = False
if Board[Row][Column] == " ":
MoveIsValid = True
return MoveIsValid
def GetPlayerScore(Board, BoardSize, Piece):
Score = 0
for Row in range(1, BoardSize + 1):
for Column in range(1, BoardSize + 1):
if Board[Row][Column] == Piece:
Score = Score + 1
return Score
def CheckIfThereArePiecesToFlip(Board, BoardSize, StartRow, StartColumn, RowDirection, ColumnDirection):
RowCount = StartRow + RowDirection
ColumnCount = StartColumn + ColumnDirection
FlipStillPossible = True
FlipFound = False
OpponentPieceFound = False
while RowCount <= BoardSize and RowCount >= 1 and ColumnCount >= 1 and ColumnCount <= BoardSize and FlipStillPossible and not FlipFound:
if Board[RowCount][ColumnCount] == " ":
FlipStillPossible = False
elif Board[RowCount][ColumnCount] != Board[StartRow][StartColumn]:
OpponentPieceFound = True
elif Board[RowCount][ColumnCount] == Board[StartRow][StartColumn] and not OpponentPieceFound:
FlipStillPossible = False
else:
FlipFound = True
RowCount = RowCount + RowDirection
ColumnCount = ColumnCount + ColumnDirection
return FlipFound
def FlipOpponentPiecesInOneDirection(Board, BoardSize, StartRow, StartColumn, RowDirection, ColumnDirection):
FlipFound = CheckIfThereArePiecesToFlip(Board, BoardSize, StartRow, StartColumn, RowDirection, ColumnDirection)
if FlipFound:
RowCount = StartRow + RowDirection
ColumnCount = StartColumn + ColumnDirection
while Board[RowCount][ColumnCount] != " " and Board[RowCount][ColumnCount] != Board[StartRow][StartColumn]:
if Board[RowCount][ColumnCount] == "H":
Board[RowCount][ColumnCount] = "C"
else:
Board[RowCount][ColumnCount] = "H"
RowCount = RowCount + RowDirection
ColumnCount = ColumnCount + ColumnDirection
def MakeMove(Board, BoardSize, Move, HumanPlayersTurn):
Row = Move % 10
Column = Move // 10
if HumanPlayersTurn:
Board[Row][Column] = "H"
else:
Board[Row][Column] = "C"
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, 1, 0)
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, -1, 0)
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, 0, 1)
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, 0, -1)
def PrintLine(BoardSize):
print(" ", end="")
for Count in range(1, BoardSize * 2):
print("_", end="")
print()
def DisplayGameBoard(Board, BoardSize):
print()
print(" ", end="")
for Column in range(1, BoardSize + 1):
print(" ", end="")
print(Column, end="")
print()
PrintLine(BoardSize)
for Row in range(1, BoardSize + 1):
print(Row, end="")
print(" ", end="")
for Column in range(1, BoardSize + 1):
print("|", end="")
print(Board[Row][Column], end="")
print("|")
PrintLine(BoardSize)
print()
def DisplayMenu():
print("(p)lay game")
print("(e)nter name")
print("(c)hange board size")
print("(i)initials change")
print("(a)lter piece name")
print("(q)uit")
print()
def GetMenuChoice(PlayerName):
print(PlayerName, "enter the letter of your chosen option: ", end="")
Choice = input()
return Choice
def CreateBoard():
Board = []
for Count in range(BoardSize + 1):
Board.append([])
for Count2 in range(BoardSize + 1):
Board[Count].append("")
return Board
def PlayGame(PlayerName, BoardSize, PlayerInitials, ComputerInitials):
Board = CreateBoard()
SetUpGameBoard(Board, BoardSize, PlayerInitials, ComputerInitials)
HumanPlayersTurn = False
while not GameOver(Board, BoardSize):
HumanPlayersTurn = not HumanPlayersTurn
DisplayGameBoard(Board, BoardSize)
MoveIsValid = False
while not MoveIsValid:
if HumanPlayersTurn:
Move = GetHumanPlayerMove(PlayerName)
else:
Move = GetComputerPlayerMove(BoardSize)
MoveIsValid = CheckIfMoveIsValid(Board, Move)
if not HumanPlayersTurn:
print("Press the Enter key and the computer will make its move")
input()
MakeMove(Board, BoardSize, Move, HumanPlayersTurn)
DisplayGameBoard(Board, BoardSize)
HumanPlayerScore = GetPlayerScore(Board, BoardSize, "H")
ComputerPlayerScore = GetPlayerScore(Board, BoardSize, "C")
if HumanPlayerScore > ComputerPlayerScore:
print("Well done", PlayerName, ", you have won the game!")
elif HumanPlayerScore == ComputerPlayerScore:
print("That was a draw!")
else:
print("The computer has won the game!")
print()
random.seed()
BoardSize = 6
PlayerName = ""
Choice = ""
PlayerInitials = 'H'
ComputerInitials = 'C'
while Choice.lower() != "q": #.lower() makes any allows uppercase input
DisplayMenu()
Choice = GetMenuChoice(PlayerName)
if Choice.lower() == "p":
PlayGame(PlayerName, BoardSize, ComputerInitials, PlayerInitials)
elif Choice.lower() == "e":
PlayerName = GetPlayersName()
elif Choice.lower() == 'a':
ChangePieceName()
elif Choice.lower() == 'i':
ChangeInitials(PlayerName)
elif Choice.lower() == "c":
BoardSize = ChangeBoardSize()
There is a problem because you don't handle entering characters other than numbers so it fails on line 39
return int(Coordinates) # if Coordinates is not str convertable to int it fails
So you need to do something like
def GetHumanPlayerMove(PlayerName):
print(PlayerName, "enter the coodinates of the square where you want to place your piece: ", end="")
Coordinates = input()
if Coordinates.isdigit():
MoveValid = True
try:
return int(Coordinates)
except ValueError:
print("Please enter number")
print(PlayerName, "enter the coodinates of the square where you want to place your piece: ", end="")
return GetHumanPlayerMove(PlayerName)
Or create a while loop like you did below. So
while not isinstance(Coordinates, int): ...
The function will look like this
def GetHumanPlayerMove(PlayerName):
MoveValid = False
while not MoveValid:
print(PlayerName, "enter the coodinates of the square where you want to place your piece: ", end="")
Coordinates = input()
if Coordinates.isdigit():
MoveValid = True
return int(Coordinates)

Categories

Resources