Advertisement
SMASIF

Tic Tac Toe

Dec 6th, 2017
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.01 KB | None | 0 0
  1. import random
  2. import pickle
  3. import itertools
  4.  
  5. def resetGame():
  6.     """This function sets the game properties to default, mainly used when the user wants to start a new game"""
  7.    
  8.     global base,play,count,finalResult,breaking,saved_games,gameplay,player_lastmove,comp_lastmove
  9.    
  10.     base = ["0","1","2","3","4","5","6","7","8"] #Base is the game board
  11.     play = []  #This list will contain x and o. so play[0] is always player 1's choice and play[1] is the opponent.
  12.     count = [0,1]  #count[0] keeps a track of the number of moves made by both players in a game. count[1] is used for printing the list of saved games when user selects the option to continue a game.
  13.     finalResult = "none"  #By default it will be none, but if a player wins it will change to "won" or if its a tie it will be changed to "tie"
  14.     breaking = False  #used for breaking out of the bigger loops in one and two player game functions.
  15.     saved_games = {}
  16.     gameplay = ["n","playerturn","gamemode","default_game_name","difficulty"]
  17.     player_lastmove = [] #this list stores all the moves made by the player
  18.     comp_lastmove= []
  19.    
  20.     ##########################################################################################################################################
  21.     #                                           GAME PROPERTIES EXPLANINED (gameplay list)
  22.    
  23.     #gameplay[0] is to store the game type, if it is a continued game it will be "y" else it's "n"
  24.     #gameplay[1] keeps a track of the turns. if its player 1's turn it will be "p1", for player 2 "p2", and for computer "comp"
  25.     #gameplay[2] stores the game mode. if its 1 player mode it will be "1p" or for 2 player it will be "2p"
  26.     #gameplay[3] stores the game name (if it has one), which will be used for saving the game (the key for an entry in save_games dictionary)
  27.     #gameplay[4] stroes the game difficulty. it will vary from "EASY", "MEDIUM", "IMPOSSIBLE"
  28.    
  29.     ##########################################################################################################################################
  30.  
  31.  
  32.        
  33. def returntoMenu():
  34.     """This function asks the user if they want to run the program from start again"""
  35.     while True:
  36.         goback = input("Do you want to go back to main Menu? (y/n)\n")
  37.         if goback == "y":
  38.             StartGame()
  39.             break
  40.         elif goback == "n":
  41.             print("\n---------- GAME CLOSED ----------\n")
  42.             break          
  43.         else:
  44.             print("Invalid entry. Enter y or n only.")
  45.    
  46. def printgameBoard():
  47.     """This function is used to print the game board after every move"""
  48.     print((base[0] + " | " + base[1] + " | " + base[2]).center(34))
  49.     print("-----------".center(34))
  50.     print((base[3] + " | " + base[4] + " | " + base[5]).center(34))
  51.     print("-----------".center(34))
  52.     print((base[6] + " | " + base[7] + " | " + base[8]).center(34))
  53.     print("\n")
  54.    
  55.  
  56. def gameMenu():
  57.     """ This function is used to print the game menu and it outputs the user selected option"""
  58.     print("-----------------------------------")
  59.     print(("TIC TAC TOE GAME\n"))
  60.     print("(1) Start Game ")
  61.     print("(2) Exit \n")
  62.     while True:      
  63.         try:
  64.             option = int(input("Select an option: "))
  65.             if option<=3 and option >0:
  66.                 print("-----------------------------------")
  67.                 return option
  68.             elif option == 4:
  69.                 return option
  70.             else:
  71.                 print("Invalid Option. Please try again.\n")
  72.                                      
  73.         except ValueError:
  74.             print("Invalid Option. Please try again.\n")
  75.  
  76.  
  77. def askMove(player):
  78.     """ This function is used for asking player 1 or player 2 where they want to place their move.
  79.        Input is either 1 or 2 as an integer only """
  80.     if player == 1:
  81.         string = "Player 1: "
  82.         number = 0
  83.     elif player == 2:
  84.         string = "Player 2: "
  85.         number = 1
  86.  
  87.     while True:
  88.         try:
  89.             print("Tip: Enter 11 to Save game")
  90.             selectedlocation = int(input(string+"Where do you want to place "+play[number]+"?\n"))
  91.             return selectedlocation
  92.             break
  93.         except ValueError:
  94.             print("Invalid entry.")
  95.             print("Only numbers should be entered.")
  96.             print("Please try again. \n")
  97.  
  98.  
  99.        
  100. def player1Move():
  101.     """This function is called when its Player 1's turn to make a move."""
  102.     while True:
  103.         selectedlocation = askMove(1)
  104.         if selectedlocation >=0 and selectedlocation <=8:
  105.             n = selectedlocation
  106.             if availability(n) == "y":
  107.                 base[n] = play[0]
  108.                 count[0] = count[0]+1
  109.                 player_lastmove.append(n)
  110.                 print("\n")
  111.                 break
  112.             else:
  113.                 print("It is not possible to place "+play[0]+" there.")
  114.                 print("Please try again. \n")
  115.  
  116.         elif selectedlocation == 11:
  117.             if gameplay[0] == "y":
  118.                 while True:
  119.                     overwrite = input("Do you want to overwrite the existing saved file? (y/n) \n")
  120.                     if overwrite == "y":
  121.                         saveGame("yes")
  122.                         break
  123.                     elif overwrite == "n":
  124.                         saveGame("no")
  125.                         break
  126.                     else:
  127.                         print("Invalid entry. Enter y or n only.")
  128.                 break
  129.             else:
  130.                 saveGame("no")
  131.                 break
  132.            
  133.  
  134.         else:
  135.             print("It is not possible to place "+play[0]+" there.")
  136.             print("Only the numbers shown on the board are possible.")
  137.             print("Please try again. \n")
  138.    
  139. def selectAI_level():
  140.     """ This funcion asks the user to select a Computer Level """
  141.     print("Choose the difficulty level of computer: \n")
  142.     print("(1) Easy")
  143.     print("(2) Medium")
  144.     print("(3) Impossible")
  145.     while True:
  146.         try:
  147.             option = int(input("\nChoice: ")) #Stores the choosen level in gameplay[4]
  148.             if option == 1:
  149.                 gameplay[4] = "EASY"  
  150.                 return
  151.             elif option == 2:
  152.                 gameplay[4] = "MEDIUM"
  153.                 return
  154.             elif option == 3:
  155.                 gameplay[4] = "IMPOSSIBLE"
  156.                 return
  157.             else:
  158.                 print("Invalid Option. Please try again.")
  159.         except ValueError:
  160.             print("Invalid Option. Please try again.")
  161.  
  162. def x_or_o():
  163.     """ This function is used by player 1 to select either x or o and in this game x always makes the first move"""
  164.     while True:
  165.         selection = input("Player 1: Pick one x or o?\n")
  166.         if selection == "x":
  167.             play.append(selection)
  168.             play.append("o")
  169.             gameplay[1] = "p1"
  170.             break
  171.         elif selection == "o":
  172.             play.append(selection)
  173.             play.append("x")
  174.             if gameplay[2] == "1p":
  175.                 gameplay[1] = "comp"
  176.             else:
  177.                 gameplay[1] = "p2"
  178.             break
  179.         else:
  180.             print("Enter x or o in lower case only. \n")
  181.        
  182.        
  183. def availability(n):
  184.     """ This function is used to check if a spot in the board is empty (available) or not. Its input is the number of the location (integer)
  185.        and outputs "y" it is available else "n" """
  186.     if base[n] == "x" or base[n] == "o":
  187.         return "n"
  188.     else:
  189.         return "y"
  190.  
  191.  
  192.  
  193.    
  194.        
  195.  
  196.  
  197.    
  198.  
  199. def AI_corner():
  200.     """This function is returns a move which is in one of the corners in the board"""
  201.     while True:
  202.         corners = [0,2,6,8]
  203.         move = corners[random.randint(0,3)]
  204.         if availability(move) == "y":
  205.             return move
  206.        
  207. def AI_Impossible():
  208.     """This function returns a move by the computer and it is called everytime when its the computers turn,
  209.       only when the user sets the difficulty level to IMPOSSIBLE."""
  210.    
  211.     if count[0]<=2: #when less than or equal to 2 moves played on board
  212.         if play[1]=="o":
  213.             if player_lastmove[0]!=4:
  214.                 return 4
  215.             else:
  216.                 move = AI_corner()
  217.                 return move
  218.         else:
  219.             if len(player_lastmove)==1 and availability(4) == "y":
  220.                 return 4
  221.             elif availability(4) == "y":
  222.                 return 4
  223.             else:
  224.                 move = AI_corner()
  225.                 return move
  226.            
  227.     if count[0]>2: #when greater than two moves played on board
  228.         for i in range(0,len(AI)):
  229.             (move1,move2,move3) = (AI[i])
  230.             if base[move1] == play[1] and base[move2] == play[1]: #Attacking
  231.                 if availability(move3)=="y":
  232.                     return move3
  233.  
  234.         for i in range(0,len(AI)):
  235.             (move1,move2,move3) = (AI[i])
  236.             if base[move1]==play[0] and base[move2] == play[0]:  #Defensive
  237.                 if availability(move3) == "y":  #if the 3rd likely move position is not occupied by player 0
  238.                     return move3
  239.                
  240.         if count[0] == 3 and play[0] == "x": #to block any tricky play
  241.             if base[5] == "x" and (base[1] == "x" or base[0] == "x"):
  242.                 return 2
  243.             elif base[5] =="x" and base[7] == "x":
  244.                 return 8
  245.             elif base[1] == "x" and base[6] == "x":
  246.                 return 0
  247.             elif base[6] == "x" and base[5] == "x":
  248.                 return 8
  249.             elif comp_lastmove[0] == 4 and availability(3) == "y":
  250.                 return 3
  251.  
  252.         for i in range(0,len(AI)):
  253.             (move1,move2,move3) = (AI[i])
  254.             if base[move1] == play[0] and (move2 in [0,2,6,8]) and availability(move2)=="y": #to block any tricky play
  255.                 return move2
  256.            
  257.    
  258.         for i in range(0,len(AI)):
  259.             (move1,move2,move3) = (AI[i])
  260.             if move1 == play[1]: #creating chance for a win
  261.                 if availability(move2) == "y":
  262.                     return move2
  263.             else: #If there is no chance of anyone winning, then a random move will be made
  264.                 while True:
  265.                     move = random.randint(0,8)
  266.                     if availability(move) == "y":
  267.                         return move
  268.  
  269. def AI_Easy():
  270.     """This function returns a move by the computer and it is called everytime when its the computers turn,
  271.       only when the user sets the difficulty level to EASY."""
  272.     for i in range(0,len(AI)):
  273.         (move1,move2,move3) = (AI[i])
  274.         if base[move1] == play[1] and base[move2] == play[1]: #Attacking
  275.             if availability(move3)=="y":
  276.                 return move3
  277.     while True:
  278.         move = random.randint(0,8)
  279.         if availability(move) == "y":
  280.             return move
  281.  
  282. def AI_Medium():
  283.     """This function returns a move by the computer and it is called everytime when its the computers turn,
  284.       only when the user sets the difficulty level to MEDIUM."""
  285.     for i in range(0,len(AI)):
  286.         (move1,move2,move3) = (AI[i])
  287.         if base[move1] == play[1] and base[move2] == play[1]: #Attacking
  288.             if availability(move3)=="y":
  289.                 return move3
  290.            
  291.     for i in range(0,len(AI)):
  292.         (move1,move2,move3) = (AI[i])
  293.         if base[move1] == play[0] and base[move2] == play[0]: #Defense
  294.             if availability(move3)=="y":
  295.                 return move3
  296.         elif availability(move1) == "y" and move1 in [0,2,6,8]:
  297.             return move1
  298.  
  299.     while True:
  300.         move = random.randint(0,8)
  301.         if availability(move) == "y":
  302.             return move
  303.        
  304.        
  305. def computerMove():
  306.     """This function is called when its computer's turn to make a move."""
  307.     if gameplay[4] == "IMPOSSIBLE":
  308.         move = AI_Impossible()
  309.         base[move] = play[1]
  310.         comp_lastmove.append(move)
  311.         count[0] = count[0] + 1      
  312.     elif gameplay[4] == "MEDIUM":
  313.         move = AI_Medium()
  314.         base[move] = play[1]
  315.         count[0] = count[0]+1
  316.     else:
  317.         move = AI_Easy()
  318.         base[move] = play[1]
  319.         count[0] = count[0]+1
  320.        
  321.            
  322.  
  323. def compAI():
  324.     """This function is used to make a list of the possible combinations of the winning moves.
  325.       It is called only once, when the user selects a one player game."""
  326.     global AI
  327.     winMoves = [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(2,4,6),(0,4,8)]
  328.     PossibleWins = []
  329.     for i in range(0,len(winMoves)):
  330.         PossibleWins.append(list(itertools.permutations(winMoves[i])))
  331.        
  332.     AI = list(itertools.chain.from_iterable(PossibleWins))
  333.      
  334. def checkWin(n):
  335.     """This function checks if x or o has won and also if its a tie.
  336.       function input is "x" or "o" string.
  337.       It returns "y" if a player wins, or "t" if its a tie, else "n".
  338.       which will be used in further parts of the program."""
  339.    
  340.     if base[0] == n and base[1] == n and base[2]==n:
  341.         return "y"
  342.     elif base[3] == n and base[4] == n and base[5]==n:
  343.         return "y"
  344.     elif base[6] == n and base[7] == n and base[8]==n:
  345.         return "y"
  346.     elif base[0] == n and base[3] == n and base[6]==n:
  347.         return "y"
  348.     elif base[1] == n and base[4] == n and base[7]==n:
  349.         return "y"
  350.     elif base[2] == n and base[5] == n and base[8]==n:
  351.         return "y"
  352.     elif base[2] == n and base[4] == n and base[6]==n:
  353.         return "y"
  354.     elif base[0] == n and base[4] == n and base[8]==n:
  355.         return "y"
  356.     elif count[0] == 9:
  357.         return "t"
  358.     else:
  359.         return "n"
  360.  
  361.  
  362. def Result(player):
  363.     """ This function is final check for a win, main purpose is to break the flow of the 1p and 2p games
  364.        and print a clear winning message.
  365.        function input is "x" or "o" string."""
  366.     global breaking,finalResult
  367.     result = checkWin(player)
  368.     if result=="y":
  369.         finalResult = "won"
  370.         printgameBoard()
  371.         breaking = True
  372.         #delgame()
  373.     elif result == "t":
  374.         printgameBoard()
  375.         finalResult = "tie"
  376.         breaking = True
  377.         #delgame()
  378.     else:
  379.         pass
  380.  
  381.  
  382. def onePlayerEnd():
  383.     """This function is used for printing the "one player game ended" message."""
  384.     print("\n--------- 1P GAME ENDED ---------\n")
  385.  
  386.  
  387.  
  388.    
  389. def onePlayerGame():
  390.     """This function sets the program flow of a one player game."""
  391.     print(("  AI LEVEL: "+gameplay[4]+"\n").center(34))
  392.     compAI()
  393.     while count[0]<=9:
  394.         if gameplay[1] == "p1":
  395.             printgameBoard()
  396.             gameplay[1] = "p1"
  397.             player1Move()
  398.             Result(play[0])
  399.             if breaking == True:
  400.                 if finalResult == "tie":
  401.                     print(("It is a tie!").center(34))
  402.                 elif finalResult == "won":
  403.                     print(("Player 1 ("+play[0]+") wins!").center(34))
  404.                 onePlayerEnd()
  405.                 returntoMenu()
  406.                 break
  407.             else:
  408.                 gameplay[1] = "comp"
  409.         else:
  410.             gameplay[1] = "comp"
  411.             computerMove()
  412.             Result(play[1])
  413.             if breaking == True:
  414.                 if finalResult == "tie":
  415.                     print(("It is a tie!").center(34))
  416.                 elif finalResult == "won":
  417.                     print(("Computer ("+play[1]+") wins!").center(34))
  418.                 onePlayerEnd()
  419.                 returntoMenu()
  420.                 break
  421.             else:
  422.                 gameplay[1] = "p1"
  423.  
  424.  
  425.    
  426. def StartGame():
  427.     """This function is used to start the program"""
  428.     option = gameMenu()
  429.     resetGame()
  430.     if option== 1:
  431.         gameplay[2] = "1p"
  432.         selectAI_level()
  433.         x_or_o()
  434.         print("\n--------- 1P GAME STARTED ---------\n")
  435.         onePlayerGame()
  436.                                        
  437.     else:
  438.         print("\n----------- TIC TAC TOE CLOSED -----------\n")
  439.  
  440.  
  441.  
  442. StartGame()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement