Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Tic-Tac-Toe in Python

tic-tac-toe

  • Please log in to reply
6 replies to this topic

#1 Vswe

Vswe

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1989 posts
  • Programming Language:Java, C#, PHP, Python, JavaScript, PL/SQL, Visual Basic .NET, Lua, ActionScript

Posted 05 October 2009 - 12:54 PM

I will in this tutorial show how to make a Tic-Tac-Toe game in Python. It will include functions, lists, if statements, while loops, for loops, error handling etc.



We'll begin with creating two functions, the first one will print out the Tic-Tac-Toe board:



def print_board():
    for i in range(0,3):
        for j in range(0,3):
            print map[2-i][j],
            if j != 2:
                print "|",
        print ""


Here we uses two for loops to go through a list variable called map. This variable is a two dimensional list which will hold the info about what's in each position.

Since I (as you will see later) uses the position from the numpad the lowest numbers will come last (at the bottom) we have to inverse the first value (2-i). Then we want to print a "|" as s separator between the squares we do so if j != 2 so we don't get a separator at the end of each line. Then when the line is finished we prints "" just so we continue on a new line since we used the comma ("print map[2-i][j],") to stay on the same line.

So now this function could print a board looking something like these examples:

|   |   
  |   |   
  |   |

X | X |   
O | X | O 
  | O | X

X | X | X 
X | X | X 
X | X | X



Then we have the check_done() function which we will use after each turn to see if the game is over, if so we returns True and prints out a message.



def check_done():
    for i in range(0,3):
        if map[i][0] == map[i][1] == map[i][2] != " " \
        or map[0][i] == map[1][i] == map[2][i] != " ":
            print turn, "won!!!"
            return True
        
    if map[0][0] == map[1][1] == map[2][2] != " " \
    or map[0][2] == map[1][1] == map[2][0] != " ":
        print turn, "won!!!"
        return True

    if " " not in map[0] and " " not in map[1] and " " not in map[2]:
        print "Draw"
        return True
        

    return False


First we check if all 3 squares in all horizontal and vertical lines are the same and not " ". This is so it won't think an completely empty line is a line with 3 in a row. Then it checks the two diagonally lines in the same way. If at least one of these 8 lines are a winning line we will print out turn, "won!!!" and also return the value True. the turn variable will hold which player who's in turn so the message will be either "X won!!!" or "O won!!!".

Then we check if none of the squares still has the value " ". If it's so it means all squares are filled and that nobody have won(since we already have tested if anyone won) so therefor the program prints out "Draw" and then returns True since the game is over.

If none of this happens the function should return False since the game is not over yet.





Now we're done with the two functions and may therefor start with the "real" program. Firstly we have to create 3 variables:


turn = "X"
map = [[" "," "," "],
       [" "," "," "],
       [" "," "," "]]
done = False

I have already told you what these 3 does, but If you have forgot:
  • turn is whose turn it is.
  • map is the board
  • done is if we're done or not
.





And now, write this:


while done != True:
    print_board()
    
    print turn, "'s turn"
    print

    moved = False
    while moved != True:

So here we have a while loop which will continue to loop until done is equal to True. As long as done = False the program will loop one more time when the users have made a move. The we prints out whose turn it is and then creates a variable called moved. The next loop is used to see if the player did a move or not, if it didn't come back here to prompt the user to try again.




Then we just prints how the players should do to play:

print "Please select position by typing in a number between 1 and 9, see below for which number that is which position..."
        print "7|8|9"
        print "4|5|6"
        print "1|2|3"
        print





Then...

try:
            pos = input("Select: ")
            if pos <=9 and pos >=1:

We want the user to select the number and then we check if it's between 1 and 9. But we also adds an error handling so the program won't quit just because an error occurs when the user types a non-number (Like "Hello").






Now we need to check if this move is possible:



Y = pos/3
                X = pos%3
                if X != 0:
                    X -=1
                else:
                     X = 2
                     Y -=1
                    
                if map[Y][X] == " ":


First we gets a X value and a Y value and then use them to check if the square the user wants to use is empty, I will now show you how the calculation of X and Y works.


[TABLE]If we entered:|X calculation:|X =| Y calculation:| Y =
1|Reminder of 1/3 = 1, 1-1 = 0|0|1/3 = 0|0
2|Reminder of 2/3 = 2, 2-1 = 1|1|2/3 = 0|0
3|Reminder of 3/3 = 0, X=0 -> X=2|2|3/3 = 1, X=0 -> Y = Y-1=0|0
4|Reminder of 4/3 = 1, 1-1 = 0|0|4/3 = 1|1
5|Reminder of 5/3 = 2, 2-1 = 1|1|5/3 = 1|1
6|Reminder of 6/3 = 0, X=0 -> X=2|2|6/3 = 2, X=0 -> Y = Y-1=1|1
7|Reminder of 7/3 = 1, 1-1 = 0|0|7/3 = 2|2
8|Reminder of 8/3 = 2, 2-1 = 1|1|8/3 = 2|2
9|Reminder of 9/3 = 0, X=0 -> X=2|2|9/3 = 3, X=0 -> Y = Y-1=2|2
[/TABLE]


