Advertisement
Guest User

Untitled

a guest
Nov 19th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.65 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement