Go Back   CodeCall Programming Forum > Software Development > Tutorials
Register Blogs Search Today's Posts Mark Forums Read

Tutorials Programming Tutorials - Post your tutorials here!

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 06-26-2009, 05:39 PM
Hignar's Avatar
Programming Expert
 
Join Date: May 2009
Posts: 398
Hignar will become famous soon enough
[python] tic-tac-toe

Tic-tac-toe seems to be a popular tutorial for a lot of the other languages on this site so I thought I'd put one together for python.

I've only been learning python for a few weeks so it's likely that there will be some errors but I thought that this would be a good tutorial to help taking people learning the language from the point where they are typing out short examples to thinking about how to put together a larger program.

This is something that I hadn't really done before, so there may be better ways to approach it but this is how I got to my final program.

To start off with I decided to make a simple noughts and crosses (tic-tac-toe) game. I didn't want to complicate it by trying to learn GUI programming at the same time so it's entirely command line based.

First thing I did was work out what parts the program would need. Clearly we'd still need to be able to display the game board. Using a nested list seemed to make sense to me as we can display each row on a seperate line to produce a 3x3 board. We'd also need a way to fill the board in turns and finally we need to check after each turn whether there is a winning line for the player who just took a turn or see if the game is drawn. To make the game easier to follow the board should be reprinted after each turn. Players also need to be identified as 'X' and 'O'. This will help with the checkwin function later on.

The basic outline of the program looks like this
Code:
def checkwin(player):
  #code for checking for a winning line

def printboard():
  print board[0]
  print board[1]
  print board[2]

#initialise an empty board
board = [['-','-','-'],['-','-','-'],['-','-','-']]
player1 = 'X'
player2 = 'O'
win = False

#game loop
while(win == False):
  #code for player one's turn
  printboard()
  checkwin(player1)

  #code for player two's turn
  printboard()
  checkwin(player2)
So, first thing to do is enable us to fill the board. The easiest way to do this is to ask each player to select the row and column where they want to place their mark. I decided to take this code out of the main loop and define a function that could be applied to either player.

Code:
#code for player's turn
def playerturn(player):
  print "%s's turn" % player1
  print "Select column [1-3]: ",
  col = int(raw_input()) - 1
  print "Select row [1-3]: ",
  row = int(raw_input()) - 1
  board[row][col] = player
While this works there is no way to stop players overwriting previous moves so we need to code a check to see if it is a valid move and to loop the function until a valid move is given.

Code:
#code for player's turn
def playerturn(player):
  print "%s's turn" % player
  turn = 1
  while(turn)
    print "Select column [1-3]: ",
    col = int(raw_input()) - 1
    print "Select row [1-3]: ",
    row = int(raw_input()) - 1
    #check if move is allowed
    if board[row][col] == 'X' or board[row][col] == 'O'
      print "Already taken!"
    else
      board[row][col] = player
      turn = 0
So we can now print and fill the board. All that's left is to check for a winning line so we need to define the checkwin function. There are four ways to produce a winning line. A horizontal line, a vertical line, a diagonal line from left to right and a diagonal line from right to left. We need to check for each, but once a winning line is found there is no need for the check to continue.

Code:
def checkwin(player):
  #loop through rows and columns
  for c in range(0,3):
    #check for horizontal line
    if board[c][0] == player and board[c][1] == player and board[c][2] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
    #check for vertical line
    elif board[0][c] == player and board[1][c] == player and board[2][c] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
    #check for diagonal win (left to right)
    elif board[0][0] == player and board[1][1] == player and board[2][2] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
    #check for diagonal win (right to left)
    elif board[0][2] == player and board[1][1] == player and board[2][0] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
  else:
    playerwin = False
    return playerwin
So with these elements we should be able to put together a functional (if buggy) game. The only other thing needed is a way to check for a draw. As there are only 9 moves available we can count the number of turns taken and declare a draw when there are no further moves available. Also as a draw is only possible after an odd number of turns we only need to check for a draw after the first players turn.

