# Making Tic-Tac-Toe winning check more efficient

My code works perfectly fine and I would just like to clean it up a little. From the research I've done, I cannot find anyone that used a multidimensional list to a game of TTT. I'm just looking for a way to make this code prettier than it is right now.

grid = [['-','-','-'],
['-','-','-'],
['-','-','-']]
turn = 'x'
stl = True
rounds = 0

def printGrid(grid):
for i,j,k in grid:
b = print(i,j,k)

def place(grid,turn,row,col):
if grid[row][col] == '-':
grid[row][col] = turn
return True

else:
return False

while stl:
rounds += 1
print("Round %i!" % rounds)

try:

printGrid(grid)
print("\nIt is %s's turn.\n" % turn)
inp = input("What position do you want to place your symbol? (row/col 1-3/1-3) ")
row,col = inp.split('/')
row = int(row)-1
col = int(col)-1
print()

a = place(grid,turn,row,col)

if a == True:
if turn == 'x':
turn = 'o'
else:turn = 'x'

print('----------------------------------\n')

if ['x','x','x'] in grid:
print("X Victory! You won in %i rounds!\n" % rounds)
printGrid(grid)
stl = False
elif ['o','o','o'] in grid:
print("O Victory! You won in %i rounds!\n" % rounds)
printGrid(grid)
stl = False

if grid[0][0] == 'x' and grid[1][0] == 'x' and grid[2][0] == 'x':
print("X Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][1] == 'x' and grid[1][1] == 'x' and grid[2][1] == 'x':
print("X Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][2] == 'x' and grid[1][2] == 'x' and grid[2][2] == 'x':
print("X Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][0] == 'x' and grid[1][1] == 'x' and grid[2][2] == 'x':
print("X Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][2] == 'x' and grid[1][1] == 'x' and grid[2][0] == 'x':
print("X Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False

elif grid[0][0] == 'o' and grid[1][0] == 'o' and grid[2][0] == 'o':
print("O Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][1] == 'o' and grid[1][1] == 'o' and grid[2][1] == 'o':
print("O Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][2] == 'o' and grid[1][2] == 'o' and grid[2][2] == 'o':
print("O Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][0] == 'o' and grid[1][1] == 'o' and grid[2][2] == 'o':
print("O Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False
elif grid[0][2] == 'o' and grid[1][1] == 'o' and grid[2][0] == 'o':
print("O Victory! You won in %i rounds!" % rounds)
printGrid(grid)
stl = False


As you can see, the last portion of the code is gross. I would just like to see if there is a better way of dealing with this.

You could store the winning positions as follows:

winning = [[(0, 0), (1, 0), (2, 0)],
[(0, 1), (1, 1), (2, 1)],
[(0, 2), (1, 2), (2, 2)],
...]


Now you can much more easily loop through the positions and test them, using all:

for positions in winning:
for symbol in 'xy':
if all(grid[r][c] == symbol for r, c in positions):
print("{} Victory! You won in {} rounds!".format(symbol.upper(),
rounds)
stl = False
break


I would wrap all of this in a class, to make life a bit easier:

class TicTacToe:

BLANK = '-'

WINNING = [[(0, 0), (1, 0), (2, 0)],
[(0, 1), (1, 1), (2, 1)],
[(0, 2), (1, 2), (2, 2)],
...]

def __init__(self):
self.grid = [[self.BLANK for _ in range(3)] for _ in range(3)]

def __str__(self):
return '\n'.join([' '.join(row) for row in self.grid])

def won(self):
"""Return the winning symbol, or None if not yet won."""
for positions in self.WINNING:
for symbol in 'xy':
if all(self.grid[r][c] == symbol for r, c in positions):
return symbol

def make_move(self, symbol, row, col):
if self.grid[row][col] != self.BLANK:

1. You should not have multiple statements on the same line (e.g. else:turn = 'x');
3. There's no need to assign the result of print - it is None, just print(i,j,k);
4. You should not have code just running within the script, write a main function and guard a call to it behind if __name__ == '__main__':; and
5. You should generally have more, smaller blocks of functionality (e.g. you could have a function whose job is to get the user to input a valid row/col selection).