Kurt Peek Kurt Peek - 2 months ago 6
Python Question

How to make a function determining the winner of Tic-Tac-Toe more concise

I'm writing a Python script which is supposed to allow human and computer players to play Tic Tac Toe. To represent the board, I'm using a 3x3 Numpy array with

for the marks of the players (instead of "X" and "O"). I've written the following function to determine the winner:

import numpy as np

class Board():
def __init__(self, grid = np.ones((3,3))*np.nan):
self.grid = grid

def winner(self):
rows = [self.grid[i,:] for i in range(3)]
cols = [self.grid[:,j] for j in range(3)]
diag = [np.array([self.grid[i,i] for i in range(3)])]
cross_diag = [np.array([self.grid[2-i,i] for i in range(3)])]

lanes = np.concatenate((rows, cols, diag, cross_diag))

if any([np.array_equal(lane, np.ones(3)) for lane in lanes]):
return 1
elif any([np.array_equal(lane, np.zeros(3)) for lane in lanes]):
return 0

So for example, if I execute

board = Board()
board.grid = np.diag(np.ones(3))
print board.winner()

I get the result
. What bothers me slightly is the repetition of the
statements. I would think there would be a more concise, DRY way of coding this. (I was thinking of a switch/case as in MATLAB but this doesn't exist in Python). Any suggestions?


Another option is to check the sum of lanes.

    s = np.sum(lanes, axis=1)
    if 3 in s:
        return 1
    elif 0 in s:
        return 0