3
\$\begingroup\$

I've just started a self-learning "course" on Python practical programming for beginners. I found this book online, and decided to go through the chapters.

The book had a half-complete implementation of a Tic-Tac-Toe game, and I was supposed to finish it as an exercise. This is my code so far:

theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
 'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
 'low-L': ' ', 'low-M': ' ', 'low-R': ' '}
def printBoard(board):
 """ This function prints the board after every move """
 print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
 print('-+-+-')
 print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
 print('-+-+-')
 print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])
def checkWin(board):
 """
 This functions checks if the win condition has been
 reached by a player
 """
 flag = False
 possibleWins = [['top-L', 'top-M', 'top-R'],
 ['mid-L', 'mid-M', 'mid-R'],
 ['low-L', 'low-M', 'low-R'],
 ['top-L', 'mid-L', 'low-L'],
 ['top-M', 'mid-M', 'low-M'],
 ['top-R', 'mid-R', 'low-R'],
 ['top-L', 'mid-M', 'low-R'],
 ['top-R', 'mid-M', 'low-L']]
 for row in range(len(possibleWins)):
 temp = board[possibleWins[row][0]]
 if temp != ' ':
 for position in possibleWins[row]:
 if board[position] != temp:
 flag = False
 break
 else:
 flag = True
 if flag:
 return True
 return False 
turn = 'X'
for i in range(9):
 printBoard(theBoard) 
 print('Turn for ' + turn + '. Move on which space?')
 while True:
 move = input()
 if move in theBoard:
 if theBoard[move] != ' ':
 print('Invalid move. Try again.')
 else:
 break
 else:
 print('Invalid move. Try again.')
 theBoard[move] = turn
 if checkWin(theBoard):
 printBoard(theBoard) 
 print('Player ' + turn + ' wins!')
 break
 if turn == 'X':
 turn = 'O'
 else:
 turn = 'X'

My checkWin function is very "stupid", it detects a win based on predetermined scenarios, and may not be very efficient in that regard as well. What if the board was of an arbitrary size nxn? Is there an algorithm to determine the victory condition without having to rewrite the entire game?

asked Jul 13, 2015 at 18:05
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Something's wrong with your formatting... I tried to fix it, but there is a return False right in the middle that I'm not 100% sure how to resolve. Please review how your code is formatted, because as it is, it's not valid Python \$\endgroup\$ Commented Jul 13, 2015 at 20:15
  • \$\begingroup\$ re-formatted, let me know if there is anything wrong again \$\endgroup\$ Commented Jul 13, 2015 at 21:40

1 Answer 1

3
\$\begingroup\$

For a 3x3 tic-tac-toe board it hardly provides any real advantage, but if you where to play on an nxn board, with n consecutive same player marks determining a winner, you could do the following...

class TicTacToe(object):
 def __init__(self, n=3):
 self.n = n
 self.board = [[0 for j in range(n)] for k in range(n)]
 self.row_sum = [0 for j in range(n)]
 self.col_sum = [0 for j in range(n)]
 self.diag_sum = 0
 self.diag2_sum = 0
 def add_move(self, player, row, col):
 assert player in (0, 1)
 assert 0 <= row < self.n and 0 <= col < self.n
 delta = [-1, 1][player]
 winner = None
 self.board[row][col] = delta
 self.row_sum[row] += delta:
 if self.row_sum[row] = delta * self.n:
 winner = player
 self.col_sum[col] += player:
 if self.col_sum[col] = player * self.n:
 winner = player
 if col == row:
 self.diag += delta
 if self.diag == delta * self.n:
 winner = player
 if row == self.n - row - 1:
 self.diag2 += delta
 if self.diag2 == delta* self.n:
 winner = player
 return winner

You basically initialize the board to all zeros, use -1 for one player and 1 for the other, and keep track of the sum of values in each row, column and diagonal. Whenever you add a new move, you can update all your data in constant time, and check in constant time if the player has won.

answered Jul 13, 2015 at 21:38
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.