amigojapan

a Tic Tac Toe game I made in python a while ago

Apr 17th, 2013
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.21 KB | None | 0 0
  1. #tictactoe game by Usmar A Padow and Inoishi Mitsuro, this title updated on Sep. 15 2009
  2. #Thanx to Dude-X and Twey
  3. #any comments to [email protected]
  4. #some work still needs to be done in the parts marked as:
  5. #*needs to be implemented
  6. #we need a way to do forks and block forks for the AI and a way to judge for a stalemate
  7. #also we need different difficulty levels
  8. import re
  9. import sys #for sys.exit()
  10. class AR():#object that containst the array and methods to handle it
  11.     def __init__(self):#constructor
  12.         self.gameover=False
  13.         self.r=["0","1","2","3","4","5","6","7","8"]
  14.     def print_board(self):
  15.         #Twey>  amigojapan: def print_board(self): print map("-----".join(map("|".join, map(self.row, range(1, 4)))))
  16.         print self.r[0]+"|"+self.r[1]+"|"+self.r[2]
  17.         print "-----"
  18.         print self.r[3]+"|"+self.r[4]+"|"+self.r[5]
  19.         print "-----"
  20.         print self.r[6]+"|"+self.r[7]+"|"+self.r[8]
  21.  
  22.     def place_is_empty(self,place):
  23.         #def place_is_empty(self, place): return self.r[place] in "012345678"
  24.         if self.r[place] in "012345678":
  25.             return True
  26.         else:
  27.             return False
  28.  
  29.         #return self.r[place] in "012345678"
  30.     def get_input(self,letter):
  31.         print "Board for player input"
  32.         self.print_board()
  33.         print "Enter a number for " + letter + " [p]ass [q]uit:"
  34.         notvalid=True
  35.         while notvalid:
  36.             number=raw_input()        
  37.             if number.lower() in "012345678pq" and len(number)==1: #true if number is 0-5 and it must be one number
  38.                 notvalid=False
  39.             else:
  40.                 print "Invalid input"
  41.         #if self.r[int(number)] == "O" or self.r[int(number)] == "X":
  42.         if number.lower() == "p":
  43.             return
  44.         if number.lower() == "q":
  45.             invalidinput = True
  46.             while invalidinput == True:
  47.                 print "press [Q] TO quit the game, [M] to quit this match or [R] to resume game"
  48.                 inp = raw_input()
  49.                 if inp.lower() in "qmr" and len(inp)==1:
  50.                     invalidinput = False
  51.                     if inp.lower() == "q":
  52.                         sys.exit()
  53.                     if inp.lower() == "m":
  54.                         self.gameover=True
  55.                         return
  56.                     if inp.lower() == "r":
  57.                         self.get_input(letter)
  58.                         return
  59.         if not self.place_is_empty(int(number)):
  60.             print "Invalid Move"
  61.             self.get_input(letter)
  62.         else:
  63.             self.r[int(number)] = letter
  64.     def make_free(self,string):
  65.         #>>> p = re.compile( '(blue|white|red)')
  66.         #>>> p.sub( 'colour', 'blue socks and red shoes')
  67.         #'colour socks and colour shoes'
  68.         #>>> p.sub( 'colour', 'blue socks and red shoes', count=1)
  69.         #'colour socks and red shoes'
  70.         #p = re.compile( '[0-8]')
  71.         #p.sub( '-', 'abc1239xmn')
  72.         p = re.compile( '[0-8]')
  73.         return p.sub( '-', string)
  74.     #<Twey> amigojapan: def row(self, n): return self.make_free(sum(self.r[(n - 1) * 3 : (n - 1) * 3 - 1])); def col(self, n): return self.make_free(sum(self.r[n - 1 :: 3]))
  75.     def row1(self):
  76.         return self.make_free(self.r[0]+self.r[1]+self.r[2])
  77.     def row2(self):
  78.         return self.make_free(self.r[3]+self.r[4]+self.r[5])
  79.     def row3(self):
  80.         return self.make_free(self.r[6]+self.r[7]+self.r[8])
  81.     def col1(self):
  82.         return self.make_free(self.r[0]+self.r[3]+self.r[6])
  83.     def col2(self):
  84.         return self.make_free(self.r[1]+self.r[4]+self.r[7])
  85.     def col3(self):
  86.         return self.make_free(self.r[2]+self.r[5]+self.r[8])
  87.     def diag1(self):
  88.         return self.make_free(self.r[0]+self.r[4]+self.r[8])
  89.     def diag2(self):
  90.         return self.make_free(self.r[2]+self.r[4]+self.r[6])
  91.  
  92.     def ai_move(self):
  93.         #1. Win: If you have two in a row, play the third to get three in a row.
  94.         if self.row1()=="XX-":
  95.             self.r[2]="X"
  96.             return
  97.         if self.row1()=="X-X":
  98.             self.r[1]="X"
  99.             return
  100.         if self.row1()=="-XX":
  101.             self.r[0]="X"
  102.             return
  103.        
  104.         if self.row2()=="XX-":
  105.             self.r[5]="X"
  106.             return
  107.         if self.row2()=="X-X":
  108.             self.r[4]="X"
  109.             return
  110.         if self.row2()=="-XX":
  111.             self.r[3]="X"
  112.             return
  113.  
  114.         if self.row3()=="XX-":
  115.             self.r[8]="X"
  116.             return
  117.         if self.row3()=="X-X":
  118.             self.r[7]="X"
  119.             return
  120.         if self.row3()=="-XX":
  121.             self.r[6]="X"
  122.             return
  123.  
  124.         if self.col1()=="XX-":
  125.             self.r[6]="X"
  126.             return
  127.         if self.col1()=="X-X":
  128.             self.r[3]="X"
  129.             return
  130.         if self.col1()=="-XX":
  131.             self.r[0]="X"
  132.             return
  133.        
  134.         if self.col2()=="XX-":
  135.             self.r[7]="X"
  136.             return
  137.         if self.col2()=="X-X":
  138.             self.r[4]="X"
  139.             return
  140.         if self.col2()=="-XX":
  141.             self.r[1]="X"
  142.             return
  143.  
  144.         if self.col3()=="XX-":
  145.             self.r[8]="X"
  146.             return
  147.         if self.col3()=="X-X":
  148.             self.r[5]="X"
  149.             return
  150.         if self.col3()=="-XX":
  151.             self.r[2]="X"
  152.             return
  153.  
  154.         if self.diag1()=="XX-":
  155.             self.r[8]="X"
  156.             return
  157.         if self.diag1()=="X-X":
  158.             self.r[4]="X"
  159.             return
  160.         if self.diag1()=="-XX":
  161.             self.r[0]="X"
  162.             return
  163.  
  164.         if self.diag2()=="XX-":
  165.             self.r[6]="X"
  166.             return
  167.         if self.diag2()=="X-X":
  168.             self.r[4]="X"
  169.             return
  170.         if self.diag2()=="-XX":
  171.             self.r[2]="X"
  172.             return
  173.  
  174.         #2. Block: If the opponent has two in a row, play the third to block them.
  175.  
  176.         if self.row1()=="OO-":
  177.             self.r[2]="X"
  178.             return
  179.         if self.row1()=="O-O":
  180.             self.r[1]="X"
  181.             return
  182.         if self.row1()=="-OO":
  183.             self.r[0]="X"
  184.             return
  185.        
  186.         if self.row2()=="OO-":
  187.             self.r[5]="X"
  188.             return
  189.         if self.row2()=="O-O":
  190.             self.r[4]="X"
  191.             return
  192.         if self.row2()=="-OO":
  193.             self.r[3]="X"
  194.             return
  195.  
  196.         if self.row3()=="OO-":
  197.             self.r[8]="X"
  198.             return
  199.         if self.row3()=="O-O":
  200.             self.r[7]="X"
  201.             return
  202.         if self.row3()=="-OO":
  203.             self.r[6]="X"
  204.             return
  205.  
  206.         if self.col1()=="OO-":
  207.             self.r[6]="X"
  208.             return
  209.         if self.col1()=="O-O":#I think  there is a bug in this option, it didnt play this move when it shouldhave
  210.             self.r[3]="X"
  211.             return
  212.         if self.col1()=="-OO":
  213.             self.r[0]="X"
  214.             return
  215.        
  216.         if self.col2()=="OO-":
  217.             self.r[7]="X"
  218.             return
  219.         if self.col2()=="O-O":
  220.             self.r[4]="X"
  221.             return
  222.         if self.col2()=="-OO":
  223.             self.r[1]="X"
  224.             return
  225.  
  226.         if self.col3()=="OO-":
  227.             self.r[8]="X"
  228.             return
  229.         if self.col3()=="O-O":
  230.             self.r[5]="X"
  231.             return
  232.         if self.col3()=="-OO":
  233.             self.r[2]="X"
  234.             return
  235.        
  236.         if self.diag1()=="OO-":
  237.             self.r[8]="X"
  238.             return
  239.         if self.diag1()=="O-O":
  240.             self.r[4]="X"
  241.             return
  242.         if self.diag1()=="-OO":
  243.             self.r[0]="X"
  244.             return
  245.  
  246.         if self.diag2()=="OO-":
  247.             self.r[6]="X"
  248.             return
  249.         if self.diag2()=="O-O":
  250.             self.r[4]="X"
  251.             return
  252.         if self.diag2()=="-OO":
  253.             self.r[2]="X"
  254.             return
  255.  
  256.         #3. Fork: Create an opportunity where you can win in two ways.
  257.         #*needs to be implemented
  258.         #4. Block Opponent's Fork:
  259.         #    Option 1: Create two in a row to force the opponent into defending, as long as it doesn't result in them creating a fork or winning. For example, if "X" has a corner, "O" has the center, and "X" has the opposite corner as well, "O" must not play a corner in order to win. (Playing a corner in this scenario creates a fork for "X" to win.)
  260.         #    Option 2: If there is a configuration where the opponent can fork, block that fork.
  261.         #*needs to be implemented
  262.         #5. Center: Play the center.
  263.         if self.place_is_empty(4):
  264.             self.r[4]="X"
  265.             return
  266.            
  267.         #6. Opposite Corner: If the opponent is in the corner, play the opposite corner.
  268.         if self.row1()=="O--":
  269.             self.r[2]="X"
  270.             return
  271.         if self.row1()=="--O":
  272.             self.r[0]="X"
  273.             return
  274.         if self.row2()=="O--":
  275.             self.r[5]="X"
  276.             return
  277.         if self.row2()=="--O":
  278.             self.r[3]="X"
  279.             return
  280.         if self.row3()=="O--":
  281.             self.r[8]="X"
  282.             return
  283.         if self.row3()=="--O":
  284.             self.r[6]="X"
  285.             return
  286.  
  287.         if self.col1()=="O--":
  288.             self.r[6]="X"
  289.             return
  290.         if self.col1()=="--O":
  291.             self.r[0]="X"
  292.             return        
  293.         if self.col2()=="O--":
  294.             self.r[7]="X"
  295.             return
  296.         if self.col2()=="--O":
  297.             self.r[1]="X"
  298.             return        
  299.         if self.col3()=="O--":
  300.             self.r[8]="X"
  301.             return
  302.         if self.col3()=="--O":
  303.             self.r[2]="X"
  304.             return
  305.         if self.diag1()=="O--":
  306.             self.r[8]="X"
  307.             return        
  308.         if self.diag1()=="--O":
  309.             self.r[0]="X"
  310.             return        
  311.         if self.diag2()=="O--":
  312.             self.r[6]="X"
  313.             return        
  314.         if self.diag2()=="--O":
  315.             self.r[2]="X"
  316.             return        
  317.        
  318.         #7. Empty Corner: Play an empty corner.
  319.         if self.place_is_empty(0):
  320.             self.r[0]="X"
  321.             return
  322.         if self.place_is_empty(2):
  323.             self.r[2]="X"
  324.             return
  325.         if self.place_is_empty(6):
  326.             self.r[6]="X"
  327.             return
  328.         if self.place_is_empty(8):
  329.             self.r[8]="X"
  330.             return
  331.        
  332.         #8. Empty Side: Play an empty side.
  333.         if self.place_is_empty(1):
  334.             self.r[1]="X"
  335.             return
  336.         if self.place_is_empty(3):
  337.             self.r[3]="X"
  338.             return
  339.         if self.place_is_empty(5):
  340.             self.r[5]="X"
  341.             return
  342.         if self.place_is_empty(7):
  343.             self.r[7]="X"
  344.             return
  345.        
  346.         #9 error, shouldn't reach this part with a perfect AI, I think.
  347.         print "Error AI didn't make any move"
  348.     def prompt_gameover(self):
  349.         print "Game Over"
  350.         invalidinput = True
  351.         while invalidinput == True:
  352.             print "Play again? [Y] or [N]:"
  353.             inp = raw_input()
  354.             if inp.lower() in "yn" and len(inp)==1:
  355.                 invalidinput = False
  356.                 if inp.lower() == "y":
  357.                     self.gameover=True
  358.                     return
  359.                 if inp.lower() == "n":
  360.                     sys.exit()
  361.        
  362.     def  judge(self):
  363.         #check to see if board is full
  364.         counter=0
  365.         for a in range (0, 9):
  366.             if self.place_is_empty(a):
  367.                 counter=counter+1
  368.         #print "counter " +str(counter)
  369.         if counter == 0:
  370.             self.prompt_gameover()
  371.             if self.gameover==True:
  372.                 return
  373.         #check for 3 in a row
  374.         if self.row1()=="OOO":
  375.             print "Player O wins"
  376.             self.prompt_gameover()
  377.         if self.row1()=="XXX":
  378.             print "Player X wins"
  379.             self.prompt_gameover()
  380.         if self.row2()=="OOO":
  381.             print "Player O wins"
  382.             self.prompt_gameover()
  383.         if self.row2()=="XXX":
  384.             print "Player X wins"
  385.             self.prompt_gameover()
  386.         if self.row3()=="OOO":
  387.             print "Player O wins"
  388.             self.prompt_gameover()
  389.         if self.row3()=="XXX":
  390.             print "Player X wins"
  391.             self.prompt_gameover()
  392.  
  393.         if self.col1()=="OOO":
  394.             print "Player O wins"
  395.             self.prompt_gameover()
  396.         if self.col1()=="XXX":
  397.             print "Player X wins"
  398.             self.prompt_gameover()
  399.         if self.col2()=="OOO":
  400.             print "Player O wins"
  401.             self.prompt_gameover()
  402.         if self.col2()=="XXX":
  403.             print "Player X wins"
  404.             self.prompt_gameover()
  405.         if self.col3()=="OOO":
  406.             print "Player O wins"
  407.             self.prompt_gameover()
  408.         if self.col3()=="XXX":
  409.             print "Player X wins"
  410.             self.prompt_gameover()
  411.         if self.diag1()=="OOO":
  412.             print "Player O wins"
  413.             self.prompt_gameover()
  414.         if self.diag1()=="XXX":
  415.             print "Player X wins"
  416.             self.prompt_gameover()
  417.         if self.diag2()=="OOO":
  418.             print "Player O wins"
  419.             self.prompt_gameover()
  420.         if self.diag2()=="XXX":
  421.             print "Player X wins"
  422.             self.prompt_gameover()
  423.         #Judge stale mate
  424.         #*needs to be implemented
  425. if __name__ == "__main__":            
  426.     ar=AR()#create instance that contains the arrayfrom array object,initialize game array in constructor
  427.     endgame=False
  428.     while endgame==False:
  429.         ar.__init__()
  430.         ar.gameover=False
  431.         invalidinput = True
  432.         while invalidinput == True:
  433.             print "Play 2 players or against computer [2] or [c]:"
  434.             inp = raw_input()
  435.             if inp.lower() in "2c" and len(inp)==1:
  436.                 invalidinput = False
  437.                 if inp.lower() == "2":
  438.                     gametype = "2player"
  439.                 if inp.lower() == "c":
  440.                     gametype = "computer"
  441.         while ar.gameover==False:
  442.             ar.get_input("O")#prompt and get user input, validate and enter data
  443.             if ar.gameover==True:
  444.                 continue
  445.             print "Judging game"#judge to see if it is game over, who wins and tie(stale mate)
  446.             ar.judge()
  447.             if ar.gameover==True:
  448.                 continue
  449.             print "Board after player move"
  450.             ar.print_board()#Show output for the users move
  451.            
  452.             #ar.get_input("X")#temporary function for testing AI or use for 2 player game
  453.             #ar.ai_move()
  454.             if gametype == "2player":
  455.                 ar.get_input("X")
  456.                 if ar.gameover==True:
  457.                     continue
  458.                 print "Board after player X's move"
  459.             if gametype == "computer":
  460.                 print "computer calculating move..."#calculate computer's move
  461.                 ar.ai_move()
  462.                 print "Board after computer move"
  463.             ar.print_board()#show computers move
  464.             print "Judging game"#judge to see if it is game over, who wins and tie(stale mate)
  465.             ar.judge()
Advertisement
Add Comment
Please, Sign In to add comment