How to create a formula that checks who won a tic-tac-toe game without lots of if statements?
<p>I have the following code and feel it could be more efficient. Meaning this is 3x3 board and could be done manually but what if it were a 30x30 board or bigger?</p>

<pre><code>x = [[1, 2, 0],[2, 1, 0],[2, 1, 0]]

for y in range (3):
    if ((x[0][0] == x[1][0] == x[2][0] == y) or

    (x[0][1] == x[1][1] == x[2][1] == y) or

    (x[0][2] == x[1][2] == x[2][2] == y) or

    (x[0][0] == x[0][1] == x[0][2] == y) or

    (x[1][0] == x[1][1] == x[1][2] == y) or

    (x[2][0] == x[2][1] == x[2][2] == y) or

    (x[0][0] == x[1][1] == x[2][2] == y) or

    (x[0][2] == x[1][1] == x[2][0] == y)):

        if y==1:
            print('Player 1 won!!!')
        if y==2:
            print('Player 2 won!!!')
        if y==0:
            print('Nobody won')
</code></pre>

<p>Is there a way to make the condition part better?</p>

<p>You could use a function generator like this:</p>

<pre><code>def cell_owner(player):
    """returns a function which can check if a cell belongs to provided player"""
    def wrapped(cell):
        return player == cell
    return wrapped
</code></pre>

<p>So you can call <code>cell_owner(1)</code> to get a function which accept a value and checks if it is 1.
This seems useless, but with such a function you can use <a href="https://docs.python.org/3.5/library/functions.html?highlight=all#all" rel="nofollow">all</a> and <a href="https://docs.python.org/3.5/library/functions.html?highlight=all#map" rel="nofollow">map</a> to check a whole cells group in one line:</p>

<pre><code># will return True if each cell in &lt;cells_group&gt; belong to &lt;player&gt;
all(map(cell_owner(&lt;player&gt;), &lt;cells_group&gt;)
</code></pre>

<p>Before, doing this, you can prepare a list of cells groups which are winnable and then iterate on the list applying the all/map functions to each group to determine is a player won.</p>

<p>Below is a complete example with some extra-functions for test pupose:</p>

<pre><code>import random


def gen_random_grid(size):
    """just for test purpose: generate a randomly filled grid"""
    return [[random.randint(0, 2) for col in range(size)] for row in range(size)]

def print_grid(grid):
    """just for test purpose: prints the grid"""
    size = len(grid)
    row_sep = "+{}+".format("+".join(["---"] * size))
    row_fmt = "|{}|".format("|".join([" {} "] * size))
    print(row_sep)
    for row in grid:
        print(row_fmt.format(*row))
        print(row_sep)

def cell_owner(player):
    """returns a function which can check is a cell belongs to provided player"""
    def wrapped(cell):
        return player == cell
    return wrapped

def get_winner(grid):
    """determines if there is a winner"""
    size = len(grid)

    # prepare list of potentially winning cells groups
    cells_groups_to_check = grid[:]  # rows
    cells_groups_to_check += [[grid[row][col] for row in range(size)]
                              for col in range(size)] #cols
    cells_groups_to_check.append(
        [grid[index][index] for index in range(size)])  # diag 1
    cells_groups_to_check.append(
        [grid[index][size - 1 - index] for index in range(size)])  # diag 2

    winner = 0
    for y in range(1, 3):  # 0 is not a player, no need to test it
        # for each player...
        for group in cells_groups_to_check:
            # ... check if a cells group is complete
            if (all(map(cell_owner(y), group))):
                winner = y
                break
        if winner: break
    return winner

# generate some random grids of different sizes
TEST_GRIDS = [gen_random_grid(3) for _ in range(3)]
TEST_GRIDS += [gen_random_grid(2) for _ in range(3)]
TEST_GRIDS += [gen_random_grid(4) for _ in range(3)]

# demonstration
for grid in TEST_GRIDS:
    print_grid(grid)
    print("Winner is {}".format(get_winner(grid)))
</code></pre>

<p>Note this code should work for any size of <strong>square</strong> grid.</p>

python