Overrice
Overrice

Reputation: 21

Efficient way to check for TicTacToe win condition // EDIT: How to check for tie?

So I made a TicTacToe program as my first little project in Python (using 3.4).

It works so far, but I want to know if it is possible to simplify the win condition checking

import os
clear = lambda: os.system('cls')



def playerChange(player):  #Function for easily swapping out players
    if player == "X":
        return "O"
    else:
        return "X"

player = "X"  #Setting initial player
tttfield = ["1","2","3","4","5","6","7","8","9"] #setting up tictactoe field
clear()
while True:

    print("", tttfield[0], "|", tttfield[1], "|", tttfield[2], "\n",
          "---------", "\n",
          tttfield[3], "|", tttfield[4], "|", tttfield[5], "\n",
          "---------", "\n",
          tttfield[6], "|", tttfield[7], "|", tttfield[8], "\n")

    choice = 0
    choice = input("\n%s, choose a slot: " % player)
    if choice in tttfield:
        tttfield[int(choice)-1] = player #marks space
        player = playerChange(player) #changes player
    else:
        input("Not a valid number! Choose again!")
    clear()

    #check for win condition
    if ((tttfield[0]==tttfield[1]==tttfield[2]) or\
        (tttfield[3]==tttfield[4]==tttfield[5]) or\
        (tttfield[6]==tttfield[7]==tttfield[8]) or\
        (tttfield[0]==tttfield[3]==tttfield[6]) or\
        (tttfield[1]==tttfield[4]==tttfield[7]) or\
        (tttfield[2]==tttfield[5]==tttfield[8]) or\
        (tttfield[0]==tttfield[4]==tttfield[8]) or\
        (tttfield[6]==tttfield[4]==tttfield[2])) :
        clear()
        input("\n\n  %s wins!" % playerChange(player))
        break

The win condition checking looks fairly clumsy, because of all the checks. Is there a way to compact it?

EDIT: Just noticed a bug in my program. I do not have any tie check, and getting into a tie situation will cause you to get stuck - how do I check for a tie? I have no idea how I could do that.

Upvotes: 1

Views: 1543

Answers (1)

Paul Bissex
Paul Bissex

Reputation: 1704

A common approach is to store the winning states in a compact data structure, e.g.

winners = [[0, 1, 2], [3, 4, 5] ...]

And then loop through them, e.g.

for squares in winners:
    if all(tttfield[square]=='x' for square in squares):
        print "X wins!"

(You'd want to run this for both X and O, i.e. add an outer loop and use its variable instead of literal X/O inside)

p.s. You don't need those backslashes. Being inside parentheses is enough for Python to know that the expression continues.

Upvotes: 2

Related Questions