So with the calculations of X and Y we get the position of the square like this:

[TABLE]|X=0|X=1|X=2
Y=2|7|8|9
Y=1|4|5|6
Y=0|1|2|3
[/TABLE]


...which is exactly the same as the instruction we typed earlier:


print "7|8|9"
        print "4|5|6"
        print "1|2|3"




Now we have done most of it but we have some lines left:


map[Y][X] = turn
                    moved = True
                    done = check_done()

                    if done == False:
                        if turn == "X":
                            turn = "O"
                        else:
                            turn = "X"
                
            
        except:
            print "You need to add a numeric value"

So we store the current users "name" at the right position (with the X and Y values), set move to True, check if we're done and stores that in done. If the game isn't over, change who's next to move and then we have two lines to print an error message if the try block failed in some way.




That was pretty much it, here comes the whole code if you just want to copy-paste it all, hope you learned something. Bye :D




def print_board():
    for i in range(0,3):
        for j in range(0,3):
            print map[2-i][j],
            if j != 2:
                print "|",
        print ""


def check_done():
    for i in range(0,3):
        if map[i][0] == map[i][1] == map[i][2] != " " \
        or map[0][i] == map[1][i] == map[2][i] != " ":
            print turn, "won!!!"
            return True
        
    if map[0][0] == map[1][1] == map[2][2] != " " \
    or map[0][2] == map[1][1] == map[2][0] != " ":
        print turn, "won!!!"
        return True

    if " " not in map[0] and " " not in map[1] and " " not in map[2]:
        print "Draw"
        return True
        

    return False





turn = "X"
map = [[" "," "," "],
       [" "," "," "],
       [" "," "," "]]
done = False


while done != True:
    print_board()
    
    print turn, "'s turn"
    print

    moved = False
    while moved != True:
        print "Please select position by typing in a number between 1 and 9, see below for which number that is which position..."
        print "7|8|9"
        print "4|5|6"
        print "1|2|3"
        print

        try:
            pos = input("Select: ")
            if pos <=9 and pos >=1:
                Y = pos/3
                X = pos%3
                if X != 0:
                    X -=1
                else:
                     X = 2
                     Y -=1
                    
                if map[Y][X] == " ":
                    map[Y][X] = turn
                    moved = True
                    done = check_done()

                    if done == False:
                        if turn == "X":
                            turn = "O"
                        else:
                            turn = "X"
                
            
        except:
            print "You need to add a numeric value"
        



Edited by Vswe, 05 October 2009 - 01:45 PM.

  • 4

#2 Guest_Jordan_*

Guest_Jordan_*
  • Guest

Posted 05 October 2009 - 01:22 PM

Wow, neat! I didn't know you were learning Python as well.
+rep
  • 0

#3 Vswe

Vswe

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1989 posts
  • Programming Language:Java, C#, PHP, Python, JavaScript, PL/SQL, Visual Basic .NET, Lua, ActionScript

Posted 05 October 2009 - 01:39 PM

I learned it yesterday. Did you know I only need one day to learn a programming language? :)
  • 0

#4 marwex89

marwex89

    CC Mentor

  • VIP Member
  • PipPipPipPipPipPipPipPip
  • 2857 posts

Posted 05 October 2009 - 02:54 PM

I hereby challenge you to learn C++ in one day :lol:

+rep, that's a nice tutorial :D
  • 0
Hey! Check out my new Toyota keyboaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

#5 debtboy

debtboy

    CC Devotee

  • Just Joined
  • PipPipPipPipPipPip
  • 499 posts

Posted 05 October 2009 - 02:57 PM

Tried it out, Very Nice +rep

I've been slowly learning Python
since I started here on the forum.

You're very sharp Vswe :thumbup1:, I'm much slower on
the uptake :sleep:, hope you can help me out when I need it.
  • 0

#6 Vswe

Vswe

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1989 posts
  • Programming Language:Java, C#, PHP, Python, JavaScript, PL/SQL, Visual Basic .NET, Lua, ActionScript

Posted 05 October 2009 - 11:13 PM

Sure I will help you if you need help, debtboy. Thanks all of you for the +rep :P
  • 0

#7 WingedPanther73

WingedPanther73

    A spammer's worst nightmare

  • Moderator
  • 17757 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others

Posted 06 October 2009 - 08:09 AM

Nicely done. +rep

I agree that some languages take longer to learn than others, though.
  • 0

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

My MineCraft server site: http://banishedwings.enjin.com/






Also tagged with one or more of these keywords: tic-tac-toe