The final code for our game is as follows

Code:
def checkwin(player):
  #loop through rows and columns
  for c in range(0,3):
    #check for horizontal line
    if board[c][0] == player and board[c][1] == player and board[c][2] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
    #check for vertical line
    elif board[0][c] == player and board[1][c] == player and board[2][c] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
    #check for diagonal win (left to right)
    elif board[0][0] == player and board[1][1] == player and board[2][2] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
    #check for diagonal win (right to left)
    elif board[0][2] == player and board[1][1] == player and board[2][0] == player:
      print "*********\n\n%s wins\n\n*********" % player
      playerwin = True
      return playerwin
  else:
    playerwin = False
    return playerwin

#code for player's turn
def playerturn(player):
  print "%s's turn" % player
  turn = 1
  while(turn):
    print "Select column [1-3]: ",
    col = int(raw_input()) - 1
    print "Select row [1-3]: ",
    row = int(raw_input()) - 1
    if board[row][col] == 'X' or board[row][col] == 'O':
      print "Already taken!"
    else:
      board[row][col] = player
      turn = 0

def printboard():
  print board[0]
  print board[1]
  print board[2]

#initialise an empty board
board = [['-','-','-'],['-','-','-'],['-','-','-']]
player1 = 'X'
player2 = 'O'
win = False
turns = 0

#game loop
#print empty board to start program
printboard()
while(win == False):
  playerturn(player1)
  turns += 1
  printboard()
  if checkwin(player1) == True: break
  if turns == 9:
    print "This game is a draw!"
    break

  playerturn(player2)
  turns += 1
  printboard()
  checkwin(player2)
  if checkwin(player2) == True: break
While the game runs and works there is clearly room for improvement. The most obvious area is error checking. As it stands any value can be entered for the moves and anything other than the numbers 1-3 produce an error. I was surprised just how much checking is needed for the game to be fully functional.

If there is any interest I will improve the game to include error checking in a further tutorial.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 06-26-2009, 08:38 PM
WingedPanther's Avatar
Super Moderator
 
Join Date: Jul 2006
Age: 36
Posts: 11,435
WingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud of
Re: [python] tic-tac-toe

Nice job! Plus, it's nice to have a few python tutorials around +rep
__________________
CodeCall Blog | CodeCall Wiki | Shareware
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 06-28-2009, 01:30 PM
Learning Programmer
 
Join Date: Jun 2009
Posts: 34
psam is on a distinguished road
Re: [python] tic-tac-toe

It's a nice tutorial . I wrote one tic-tac-toe script too a few days ago but it has a GUI (it's programmed using Tkinter) and it's a singleplayer version (computer plays are random so it's really easy to win). I'm attaching it to this message to contribute to this post.
Attached Files
File Type: zip tic-tac-toe.zip (13.8 KB, 35 views)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 07-22-2009, 02:33 AM
Brandon W's Avatar
Code Warrior
 
Join Date: Sep 2008
Location: Australia
Age: 16
Posts: 4,824
Brandon W is a name known to allBrandon W is a name known to allBrandon W is a name known to allBrandon W is a name known to allBrandon W is a name known to allBrandon W is a name known to all
Send a message via MSN to Brandon W
Re: [python] tic-tac-toe

The tutorial could of been better if you explained the code like you did in your encryption one. Still like the output of your work and all people that put time into writing these should be recognised.

+rep

EDIT: Will have to wait a while, I just did it before
__________________
jQuery Selectors Tutorial - jQuery Striped Table tutorial - jQuery Events - jQuery Validation
Sorry if I don't post as often as I did, I'll try to get here as much as possible! I'm working my bum off to get this scholarship and other stuff!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
[Python] GooProxy LogicKills Classes and Code Snippets 2 10-20-2008 12:15 AM


All times are GMT -5. The time now is 06:54 AM.


vBulletin v3.8.0 ©2010, Jelsoft Enterprises Ltd.


no new posts

LinkBacks Enabled by vBSEO 3.1.0