I try to make a tic tac toe game and I get:
'str' object is not callable
as error. No idea what to do.
from IPython.display import clear_output
def display_board (board):
clear_output()
print (' ' + board [7] + '|' + board [8] + '|' + board[9])
print (' ' + board [4] + '|' + board [5] + '|' + board[6])
print (' ' + board [1] + '|' + board [2] + '|' + board[3])
def player_input():
marker = " "
while marker != "X" and marker != "O":
marker = input ('Igralec 1: izberi X ali O: ').upper()
if marker == 'X':
return ('X', 'O')
else:
return ('O', 'X')
def place_marker (board, marker, position):
board[position]= marker
def win_check (board, mark):
return ((board[1] == board[2] == board[3] == mark) or #vrsta 1
(board[4] == board[5] == board[6] == mark) or #vrsta 2
(board[5] == board[6] == board[7] == mark) or #vrsta 3
(board[8] == board[5] == board[2] == mark) or #stolpec 2
(board[9] == board[6] == board[3] == mark) or #stolpec 3
(board[7] == board[4] == board[1] == mark) or #stolpec 4
(board[3] == board[5] == board[7] == mark) or #diagonala
(board[1] == board[5] == board[9] == mark)) #diagonala
import random
def choose_first():
flip= random.randint (0,1)
if flip== 0:
return 'Igralec 1'
else:
return 'Player 2'
def space_check (board, position):
board[position] ==' '
def full_board_check (board):
for i in range (1,10):
if space_check (board, i):
return False
return True
def player_choice (board):
position= 0
while position not in [1,2,3,4,5,6,7,8,9] or not space_check (board, position):
position = int(input('Izberi pozicijo: (1-9) '))
return position
def replay():
choice = input ('Želiš še enkrat igrat (Y or N)? ')
return choice ('Y')
print (' Hello, pri tri v vrsto!')
while True:
the_board=[""] *10
player1_marker,player2_marker = player_input()
turn= choose_first()
print= (turn+ ' je prvi igralec!')
play_game= input (' Pripravljeni za igro? y or n ')
if play_game== 'y':
game_on= True
else:
game_on= False
##game time
while game_on:
#igralec 1
if turn== 'Player 1':
display_board(the_board)
position= player_choice(the_board)
place_marker(the_board,player1_marker,position)
#check if they won
if win_check(the_board,player1_marker):
display_board(the_board)
print ('Igralec 1 je zmagovalec!')
game_on = False
else:
if full_board_check(the_board):
display_board(the_board)
print ("Izanačeno!")
game_on= False
else:
turn = 'Igralec 2'
else:
#igralec 2
display_board(the_board)
position= player_choice(the_board)
place_marker(the_board,player2_marker,position)
#check if they won
if win_check(the_board,player2_marker):
display_board(the_board)
print ('Igralec 2 je zmagovalec!')
game_on = False
else:
if full_board_check(the_board):
display_board(the_board)
print ("Izanačeno!")
game_on= False
else:
turn = 'Igralec 1'
if not replay():
break
Errors are:
49 display_board(the_board)
\AppData\Local\Temp/ipykernel_10492/3794783463.py in display_board(board)
print (' ' + board [7] + '|' + board [8] + '|' + board[9])
TypeError: 'str' object is not callable
TypeError
1 print (' Hello pri tri v vrsto!')
2
3 while True:
TypeError: 'str' object is not callable
This line of code:
print= (turn+ ' je prvi igralec!')
Should be written like this:
print(turn+ ' je prvi igralec!')
You can find what goes wrong with the error description hints ;)
You have the typo = in print(), the fix would be:
print(turn + ' je prvi igralec!')
to prevent such cases install the linter, like flake8 or pylint, they could help you to improve your code. Also check the black formatting tool to improve readability.
Related
I recently tried creating a simple Tic Tac Toe AI with minimax (with help from YouTube), but I can't get it to work. The algorithm just spits out the first value it checks instead of going through all of them and giving the best one.
I tried copying the code from the YouTube video but it still doesn't work, can someone tell me what's wrong?
import math
import random
print()
board = {1: ' ', 2: ' ', 3: ' ',
4: ' ', 5: ' ', 6: ' ',
7: ' ', 8: ' ', 9: ' '}
computerLetter = 'X'
playerLetter = 'O'
def print_board(board=board):
for i in range(1, 8, 3):
print('|' + board[i] + '|' + board[i + 1] + '|' + board[i + 2] + '|')
if i < 7:
print('-' * 13)
print()
def space_is_free(position):
if board[position] == ' ':
return True
else:
return False
def free_spaces(board=board):
freeSpaces = 0
for key in board.keys():
if key == ' ':
freeSpaces += 1
return freeSpaces
def make_move(letter, position):
if space_is_free(position):
board[position] = ' ' + letter + ' '
print_board(board)
if check_for_win(board):
if letter == 'O':
print("You win!!")
exit()
else:
print("The computer wins. Better luck next time!")
exit()
elif check_for_tie(board):
print("It's a tie! Well played.")
exit()
else:
print("Invalid choice.")
position = int(input("Enter new position: "))
make_move(letter, position)
def check_for_win(board=board):
if board[1] == board[2] == board[3] != ' ' or board[4] == board[5] == board[6] != ' ' or board[7] == board[8] \
== board[9] != ' ' or board[1] == board[4] == board[7] != ' ' or board[2] == board[5] == board[6] != \
' ' or board[3] == board[6] == board[9] != ' ' or board[1] == board[5] == board[9] != ' ' or board[3]\
== board[5] == board[7] != ' ':
return True
else:
return False
def check_for_win_letter(letter):
if board[1] == board[2] == board[3] == ' ' + letter + ' ' or board[4] == board[5] == board[6] == ' ' + letter + ' '\
or board[7] == board[8] == board[9] == ' ' + letter + ' ' or board[1] == board[4] or board[7] == ' ' +\
letter + ' ' or board[2] == board[5] or board[6] == ' ' + letter + ' ' or board[3] == board[6] or board[9]\
== ' ' + letter + ' ' or board[1] == board[5] == board[9] == ' ' + letter + ' ' or board[3] == board[5] ==\
board[7] == ' ' + letter + ' ':
return True
else:
return False
def check_for_tie(board=board):
for key in board.keys():
if board[key] == ' ':
return False
else:
return True
def player_move(playerLetter='O'):
if free_spaces(board) >= 9:
print_board(board)
position = int(input("Enter position (1-9): "))
make_move(playerLetter, position)
def computer_move(computerLetter='X'):
if free_spaces(board) == 9:
make_move(computerLetter, 5)
else:
bestScore = -math.inf
bestPosition = 0
for key in board.keys():
if space_is_free(key):
board[key] = ' ' + computerLetter + ' '
score = minimax(board, 0, False)
board[key] = ' '
if score > bestScore:
bestScore = score
bestPosition = key
make_move(computerLetter, bestPosition)
print(f"Computer moves to {bestPosition}.")
def minimax(board, depth, isMaximising):
if check_for_win_letter('X'):
return 1 * (free_spaces(board) + 1)
elif check_for_win_letter('O'):
return -1 * (free_spaces(board) + 1)
elif check_for_tie(board):
return 0
if isMaximising:
bestScore = -math.inf
for key in board.keys():
if space_is_free(key):
board[key] = ' ' + computerLetter + ' '
score = minimax(board, depth + 1, False)
board[key] = ' '
bestScore = max(score, bestScore)
return bestScore
else:
bestScore = math.inf
for key in board.keys():
if space_is_free(key):
board[key] = ' ' + playerLetter + ' '
score = minimax(board, depth + 1, True)
board[key] = ' '
bestScore = min(score, bestScore)
return bestScore
while not check_for_win(board):
computer_move('X')
player_move('O')
# gameState = input("Would you like to play again? (y/n)")
#
# if gameState.lower() == 'y':
# main()
# elif gameState.lower() == 'n':
# exit()
# else:
# print("Invalid choice.")
I tried changing the computer and player letters, and whether the computer was maximising or minimising but it didn't work.
I think I have found what is wrong with your code, in the minmax function the first if, elif, else statement always ends with a return statement.
def minimax(board, depth, isMaximising):
if check_for_win_letter('X'):
return 1 * (free_spaces(board) + 1)
elif check_for_win_letter('O'):
return -1 * (free_spaces(board) + 1)
elif check_for_tie(board):
return 0
The else statement is the reason it is failing.
When a return statement is called, it ends the function returning the variable stated, in this case it will always be a number between -9 and 9, and does not run the next block of code, ruining the computer's process to find the best/worst place to play. the else statement means that even if the previous statements are false, it will always return zero, ending the function and halting the process of the next block of code.
I hope this helps! :)
Okay I figured out the problem, it was actually a bunch of logical errors in the functions which were checking for a winner and the winner letter, a few typos per say.
Error 1:
def check_for_win(board=board):
if board[1] == board[2] == board[3] != ' ' or board[4] == board[5] == board[6] != ' ' or board[7] == board[8] \
== board[9] != ' ' or board[1] == board[4] == board[7] != ' ' or ****board[2] == board[5] == board[6]**** != \ # board[6] should be board[8]
' ' or board[3] == board[6] == board[9] != ' ' or board[1] == board[5] == board[9] != ' ' or board[3]\
== board[5] == board[7] != ' ':
return True
Error 2:
def check_for_win_letter(letter):
if board[1] == board[2] == board[3] == ' ' + letter + ' ' or board[4] == board[5] == board[6] == ' ' + letter + ' '\
or board[7] == board[8] == board[9] == ' ' + letter + ' ' or board[1] == board[4] ****or board[7]**** == ' ' +\
letter + ' ' or board[2] == board[5] ****or board[6]**** == ' ' + letter + ' ' or board[3] == board[6] ****or board[9]****\
== ' ' + letter + ' ' or board[1] == board[5] == board[9] == ' ' + letter + ' ' or board[3] == board[5] ==\
board[7] == ' ' + letter + ' ':
return True
The statements within asterisks (*) are the errors, the or statements should be == and the board[6] should again be board[8].
I am a complete beginner with Python and coding in general. I am making a Tic Tac Toe game in Python as part of the online course I am studying.
I've struggled with getting my head around the nitty gritty of how functions work and can be utilised. I have had to follow the course notes quite closely to try and understand what is happening once the code starts fitting together. Can't find similar problems on here so it can't be an issue with the course notes!
When I run the programme, it skips my position_choice() function, displays the empty board and then asks to replay. I feel I'm missing some basic issue like indentation, but would really appreciate if anyone is able to spot a problem with the function itself or the code set up? It follows the course notes structure almost identically and I'm at a loss!
Here are the functions:
from IPython.display import clear_output
import random
def display_board(board):
clear_output()
print(' ' + board[7] + ' ' + '|' + ' ' + board[8] + ' ' + '|' + ' ' + board[9] + ' ')
print('- - - - - -')
print(' ' + board[4] + ' ' + '|' + ' ' + board[5] + ' ' + '|' + ' ' + board[6] + ' ')
print('- - - - - -')
print(' ' + board[1] + ' ' + '|' + ' ' + board[2] + ' ' + '|' + ' ' + board[3] + ' ')
def player_choice():
player1 = input('Choose your marker: '.upper())
while True:
if player1.upper() == 'X':
player2 = 'O'
print('\nPlayer 1 is ' + player1.upper() + '\nPlayer 2 is ' + player2 + '.')
return player1.upper(), player2
elif player1.upper() == 'O':
player2 = 'X'
print('\nPlayer 1 is ' + player1.upper() + '\nPlayer 2 is ' + player2 + '.')
return player1.upper(), player2
else:
print('Sorry, that is not a valid marker. Please choose either O or X.')
player1 = input('Choose your marker: '.upper())
def place_marker(board, marker, position):
board[position] = marker
def win_check(position, mark):
return ((position[7] == position[8] == position[9] == mark)
or (position[4] == position[5] == position[6] == mark)
or (position[1] == position[2] == position[3] == mark)
or (position[1] == position[5] == position[9] == mark)
or (position[7] == position[5] == position[3] == mark)
or (position[7] == position[4] == position[1] == mark)
or (position[8] == position[5] == position[2] == mark)
or (position[9] == position[6] == position[3] == mark))
def choose_first():
rand_int = random.randint(1,2)
if rand_int == 1:
print('Player 1 goes first')
return '1'
if rand_int == 2:
print('Player 2 goes first')
return '2'
def space_check(board, position):
return board[position] == ' '
def full_board_check(board):
for position in range(1,10):
if space_check(board, position):
return False
return True
def position_choice(board):
position = 0
while position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position):
position = int(input('Please choose your position: '))
return position
def replay():
return input('Do you want to play again?').lower().startswith('y')
def play_game():
play_game = input('Do you want to play?')
if play_game.lower()[0] == 'y':
return True
else:
return False
And here's the programme code. Why does it just display the empty board, skip asking for the position, and ask for the replay? Any help would keep up my stalling motivation!!
print('Welcome to Tic Tac Toe!')
while play_game():
theboard = [' '] * 10
player1_marker, player2_marker = player_choice()
turn = choose_first()
if turn == 1:
display_board(theboard)
position = position_choice(theboard)
place_marker(theboard, player1_marker, position)
if win_check(theboard, player1_marker):
display_board(theboard)
print('Player 1 is the winner!')
replay()
else:
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
replay()
else:
turn == 2
else:
display_board(theboard)
position = position_choice(theboard)
place_marker(theboard, player2_marker, position)
if win_check(theboard, player2_marker):
display_board(theboard)
print('Player 2 is the winner!')
replay()
else:
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
replay()
else:
turn == 1
if not replay():
break
There are several problems :
The choose_first returns a String instead of an integer.
The method called in the while, always ask if you want to play.
You recreate a new board on each loop, you have to declare it before the loop if you don't want to lose it.
At the end of each loop you ask each times if you want to replay
to change the turn variable you should do turn = 2 instead of using double equals witch is comparing equality.
And when you want to "replay", don't forget to reset the board.
To debug this, you should comment a part of your code. And run it step by step. By doing this, you will find were are the errors.
Here is the code, the game will works but you may still want to ad some improvements.
theboard = [' '] * 10
if play_game():
player1_marker, player2_marker = player_choice()
turn = choose_first()
while not full_board_check(theboard):
display_board(theboard)
position = position_choice(theboard)
if turn == 1:
place_marker(theboard, player1_marker, position)
if win_check(theboard, player1_marker):
display_board(theboard)
print('Player 1 is the winner!')
if replay():
theboard = [' '] * 10
else:
break
turn = 2
else:
place_marker(theboard, player2_marker, position)
if win_check(theboard, player2_marker):
display_board(theboard)
print('Player 2 is the winner!')
if replay():
theboard = [' '] * 10
else:
break
turn = 1
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
if replay():
theboard = [' '] * 10
else:
break
Why does it just display the empty board, skip asking for the position, and ask for the replay?
position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position) - this condition isn't working, the logic is wrong.
>>> theboard = [' '] * 10
>>> theboard
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
>>> position = 0
>>> position not in [1,2,3,4,5,6,7,8,9] and not space_check(theboard, position)
False
>>>
Here is one way to refactor position_choice
def position_choice(board):
#print(board)
#position = 0
valid = False
# keep asking till thay give a valid answer
while not valid:
position = int(input('Please choose your position (1-9): '))
valid = position in [1,2,3,4,5,6,7,8,9]
valid = valid and space_check(board, position)
return position
## OLD STUFF
## while position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position):
## position = int(input('Please choose your position: '))
##
## return position
Asking the user for input until they give a valid response
How to debug small programs
So, I was trying to make a basic Tic-Tac-Toe game with python, And I created one which works perfectly fine, but my code is not so good, as it has a lot of code for checking the list indexes(Winner Of The Game), which kinda bothers me. So, How I avoid using the left index for checking the winner of the game?
My Code:
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
def show_board():# for showing the tic-tac-toe board
print(' | ' + str(board[0]) + ' | ' +
str(board[1]) + ' | ' + str(board[2]) + ' | ')
print(' | ' + str(board[3]) + ' | ' +
str(board[4]) + ' | ' + str(board[5]) + ' | ')
print(' | ' + str(board[6]) + ' | ' +
str(board[7]) + ' | ' + str(board[8]) + ' | ')
def main():
one = 1
flag = 1
show_board()
while one == 1:
if flag == 1:
x_o = 'X'
if flag == 2:
x_o = 'O'
pos = int(input('Player "' + x_o + '" Turn: '))
if x_o == 'o':
x_o = 'O'
if x_o == 'x':
x_o = 'X'
if board[pos - 1] == 'O' or board[pos - 1] == 'O':
print('That Place Is Already Filled By Player "0"')
if board[pos - 1] == 'X' or board[pos - 1] == 'X':
print('That Place Is Already Filled By Player "X"')
else:
try:
board[pos - 1] = x_o
except IndexError:
print('Type Numbers Between Only 1 And 9')
if flag == 1:
flag = 2
elif flag == 2:
flag = 1
show_board()
# Checking The Winner Of The Game
# for horizontal X
if board[0] == board[1] == board[2] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[3] == board[4] == board[5] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[6] == board[7] == board[8] == 'X':
one = 2
print('The Winner Is Player "X"!')
# for Daigonal X
elif board[0] == board[4] == board[8] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[2] == board[4] == board[6] == 'X':
one = 2
print('The Winner Is Player "X"!')
# for Vertical X
elif board[1] == board[4] == board[7] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[2] == board[5] == board[8] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[0] == board[3] == board[6] == 'X':
one = 2
print('The Winner Is Player "X"!')
# for horizontal O
elif board[0] == board[1] == board[2] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[3] == board[4] == board[5] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[6] == board[7] == board[8] == 'O':
one = 2
print('The Winner Is Player "O"!')
# for Diagonal O
elif board[0] == board[4] == board[8] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[2] == board[4] == board[6] == 'O':
one = 2
print('The Winner Is Player "O"!')
# for Vertical 0
elif board[1] == board[4] == board[7] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[2] == board[5] == board[8] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[0] == board[3] == board[6] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[0] != ' ' and board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[6] != ' ' and board[7] != ' ' and board[8] != ' ':
print('The Match Is A Tie!')
one = 2
main()
So, as you can see I'm using a lot of if statements for checking the winner of the game. How can I avoid that and do it in fewer lines.
You can replace them with some loops like:
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
def show_board():# for showing the tic-tac-toe board
print(' | ' + str(board[0]) + ' | ' +
str(board[1]) + ' | ' + str(board[2]) + ' | ')
print(' | ' + str(board[3]) + ' | ' +
str(board[4]) + ' | ' + str(board[5]) + ' | ')
print(' | ' + str(board[6]) + ' | ' +
str(board[7]) + ' | ' + str(board[8]) + ' | ')
def main():
one = 1
flag = 1
show_board()
while one == 1:
if flag == 1:
x_o = 'X'
if flag == 2:
x_o = 'O'
pos = int(input('Player "' + x_o + '" Turn: '))
if x_o == 'o':
x_o = 'O'
if x_o == 'x':
x_o = 'X'
if board[pos - 1] == 'O' or board[pos - 1] == 'O':
print('That Place Is Already Filled By Player "0"')
if board[pos - 1] == 'X' or board[pos - 1] == 'X':
print('That Place Is Already Filled By Player "X"')
else:
try:
board[pos - 1] = x_o
except IndexError:
print('Type Numbers Between Only 1 And 9')
if flag == 1:
flag = 2
elif flag == 2:
flag = 1
show_board()
# Checking The Winner Of The Game
won = False
for turn in ('X', 'O'):
# horizontal
if not won:
for i in (0, 3, 6):
if all(board[i + k] == turn for k in range(3)):
won = True
break
# vertical
if not won:
for i in range(3):
if all(board[i + k] == turn for k in (0, 3, 6)):
won = True
break
# diagonal
if not won:
if all(board[k] == turn for k in (0, 4, 8)) or \
all(board[k] == turn for k in (2, 4, 6)):
won = True
# handle winning
if won:
one = 2
print(f'The Winner Is Player "{turn}"!')
break
# handle a tie
if not won and all(square != ' ' for square in board):
one = 2
print('The Match Is A Tie!')
main()
(You can probably also polish/simplify the rest of the code quite a bit)
EDIT
Here is some similar code simplified / polished / expanded to:
handle boards of arbitrary sizes
correctly handle non-numerical input
use more functions
get rid of redundant variables
NUM_ROWS = 3
NUM_COLS = 3
NUM_WIN = 3
BOARD_SIZE = NUM_ROWS * NUM_COLS
EMPTY = ' '
BOARD = [EMPTY] * BOARD_SIZE
TURNS = 'X', 'O'
def show_board(board):
"""Show the tic-tac-toe board."""
for i in range(0, BOARD_SIZE, NUM_COLS):
print(' | ' + ' | '.join(board[i:i + NUM_COLS]) + ' | ')
def ij(i, j):
"""Convert (row, col) to board index."""
return i + NUM_COLS * j
def check_winner(board, turn):
"""Check if there is a winner."""
# horizontal
for i in range(NUM_ROWS):
for j in range(NUM_COLS - NUM_WIN + 1):
if all(board[ij(i, j + k)] == turn for k in range(NUM_WIN)):
return True
# vertical
for i in range(NUM_ROWS - NUM_WIN + 1):
for j in range(NUM_COLS):
if all(board[ij(i + k, j)] == turn for k in range(NUM_WIN)):
return True
# diagonal
for i in range(NUM_ROWS - NUM_WIN + 1):
for j in range(NUM_COLS - NUM_WIN + 1):
K = NUM_WIN
if all(board[ij(i + k, j + k)] == turn for k in range(NUM_WIN)):
return True
if all(board[ij(i + NUM_WIN - k - 1, j + k)] == turn
for k in range(NUM_WIN)):
return True
def check_tie(board):
"""Check if tie."""
return all(square != EMPTY for square in board)
def next_turn(turn):
"""Advance to next turn."""
return TURNS[(TURNS.index(turn) + 1) % 2]
def main():
"""Tic-tac-toe game."""
turn = TURNS[0]
show_board(BOARD)
while True:
valid_input = False
while not valid_input:
try:
choice = int(input(f'Player `{turn}` turn: '))
valid_input = (1 <= choice <= BOARD_SIZE)
if not valid_input:
raise ValueError
except ValueError:
print(f'Type numbers between 1 and {BOARD_SIZE} only.')
else:
idx = choice - 1
if BOARD[idx] != EMPTY:
print(f'Position `{idx}` already taken by `{BOARD[idx]}`')
else:
BOARD[idx] = turn
show_board(BOARD)
won = check_winner(BOARD, turn)
if won:
print(f'The winner is player `{turn}`!')
break
# handle a tie
if not won and check_tie(BOARD):
print('The match is a tie!')
break
turn = next_turn(turn)
if __name__ == '__main__':
main()
Please check mnk-game's source code for a similar implementation using NumPy and classes (especially Board.py). DISCLAIMER: I am the author of the package.
EDIT 2
Note that for tic-tac-toe only, check_winner() could be shortend using an approach similar to what #rusu_ro1 proposed :
WIN_CASES = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], # horizontal
[0, 3, 6], [1, 4, 7], [2, 5, 8], # vertical
[0, 4, 8], [2, 4, 6], # diagonal
]
def check_winner(board, turn, win_cases=WIN_CASES):
"""Check if there is a winner."""
for win_case in win_cases:
if all(board[i] == turn for i in win_case):
return True
import random as rnd
size = 3
## random board to test
board = [[rnd.choice(["X", "O"]) for _ in range(size)] for _ in range(size)]
print(board)
def check_winner(board):
for mark in ["X", "O"]:
## count mark in all rows
count_in_rows = [row.count(mark) for row in board]
## count mark in all columns
count_in_columns = [ [board[row_n][col_n] for row_n in range(size)].count(mark) for col_n in range(size)]
## count mark in fwd diagonal
count_in_diag = [[board[i][i] for i in range(size)].count(mark)]
## count in backward diagonal
count_in_diag.append([board[i][size-i-1] for i in range(size)].count(mark))
print((count_in_rows + count_in_columns + count_in_diag))
## if there is 3 count of mark in any rows, columns or diagonal
if 3 in (count_in_rows + count_in_columns + [count_in_diag]):
print(f"winner is {mark}")
return mark
return
check_winner(board)
you can definition o_list =['o', 'o', 'o'] and x_list = ['x', 'x', 'x']
and then just comparison them like:
#l = board
if(l[0:3] == o_list or l[3:6] == o_list or l[6:9] == o_list or l[0:9:3] == o_list or l[1:9:3] == o_list or l[8:0:-3] == o_list):
print('The Winner Is Player "O"!')
same as for x_list.
;)
o_list =['o', 'o', 'o']
x_list =['x', 'x', 'x']
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
def show_board():# for showing the tic-tac-toe board
print(' | ' + str(board[0]) + ' | ' +
str(board[1]) + ' | ' + str(board[2]) + ' | ')
print(' | ' + str(board[3]) + ' | ' +
str(board[4]) + ' | ' + str(board[5]) + ' | ')
print(' | ' + str(board[6]) + ' | ' +
str(board[7]) + ' | ' + str(board[8]) + ' | ')
def main():
one = 1
flag = 1
o_list =['o', 'o', 'o']
x_list =['x', 'x', 'x']
show_board()
while one == 1:
if flag == 1:
x_o = 'X'
if flag == 2:
x_o = 'O'
pos = int(input('Player "' + x_o + '" Turn: '))
if x_o == 'o':
x_o = 'O'
if x_o == 'x':
x_o = 'X'
if board[pos - 1] == 'O' or board[pos - 1] == 'O':
print('That Place Is Already Filled By Player "0"')
if board[pos - 1] == 'X' or board[pos - 1] == 'X':
print('That Place Is Already Filled By Player "X"')
else:
try:
board[pos - 1] = x_o
except IndexError:
print('Type Numbers Between Only 1 And 9')
if flag == 1:
flag = 2
elif flag == 2:
flag = 1
show_board()
# Checking The Winner Of The Game
# for horizontal X
if(board[0:3] == x_list or board[3:6] == x_list or board[6:9] == x_list or board[0:9:3] == x_list or board[1:9:3] == x_list or board[8:0:-3] == x_list):
one = 2
print('The Winner Is Player "X"!')
if(board[0:3] == o_list or board[3:6] == o_list or board[6:9] == o_list or board[0:9:3] == o_list or board[1:9:3] == o_list or board[8:0:-3] == o_list):
one = 2
print('The Winner Is Player "O"!')
elif board[0] != ' ' and board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[6] != ' ' and board[7] != ' ' and board[8] != ' ':
print('The Match Is A Tie!')
one = 2
main()
You can use this functions(input:board and a player's letter, output: True if that player has won):
def isWinner(board, letter):
return (
(board[1] == board[2] == board[3] == letter) or
(board[4] == board[5] == board[6] == letter) or
(board[7] == board[8] == board[9] == letter) or
(board[7] == board[4] == board[1] == letter) or
(board[8] == board[5] == board[2] == letter) or
(board[9] == board[6] == board[3] == letter) or
(board[7] == board[5] == board[3] == letter) or
(board[9] == board[5] == board[1] == letter))
for checking the winner you can use:
from operator import itemgetter
from itertools import chain
winning_cases = {'diags' : [[0, 4, 8], [2, 4, 6]],
'rows': [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
'cols': [[0, 3, 6], [1, 4, 7], [2, 5, 8]]}
def check_winner(board=board):
for case in chain(*winning_cases.values()):
candidates = set(itemgetter(*case)(board))
if len(candidates) == 1 and '' not in candidates: # check if a diag, row or col has only one charcter
winner, = candidates
return winner
return None
for example:
board = ['X', 'X', 'O', 'X', 'O','O', 'X', 'O', 'X']
check_winner(board)
output:
X
the method check_winner will return the winner if there is one, otherwise None
I am doing python lessons from this page.
https://inventwithpython.com/chapter10.html
I have created tic tac toe by typing all the code from above site myself
Sometimes the code works fine. Sometimes I get this error and the game crashes
Traceback (most recent call last):
File "E:\Python\tictac.py", line 139, in <module>
makeMove(theBoard, computerLetter, move)
File "E:\Python\tictac.py", line 40, in makeMove
board[move] = letter
TypeError: list indices must be integers, not NoneType
Here is my code from the game which i typed
import random
def drawBoard(board):
#this functions printts the board
print(' | |')
print(' ' + board[7] + '| ' + board[8] + ' | ' + board[9])
print(' | |')
print('-----------')
print(' ' + board[4] + '| ' + board[5] + ' | ' + board[6])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[1] + '| ' + board[2] + ' | ' + board[3])
print(' | |')
def inputPlayerletter():
#lets the player type the letter which they want to be
letter = ''
while not (letter == 'X' or letter == 'O'):
print('Do you want to be X or O?')
letter = input().upper()
#first letter is users, second belongs to pc
if letter == 'X':
return['X','O']
else:
return['O','X']
def whoGoesFirst():
if random.randint(0,1) == 0:
return 'computer'
else:
return 'player'
def playAgain():
print('Do you want to play again?(yes or no)')
return input().lower().startswith('y')
def makeMove(board, letter, move):
board[move] = letter
def isWinner(bo, le):
#returns true if player wins
#bo is board le is letter
return((bo[7] == le and bo[5] == le and bo[6] == le) or
(bo[1] == le and bo[2] == le and bo[3] == le) or
(bo[7] == le and bo[4] == le and bo[1] == le) or
(bo[8] == le and bo[5] == le and bo[2] == le) or
(bo[9] == le and bo[6] == le and bo[3] == le) or
(bo[7] == le and bo[5] == le and bo[3] == le) or
(bo[9] == le and bo[5] == le and bo[1] == le))
def getBoardCopy(board):
dupeBoard = []
for i in board:
dupeBoard.append(i)
return dupeBoard
def isSpaceFree(board, move):
return board[move] == ' '
def getPlayerMove(board):
move = ' '
while move not in '1 2 3 4 5 6 7 8 9 '.split() or not isSpaceFree(board, int(move)):
move = input()
return int(move)
def chooseRandomMoveFromList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
def getComputerMove(board, computerLetter):
if computerLetter == 'X':
playerLetter = 'O'
else:
playerLetter = 'X'
for i in range(1,10):
copy = getBoardCopy(board)
if isSpaceFree(copy, i):
makeMove(copy, computerLetter, i)
if isWinner(copy, computerLetter):
return i
move = chooseRandomMoveFromList(board, [1,3,7,9])
if move != None:
return move
if isSpaceFree(board, 5):
return 5
return chooseRandomMoveFromList(board, [ 2,4,6,8])
def isBoardFull(board):
#return true if the board is filled
for i in range(1,10):
if isSpaceFree(board, i):
return False
return True
print('Welcome to tic tac toe')
while True:
#reset the Board
theBoard = [' '] * 10
playerLetter, computerLetter = inputPlayerletter()
turn = whoGoesFirst()
print('The ' + turn + ' will go first.')
gameIsPlaying = True
while gameIsPlaying:
if turn == 'player':
#player's turn
drawBoard(theBoard)
move = getPlayerMove(theBoard)
makeMove(theBoard, playerLetter, move)
if isWinner(theBoard, playerLetter):
drawBoard(theBoard)
print('Hooray! Yoou have won the game!')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The gaame is a tie!')
break
else:
turn = 'computer'
else:
#computer turns
move = getComputerMove(theBoard, computerLetter)
makeMove(theBoard, computerLetter, move)
if isWinner(theBoard, computerLetter):
drawBoard(theBoard)
print('The Computer has beaten you! You lose. ')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'player'
if not playAgain():
break
You should convert:
def chooseRandomMoveFromList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
to
def chooseRandomMoveFromList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
The problem is that because of the indentation you don't calculate all free positions. Instead, you check only the first candidate position if it's free and when it's not you return nothing.
This is a Tic Tac Toe program, but it has a certain twist to it...you are able to cover up an opponent's x or o with a larger x or o. You have medium pieces and large pieces. For some reason, I can't get my board to display the current moves and it doesn't seem to recognize winning conditions. Any help would be greatly appreciated.
#Winner checker.
def player_done(playerSym, board):
return ((board[6] == playerSym and board[7] == playerSym and board[8] == playerSym) or # across the top
(board[3] == playerSym and board[4] == playerSym and board[5] == playerSym) or # across the middle
(board[0] == playerSym and board[1] == playerSym and board[2] == playerSym) or # across the bottom
(board[6] == playerSym and board[3] == playerSym and board[0] == playerSym) or # down the left side
(board[7] == playerSym and board[4] == playerSym and board[3] == playerSym) or # down the middle
(board[8] == playerSym and board[5] == playerSym and board[2] == playerSym) or # down the right side
(board[6] == playerSym and board[4] == playerSym and board[2] == playerSym) or # diagonal
(board[8] == playerSym and board[4] == playerSym and board[0] == playerSym)) # diagonal
def opponent_done(oppSym, board):
return ((board[6] == oppSym and board[7] == oppSym and board[8] == oppSym) or # across the top
(board[3] == oppSym and board[4] == oppSym and board[5] == oppSym) or # across the middle
(board[0] == oppSym and board[1] == oppSym and board[2] == oppSym) or # across the bottom
(board[6] == oppSym and board[3] == oppSym and board[0] == oppSym) or # down the left side
(board[7] == oppSym and board[4] == oppSym and board[1] == oppSym) or # down the middle
(board[8] == oppSym and board[5] == oppSym and board[2] == oppSym) or # down the right side
(board[6] == oppSym and board[4] == oppSym and board[2] == oppSym) or # diagonal
(board[8] == oppSym and board[4] == oppSym and board[0] == oppSym)) # diagonal
# Sets up the Board
def drawBoard(board):
print(' | |')
print(' ' + board[6] + ' | ' + board[7] + ' | ' + board[8])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[5] + ' | ' + board[4] + ' | ' + board[3])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[0] + ' | ' + board[1] + ' | ' + board[2])
print(' | |')
#Prints the current board
def print_board(board):
# Make a duplicate of the board list and return it the duplicate.
dupeBoard = []
for i in board:
dupeBoard.append(i)
return dupeBoard
#The Board
board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
done = False
#The Move list for X's and O's
xmovesList = ["*","x","X"]
omovesList = [".","o","O"]
#Greeting message and choosing the initial X and O assignment.
print "Welcome to Tic-Tac-Toe-Cover-Up!"
playerSym = raw_input("Player 1, please select either X or O for your pieces: ")
print
#Player and opponent move assignment
if (playerSym == "X"):
playerSym = xmovesList
oppSym = omovesList
turn = "X"
else:
playerSym = omovesList
oppSym = xmovesList
turn = "O"
#Main game loop.
while not done:
drawBoard(board)
print turn,"'s turn"
if (turn == "X"):
player = xmovesList
opponent = omovesList
else:
player = omovesList
opponent = xmovesList
print "Select the place you want to play (0-8)"
print_board(board)
pos = input("Select: ")
if pos <=8 and pos >=0:
Y = pos/3
X = pos%3
if X != -1:
X -=1
else:
X = 2
Y -=1
if board == " ":
board = player[9]
moved = True
done = player()
elif board != " ":
if board == opponent[0]:
board = player[1]
moved = True
done = player_done()
done = opponent_done()
if board == opponent[1]:
board = player[2]
moved = True
done = player_done()
done = opponent_done()
if done == False:
if turn == "X":
turn = "O"
else:
turn = "X"
There were mltiple issues with it.
For emptiness You were comparing with " " where as you are initialing board with 1-9
Also major issue of error :
board = player[9]
This you needed
board[pos] = player[0]
Also you need to fix checking logic to :
board[6] in playerSym # and not board[6] == playerSym
This is program with some fixes.
#Winner checker.
def check_done(playerSym,board):
return ((board[6] in playerSym and board[7] in playerSym and board[8] in playerSym) or # across the top
(board[3] in playerSym and board[4] in playerSym and board[5] in playerSym) or # across the middle
(board[0] in playerSym and board[1] in playerSym and board[2] in playerSym) or # across the bottom
(board[6] in playerSym and board[3] in playerSym and board[0] in playerSym) or # down the left side
(board[7] in playerSym and board[4] in playerSym and board[3] in playerSym) or # down the middle
(board[8] in playerSym and board[5] in playerSym and board[2] in playerSym) or # down the right side
(board[6] in playerSym and board[4] in playerSym and board[2] in playerSym) or # diagonal
(board[8] in playerSym and board[4] in playerSym and board[0] in playerSym)) # diagonal
# Sets up the Board
def drawBoard(board):
print(' | |')
print(' ' + board[6] + ' | ' + board[7] + ' | ' + board[8])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[5] + ' | ' + board[4] + ' | ' + board[3])
print(' | |')
print('-----------')
print(' | |')
print(' ' + board[0] + ' | ' + board[1] + ' | ' + board[2])
print(' | |')
#Verifies if board is not full with all largest signs and no mpre moves are possible.
def movesPossible(board):
#TODO: implement this
return True
#Prints the current board
def print_board(board):
# Make a duplicate of the board list and return it the duplicate.
dupeBoard = []
for i in board:
dupeBoard.append(i)
return dupeBoard
#The Board
board = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
done = False
#The Move list for X's and O's
xmovesList = ["*","x","X"]
omovesList = [".","o","O"]
#Greeting message and choosing the initial X and O assignment.
print "Welcome to Tic-Tac-Toe-Cover-Up!"
playerSym = raw_input("Player 1, please select either X or O for your pieces: ")
print
#Player and opponent move assignment
if (playerSym == "X"):
player = xmovesList
opponent = omovesList
else:
player = omovesList
opponent = xmovesList
drawBoard(board)
#Main game loop.
while movesPossible(board):
print player[2],"'s turn"
print "Select the place you want to play (0-8)"
print_board(board)
moved = False
pos = input("Select: ")
if pos <=8 and pos >=0:
Y = pos/3
X = pos%3
if X != -1:
X -=1
else:
X = 2
Y -=1
if board[pos] == str(pos):
board[pos] = player[0]
moved = True
done = check_done(player,board)
else :
if board[pos] == opponent[0]:
board[pos] = player[1]
moved = True
done = check_done(player,board)
if board[pos] == opponent[1]:
board[pos] = player[2]
moved = True
done = check_done(player,board)
drawBoard(board)
if done:
break;
if moved :
player,opponent = opponent,player
if(done):
print player[2], "wins "
else:
print "No more moves possible. It's a draw."