Advertisement
SMASIF

AI Tic Tac Toe

Dec 6th, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.13 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.             selectedlocation = int(input(string+"Where do you want to place "+play[number]+"?\n"))
  90.             return selectedlocation
  91.             break
  92.         except ValueError:
  93.             print("Invalid entry.")
  94.             print("Only numbers should be entered.")
  95.             print("Please try again. \n")
  96.  
  97.  
  98.        
  99. def player1Move():
  100.     """This function is called when its Player 1's turn to make a move."""
  101.     while True:
  102.         selectedlocation = askMove(1)
  103.         if selectedlocation >=0 and selectedlocation <=8:
  104.             n = selectedlocation
  105.             if availability(n) == "y":
  106.                 base[n] = play[0]
  107.                 count[0] = count[0]+1
  108.                 player_lastmove.append(n)
  109.                 print("\n")
  110.                 break
  111.             else:
  112.                 print("It is not possible to place "+play[0]+" there.")
  113.                 print("Please try again. \n")
  114.            
  115.    
  116. def selectAI_level():
  117.     """ This funcion asks the user to select a Computer Level """
  118.     print("Choose the difficulty level of computer: \n")
  119.     print("(1) Easy")
  120.     print("(2) Medium")
  121.     print("(3) Impossible")
  122.     while True:
  123.         try:
  124.             option = int(input("\nChoice: ")) #Stores the choosen level in gameplay[4]
  125.             if option == 1:
  126.                 gameplay[4] = "EASY"  
  127.                 return
  128.             elif option == 2:
  129.                 gameplay[4] = "MEDIUM"
  130.                 return
  131.             elif option == 3:
  132.                 gameplay[4] = "IMPOSSIBLE"
  133.                 return
  134.             else:
  135.                 print("Invalid Option. Please try again.")
  136.         except ValueError:
  137.             print("Invalid Option. Please try again.")
  138.  
  139. def x_or_o():
  140.     """ This function is used by player 1 to select either x or o and in this game x always makes the first move"""
  141.     while True:
  142.         selection = input("Player 1: Pick one x or o?\n")
  143.         if selection == "x":
  144.             play.append(selection)
  145.             play.append("o")
  146.             gameplay[1] = "p1"
  147.             break
  148.         elif selection == "o":
  149.             play.append(selection)
  150.             play.append("x")
  151.             if gameplay[2] == "1p":
  152.                 gameplay[1] = "comp"
  153.             else:
  154.                
  155.              break
  156.         else:
  157.             print("Enter x or o in lower case only. \n")
  158.        
  159.        
  160. def availability(n):
  161.     """ 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)
  162.        and outputs "y" it is available else "n" """
  163.     if base[n] == "x" or base[n] == "o":
  164.         return "n"
  165.     else:
  166.         return "y"
  167.  
  168.  
  169.  
  170.    
  171.        
  172.  
  173.  
  174.    
  175.  
  176. def AI_corner():
  177.     """This function is returns a move which is in one of the corners in the board"""
  178.     while True:
  179.         corners = [0,2,6,8]
  180.         move = corners[random.randint(0,3)]
  181.         if availability(move) == "y":
  182.             return move
  183.        
  184. def AI_Impossible():
  185.     """This function returns a move by the computer and it is called everytime when its the computers turn,
  186.       only when the user sets the difficulty level to IMPOSSIBLE."""
  187.    
  188.     if count[0]<=2: #when less than or equal to 2 moves played on board
  189.         if play[1]=="o":
  190.             if player_lastmove[0]!=4:
  191.                 return 4
  192.             else:
  193.                 move = AI_corner()
  194.                 return move
  195.         else:
  196.             if len(player_lastmove)==1 and availability(4) == "y":
  197.                 return 4
  198.             elif availability(4) == "y":
  199.                 return 4
  200.             else:
  201.                 move = AI_corner()
  202.                 return move
  203.            
  204.     if count[0]>2: #when greater than two moves played on board
  205.         for i in range(0,len(AI)):
  206.             (move1,move2,move3) = (AI[i])
  207.             if base[move1] == play[1] and base[move2] == play[1]: #Attacking
  208.                 if availability(move3)=="y":
  209.                     return move3
  210.  
  211.         for i in range(0,len(AI)):
  212.             (move1,move2,move3) = (AI[i])
  213.             if base[move1]==play[0] and base[move2] == play[0]:  #Defensive
  214.                 if availability(move3) == "y":  #if the 3rd likely move position is not occupied by player 0
  215.                     return move3
  216.                
  217.         if count[0] == 3 and play[0] == "x": #to block any tricky play
  218.             if base[5] == "x" and (base[1] == "x" or base[0] == "x"):
  219.                 return 2
  220.             elif base[5] =="x" and base[7] == "x":
  221.                 return 8
  222.             elif base[1] == "x" and base[6] == "x":
  223.                 return 0
  224.             elif base[6] == "x" and base[5] == "x":
  225.                 return 8
  226.             elif comp_lastmove[0] == 4 and availability(3) == "y":
  227.                 return 3
  228.  
  229.         for i in range(0,len(AI)):
  230.             (move1,move2,move3) = (AI[i])
  231.             if base[move1] == play[0] and (move2 in [0,2,6,8]) and availability(move2)=="y": #to block any tricky play
  232.                 return move2
  233.            
  234.    
  235.         for i in range(0,len(AI)):
  236.             (move1,move2,move3) = (AI[i])
  237.             if move1 == play[1]: #creating chance for a win
  238.                 if availability(move2) == "y":
  239.                     return move2
  240.             else: #If there is no chance of anyone winning, then a random move will be made
  241.                 while True:
  242.                     move = random.randint(0,8)
  243.                     if availability(move) == "y":
  244.                         return move
  245.  
  246. def AI_Easy():
  247.     """This function returns a move by the computer and it is called everytime when its the computers turn,
  248.       only when the user sets the difficulty level to EASY."""
  249.     for i in range(0,len(AI)):
  250.         (move1,move2,move3) = (AI[i])
  251.         if base[move1] == play[1] and base[move2] == play[1]: #Attacking
  252.             if availability(move3)=="y":
  253.                 return move3
  254.     while True:
  255.         move = random.randint(0,8)
  256.         if availability(move) == "y":
  257.             return move
  258.  
  259. def AI_Medium():
  260.     """This function returns a move by the computer and it is called everytime when its the computers turn,
  261.       only when the user sets the difficulty level to MEDIUM."""
  262.     for i in range(0,len(AI)):
  263.         (move1,move2,move3) = (AI[i])
  264.         if base[move1] == play[1] and base[move2] == play[1]: #Attacking
  265.             if availability(move3)=="y":
  266.                 return move3
  267.            
  268.     for i in range(0,len(AI)):
  269.         (move1,move2,move3) = (AI[i])
  270.         if base[move1] == play[0] and base[move2] == play[0]: #Defense
  271.             if availability(move3)=="y":
  272.                 return move3
  273.         elif availability(move1) == "y" and move1 in [0,2,6,8]:
  274.             return move1
  275.  
  276.     while True:
  277.         move = random.randint(0,8)
  278.         if availability(move) == "y":
  279.             return move
  280.        
  281.        
  282. def computerMove():
  283.     """This function is called when its computer's turn to make a move."""
  284.     if gameplay[4] == "IMPOSSIBLE":
  285.         move = AI_Impossible()
  286.         base[move] = play[1]
  287.         comp_lastmove.append(move)
  288.         count[0] = count[0] + 1      
  289.     elif gameplay[4] == "MEDIUM":
  290.         move = AI_Medium()
  291.         base[move] = play[1]
  292.         count[0] = count[0]+1
  293.     else:
  294.         move = AI_Easy()
  295.         base[move] = play[1]
  296.         count[0] = count[0]+1
  297.        
  298.            
  299.  
  300. def compAI():
  301.     """This function is used to make a list of the possible combinations of the winning moves.
  302.       It is called only once, when the user selects a one player game."""
  303.     global AI
  304.     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)]
  305.     PossibleWins = []
  306.     for i in range(0,len(winMoves)):
  307.         PossibleWins.append(list(itertools.permutations(winMoves[i])))
  308.        
  309.     AI = list(itertools.chain.from_iterable(PossibleWins))
  310.      
  311. def checkWin(n):
  312.     """This function checks if x or o has won and also if its a tie.
  313.       function input is "x" or "o" string.
  314.       It returns "y" if a player wins, or "t" if its a tie, else "n".
  315.       which will be used in further parts of the program."""
  316.    
  317.     if base[0] == n and base[1] == n and base[2]==n:
  318.         return "y"
  319.     elif base[3] == n and base[4] == n and base[5]==n:
  320.         return "y"
  321.     elif base[6] == n and base[7] == n and base[8]==n:
  322.         return "y"
  323.     elif base[0] == n and base[3] == n and base[6]==n:
  324.         return "y"
  325.     elif base[1] == n and base[4] == n and base[7]==n:
  326.         return "y"
  327.     elif base[2] == n and base[5] == n and base[8]==n:
  328.         return "y"
  329.     elif base[2] == n and base[4] == n and base[6]==n:
  330.         return "y"
  331.     elif base[0] == n and base[4] == n and base[8]==n:
  332.         return "y"
  333.     elif count[0] == 9:
  334.         return "t"
  335.     else:
  336.         return "n"
  337.  
  338.  
  339. def Result(player):
  340.     """ This function is final check for a win, main purpose is to break the flow of the 1p and 2p games
  341.        and print a clear winning message.
  342.        function input is "x" or "o" string."""
  343.     global breaking,finalResult
  344.     result = checkWin(player)
  345.     if result=="y":
  346.         finalResult = "won"
  347.         printgameBoard()
  348.         breaking = True
  349.         #delgame()
  350.     elif result == "t":
  351.         printgameBoard()
  352.         finalResult = "tie"
  353.         breaking = True
  354.         #delgame()
  355.     else:
  356.         pass
  357.  
  358.  
  359. def onePlayerEnd():
  360.     """This function is used for printing the "one player game ended" message."""
  361.     print("\n--------- 1P GAME ENDED ---------\n")
  362.  
  363.  
  364.  
  365.    
  366. def onePlayerGame():
  367.     """This function sets the program flow of a one player game."""
  368.     print(("  AI LEVEL: "+gameplay[4]+"\n").center(34))
  369.     compAI()
  370.     while count[0]<=9:
  371.         if gameplay[1] == "p1":
  372.             printgameBoard()
  373.             gameplay[1] = "p1"
  374.             player1Move()
  375.             Result(play[0])
  376.             if breaking == True:
  377.                 if finalResult == "tie":
  378.                     print(("It is a tie!").center(34))
  379.                 elif finalResult == "won":
  380.                     print(("Player 1 ("+play[0]+") wins!").center(34))
  381.                 onePlayerEnd()
  382.                 returntoMenu()
  383.                 break
  384.             else:
  385.                 gameplay[1] = "comp"
  386.         else:
  387.             gameplay[1] = "comp"
  388.             computerMove()
  389.             Result(play[1])
  390.             if breaking == True:
  391.                 if finalResult == "tie":
  392.                     print(("It is a tie!").center(34))
  393.                 elif finalResult == "won":
  394.                     print(("Computer ("+play[1]+") wins!").center(34))
  395.                 onePlayerEnd()
  396.                 returntoMenu()
  397.                 break
  398.             else:
  399.                 gameplay[1] = "p1"
  400.  
  401.  
  402.    
  403. def StartGame():
  404.     """This function is used to start the program"""
  405.     option = gameMenu()
  406.     resetGame()
  407.     if option== 1:
  408.         gameplay[2] = "1p"
  409.         selectAI_level()
  410.         x_or_o()
  411.         print("\n--------- 1P GAME STARTED ---------\n")
  412.         onePlayerGame()
  413.                                        
  414.     else:
  415.         print("\n----------- TIC TAC TOE CLOSED -----------\n")
  416.  
  417.  
  418.  
  419. StartGame()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement