SHARE
TWEET

Untitled

a guest Nov 19th, 2019 78 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #   The primary exercise I want you to try and do is  noughts and crosses (tic tac toe).
  2. #   In this exercise I want you to draw the board as follows:
  3. #    1 | 2 | 3
  4. #   ---+---+----
  5. #    4 | 5 | 6
  6. #   ---+---+----
  7. #    7 | 8 | 9
  8.  
  9. #   The user will always be crosses. Ask the user to choose a square to play.
  10. #   Make sure the square is a valid square, I.E.: not occupied and within the range
  11. #   After each valid move by the user have the computer play a move (random).
  12. #   You can use the pythons random module for this. Everytime both players have made a move draw the state of the board again. And after #  each move check if the user or the computer has won.
  13.  
  14. import random
  15.  
  16.     ##      coordinates
  17.     ##          [0,0 0,1 0,2]
  18.     ##          [1,0 1,1 1,2]
  19.     ##          [2,0 2,1 2,2]
  20.  
  21. #grid_values = [["1", "2", "3"],
  22. #               ["4", "5", "6"],
  23. #               ["7", "8", "9"]]
  24.  
  25. # test grid
  26. grid_values = [["X", "X", "3"],
  27.                 ["4", "5", "O"],
  28.                 ["X", "O", "O"]]
  29.  
  30. game_over = 0
  31.  
  32.  
  33. def checkGrid(gv, move):
  34.  
  35.     #print "checking position:", move
  36.     #print "position contains:", gv[move[0]][move[1]]
  37.  
  38.     if gv[move[0]][move[1]] == "X" or gv[move[0]][move[1]] == "O":
  39.         #print "occupied"
  40.         return 1
  41.  
  42.     else:
  43.         #print "empty"
  44.         return 0
  45.  
  46. def drawGrid(gv, win=0, wh=[[" ", " ", " "],
  47.                     [" ", " ", " "],
  48.                     [" ", " ", " "]],
  49.                 wv=[[" ", " ", " "],
  50.                     [" ", " ", " "],
  51.                     [" ", " ", " "]],
  52.                 wd=[" ", " ", " ", " "]):
  53.  
  54.     if win == "1":
  55.         print "Player has won the game!"
  56.  
  57.     if win == "2":
  58.         print "Computer has won the game!"
  59.  
  60.     print "\n", wd[0], wv[0][0], " ", wv[0][1], " ", wv[0][2], wd[1]
  61.     print wh[0][0], gv[0][0], "|", gv[0][1], "|", gv[0][2], wh[0][2]
  62.     print " ---+---+---"
  63.     print wh[1][0], gv[1][0], "|", gv[1][1], "|", gv[1][2], wh[1][2]
  64.     print " ---+---+---"
  65.     print wh[2][0], gv[2][0], "|", gv[2][1], "|", gv[2][2], wh[2][2]
  66.     print wd[2], wv[2][0], " ", wv[2][1], " ", wv[2][2], wd[3], "\n"
  67.  
  68.  
  69. def checkWin(gv):
  70.    
  71.     win_horiz = [[" ", " ", " "],
  72.                 [" ", " ", " "],
  73.                 [" ", " ", " "]]
  74.  
  75.     win_vert = [[" ", " ", " "],
  76.                 [" ", " ", " "],
  77.                 [" ", " ", " "]]
  78.  
  79.     win_diag = [" ", " ", " ", " "]
  80.  
  81.  
  82.     win = 0
  83.     #win_type = 0
  84.     #win_pos = 0
  85.  
  86.     i = 0   #print gv
  87.  
  88.     while i < 3:
  89.  
  90.         # check if row has match
  91.         if gv[i][0] == gv[i][1] and gv[i][0] == gv[i][2]:
  92.  
  93.             win_horiz[i][0] = u"\u2192"
  94.             win_horiz[i][2] = u"\u2190"
  95.  
  96.             if gv[i][0] == "X":
  97.                 win = 1
  98.  
  99.             else:
  100.                 win = 2
  101.  
  102.         # check if column has match
  103.         if gv[0][i] == gv[1][i] and gv[0][i] == gv[2][i]:
  104.  
  105.             win_vert[0][i] = u"\u2193"
  106.             win_vert[2][i] = u"\u2191"
  107.  
  108.             if gv[0][i] == "X":
  109.                 win = 1
  110.  
  111.             else:
  112.                 win = 2
  113.  
  114.         i += 1
  115.  
  116.     #   check for diagonal match
  117.     #   diagonal win, left to right
  118.     if gv[0][0] == gv[1][1] and gv[0][0] == gv[2][2]:
  119.  
  120.         win_diag[0] = u"\u2198"
  121.         win_diag[3] = u"\u2196"
  122.  
  123.         if gv[0][0] == "X":
  124.             win = 1
  125.  
  126.         else:
  127.             win = 2
  128.  
  129.     #   diagonal win, right to left
  130.     if gv[0][2] == gv[1][1] and gv[0][2] == gv[2][0]:
  131.    
  132.         win_diag[1] = u"\u2199"
  133.         win_diag[2] = u"\u2197"
  134.  
  135.         if gv[0][2] == "X":
  136.             win = 1
  137.  
  138.         else:
  139.             win = 2
  140.  
  141.  
  142.     if win == 1:
  143.         print "\nPlayer Wins!"
  144.  
  145.     if win == 2:
  146.         print "Computer Wins!"
  147.  
  148.     drawGrid(gv, win, win_horiz, win_vert, win_diag)
  149.     return win
  150.  
  151.  
  152.  
  153. def getPlay(gv):
  154.  
  155. # get move position value from 1 to 9, enter it into the play grid
  156.  
  157.     while True:
  158.         try:
  159.             next_move = int(raw_input("\nEnter your next move (grid numbers 1 to 9): "))
  160.  
  161.             if 1 <= next_move <= 9:
  162.  
  163.                 xcoord = (next_move - 1) % 3
  164.                 ycoord = (next_move - 1) / 3
  165.  
  166.                 if (gv[ycoord][xcoord] != "X") and (gv[ycoord][xcoord] != "O"):
  167.                     break
  168.  
  169.                 else:
  170.                     print("That slot is already taken. Please chose an empty one.")
  171.  
  172.         except ValueError:
  173.             pass
  174.  
  175.     print "\nPlayer Move:"
  176.  
  177.     gv[ycoord][xcoord] = "X"
  178.  
  179.     return gv
  180.  
  181. def cpuPlay(gv):
  182. ##  Random number based computer moves  ##
  183.  
  184.     while True:
  185.  
  186.         cpu_move = random.randint(1, 9)
  187.         xcoord = (cpu_move - 1) % 3
  188.         ycoord = (cpu_move - 1) / 3
  189.  
  190.         if (gv[ycoord][xcoord] != "X") and (gv[ycoord][xcoord] != "O"):
  191.             break
  192.  
  193.     print "\nComputer Move:"
  194.  
  195.     gv[ycoord][xcoord] = "O"
  196.  
  197.     return gv
  198.  
  199.  
  200.  
  201. def cpuAI(gv):
  202. ##  "Logic" based computer moves    ##
  203.  
  204. ##  NESTED FUNCTION
  205.  
  206.     ## check new number is not already in temp list
  207.     def tempCycle(move, temp):
  208.  
  209.         for tmp in temp:
  210.             #print "tmp:", tmp
  211.             if tmp == move:
  212.                 #print "Already Exists!", "tmp:", tmp, "move", move
  213.                 return 1
  214.  
  215.         return 0
  216.  
  217.  
  218.     ##  check if moves are in a row
  219.     def doublesCheck(moves):
  220.  
  221.         ## NESTED FUNCTIONS
  222.  
  223.         ## find missing number in matched row
  224.         def rowMatchCheck(rmatch):
  225.  
  226.             new_move = [0, 0]
  227.  
  228.             for i in range(0, 3):
  229.  
  230.                 if i != rmatch[0][1] and i != rmatch[1][1]:
  231.  
  232.                     new_move[0] = rmatch[0][0]
  233.                     new_move[1] = i
  234. #                   print "new move:", new_move
  235.  
  236.             return new_move
  237.  
  238.         ## find missing number in matched col
  239.         def colMatchCheck(cmatch):
  240.  
  241.             new_move = [0, 0]
  242.  
  243.             for i in range(0, 3):
  244.  
  245.                 if i != cmatch[0][0] and i != cmatch[1][0]:
  246.  
  247.                     new_move[1] = cmatch[0][1]
  248.                     new_move[0] = i
  249.  
  250.             return new_move
  251.  
  252.         ## NESTED FUNCTION END
  253.  
  254.  
  255.         row_match = []
  256.         col_match = []
  257.         diag1_match = []
  258.         diag2_match = []
  259.  
  260.         row_move = []
  261.         col_move = []
  262.  
  263.         temp_r = []
  264.         temp_c = []
  265.  
  266.         i = 0
  267.  
  268.         print "\nmoves", moves
  269.  
  270.         #   check for 2 in a same row or column ##
  271.         for mov in moves:
  272.             j = 0
  273.  
  274. #           print "row match:", row_match, len(row_match)
  275.             for mv in moves:
  276.  
  277.                 if moves[i][0] == moves[j][0] and mov != mv and tempCycle(mov, temp_r) == 0 and tempCycle(mv, temp_r) == 0:
  278.  
  279.                     temp_r.append(mov)
  280.                     temp_r.append(mv)
  281.  
  282.                     row_match.append(mov)
  283.                     row_match.append(mv)
  284.  
  285.  
  286.                 if moves[i][1] == moves[j][1] and mov != mv and tempCycle(mov, temp_c) == 0 and tempCycle(mv, temp_c) == 0:
  287.  
  288.                     temp_c.append(mov)
  289.                     temp_c.append(mv)
  290.  
  291.                     col_match.append(mv)
  292.                     col_match.append(mov)
  293.  
  294.                 j += 1
  295.             i += 1
  296.  
  297.  
  298.         #   Check for diagonal
  299.         temp1 = []
  300.         temp2 = []
  301.  
  302.         for mov in moves:
  303.  
  304.             if mov == [0, 0] or mov == [1, 1] or mov == [2, 2]:
  305.                 print "match diagonal 1!", mov
  306.                 temp1.append(mov)
  307.  
  308.                 if len(temp1) > 1 and rowMatchCheck(temp1):
  309.                     diag1_match.append(mov)
  310.  
  311.             if mov == [0, 2] or mov == [1, 1] or mov == [2, 1]:
  312.                 print "match diagonal 2!", mov
  313.                 temp2.append(mov)
  314.  
  315.                 if len(temp2) > 1 and rowMatchCheck(temp2):
  316.                     diag2_match.append(mov)
  317.  
  318.  
  319.         print "row_match ", row_match
  320.         print "col_match ", col_match
  321.         print "diag1_match", diag1_match
  322.         print "diag2_match", diag2_match, "\n"
  323.  
  324.  
  325.         ## cycle through each row match, call rowMatchCheck() to get move to complete row.
  326.  
  327.         i = 0
  328.         temp = []
  329.  
  330.         for mv in row_match:
  331.             j = 0
  332.  
  333.             for mov in row_match:
  334.                 ## If 2 rows have the same value, are duplicates, have different col values and are not trasposed versions of the same thing:
  335.                 if mov[0] == mv[0] and mov != mv and row_match[i][1] != row_match[j][1] and tempCycle(mov, temp) == 0 and tempCycle(mv, temp) == 0:
  336.  
  337.                     #print "temp", temp
  338.                     temp.append(mov)
  339.                     temp.append(mv)
  340.                     current_match = []
  341.  
  342.                     current_match.append(mov)
  343.                     current_match.append(mv)
  344.  
  345.                     #print "current match row:", current_match, "\n"
  346.  
  347.                     row_move.append(rowMatchCheck(current_match))
  348.  
  349.                 j += 1     
  350.             i += 1
  351.  
  352.  
  353.         ## cycle through each column match, call colMatchCheck() to get move to complete column
  354.  
  355.         i = 0
  356.         temp = []
  357.  
  358.         for mv in col_match:
  359.             j = 0
  360.  
  361.             for mov in col_match:
  362.                 ## If 2 columns have the same value, are duplicates, have different row values and are not trasposed versions of the same thing:
  363.                 if mov[1] == mv[1] and mov != mv and col_match[i][0] != col_match[j][0] and tempCycle(mov, temp) == 0 and tempCycle(mv, temp) == 0:
  364.  
  365.                     #print "temp", temp
  366.                     temp.append(mov)
  367.                     temp.append(mv)
  368.                     current_match = []
  369.  
  370.                     current_match.append(mov)
  371.                     current_match.append(mv)
  372.  
  373.                     #print "current match col:", current_match, "\n"
  374.  
  375.                     col_move.append(colMatchCheck(current_match))
  376.  
  377.                 j += 1
  378.             i += 1
  379.  
  380.                     #col_move.append(colMatchCheck(current_match))
  381.  
  382. #       print "matched rows", row_match, "\n"
  383. #       print "row move", row_move, "\n"
  384. #       print "matched columns", col_match, "\n\n"
  385.  
  386.  
  387.         #print "Row moves:", row_move
  388.         #print "Col moves:", col_move
  389.  
  390.         doubles = row_move + col_move
  391.  
  392.         return doubles
  393.  
  394. ##  NESTED FUNCTION END ##
  395.  
  396.  
  397.     player_moves = []
  398.     cpu_moves = []
  399.  
  400.     new_cpu = []
  401.  
  402.     ##  store current moves ##
  403.     for i in range(0, 3):
  404.         for j in range(0, 3):
  405.  
  406.             temp_player = ["0", "0"]
  407.             temp_cpu = ["0", "0"]
  408.  
  409.             if gv[i][j] == "X":
  410.                         temp_player[0] = i 
  411.                 temp_player[1] = j
  412.  
  413.                 player_moves.append(temp_player)
  414.  
  415.             if gv[i][j] == "O":
  416.                 temp_cpu[0] = i
  417.                 temp_cpu[1] = j
  418.  
  419.                 cpu_moves.append(temp_cpu)
  420.  
  421.     print "PLAYER MOVES: 'X'"
  422.     defensive_options = doublesCheck(player_moves)
  423.     print "COMPUTER MOVES: 'O'"
  424.     attacking_options = doublesCheck(cpu_moves)
  425.  
  426.     print "Defensive options", defensive_options
  427.     print "Attacking options", attacking_options
  428.  
  429.  
  430.     ## If potential move is both attacking and defensive
  431.     for atta in attacking_options:
  432.         for defe in defensive_options:
  433.             if atta == defe and tempCycle(atta, new_cpu) == 0 and checkGrid(gv, atta) == 0:
  434.                 new_cpu.insert(0, atta)
  435.                 defensive_options.remove(atta)
  436.                 attacking_options.remove(atta)
  437.  
  438.  
  439.  
  440.     print "computer move priority", new_cpu
  441.     print "other defense moves", defensive_options
  442.     print "other attack moves", attacking_options
  443.  
  444.  
  445.  
  446.  
  447.  
  448.     return gv
  449.  
  450. ##      GAME LOOP       ##
  451.  
  452. drawGrid(grid_values)
  453.  
  454. turn = 0
  455.  
  456. #while game_over == 0 and turn <= 5:
  457.  
  458. grid_values = getPlay(grid_values)
  459. game_over = checkWin(grid_values)
  460.  
  461. if turn <= 4:
  462.  
  463.     ### ENABLE FOR RANDOM AI
  464.     #grid_values = cpuPlay(grid_values)
  465.  
  466.     ### ENABLE FOR COMPUTER AI
  467.     grid_values = cpuAI(grid_values)
  468.     game_over = checkWin(grid_values)
  469.  
  470. turn += 1
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top