I've been developing a basic tictactoe game in Python 3 where a player competes against an AI to win. On the first turn, the code is executed successfully with no errors, but after that I get the error previously described.
I've tried changing "board[move] = computer" to "move = computer", but that simply skips the computer's turn, as nothing is being filled out.
I expected the output of a tictactoe board with a new square filled in with an "O". But I get the error "board[move] = computer TypeError: list indices must be integers or slices, not NoneType"
Here's the code:
X = "X"
O = "O"
EMPTY = " "
TIE = "TIE"
NUM_SQUARES = 9
def pieces():
go_first = ask_yes_no("Do you require the first move? (y/n): ")
if go_first == "y":
print("\nThen take the first move. You will need it.")
human = X
computer = O
else:
print("\nYour bravery will be your undoing... I'll go first")
computer = X
human = O
return computer, human
def new_board():
board = []
for square in range(NUM_SQUARES):
board.append(EMPTY)
return board
def legal_moves(board):
moves = []
for square in range(NUM_SQUARES):
if board[square] == EMPTY:
moves.append(square)
return moves
def winner(board):
WAYS_TO_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 row in WAYS_TO_WIN:
if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:
winner = board[row[0]]
return winner
if EMPTY not in board:
return TIE
return None
def human_move(board, human):
legal = legal_moves(board)
move = None
while move not in legal:
move = ask_number("Where will you move? (0 - 8):", 0,
NUM_SQUARES)
if move not in legal:
print("\nThat square is already occupied. Choose another.\n")
print("Fine...")
return move
def computer_move(board, computer, human):
board = board[:]
BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7)
print("I shall take square number", end=" ")
for move in legal_moves(board):
board[move] = computer
if winner(board) == computer:
print(move)
return move
board[move] = EMPTY
for move in legal_moves(board):
board[move] = human
if winner(board) == human:
print(move)
return move
board[move] = EMPTY
for move in BEST_MOVES:
if move in legal_moves(board):
print(move)
return move
def next_turn(turn):
if turn == X:
return O
else:
return X
def main():
computer, human = pieces()
turn = X
board = new_board()
display_board(board)
while not winner(board):
if turn == human:
move = human_move(board, human)
board[move] = human
else:
move = computer_move(board, computer, human)
board[move] = computer
display_board(board)
turn = next_turn(turn)
the_winner = winner(board)
main()
Your legal_moves function is broken, because it returns just after the first 'sqare' no matter what. If it was alredy taken, it returns an empty list.
Just move the return
an intendation down:
def legal_moves(board):
moves = []
for square in range(NUM_SQUARES):
if board[square] == EMPTY:
moves.append(square)
return moves