1 AnswerNew Answer
A few thoughts from the small to the big: - `not(A) and not(B) and not(C)` can be rearranged to `not(A or B or C)` which is technically shorter. It's called DeMorgan's law! So it turns out that your checks on line 18 and 54 are the exact same but negated. - You could offload those checks into a function: def game_over(board): return (board == board == ...) or (...) ... And then you don't have to repeat yourself twice: while(not game_over(board)): if(game_over(board) and not cheat): - The ideal way to DRY up your code is to write seperate functions for checking a single row/column/diagonal. It will probably make your code *longer* but DRYer for sure. Think about how you would solve a 100x100 tic tac toe puzzle!