• API
• FAQ
• Tools
• Archive
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][move]
37.
38.     if gv[move][move] == "X" or gv[move][move] == "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, wv, " ", wv, " ", wv, wd
61.     print wh, gv, "|", gv, "|", gv, wh
62.     print " ---+---+---"
63.     print wh, gv, "|", gv, "|", gv, wh
64.     print " ---+---+---"
65.     print wh, gv, "|", gv, "|", gv, wh
66.     print wd, wv, " ", wv, " ", wv, wd, "\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] == gv[i] and gv[i] == gv[i]:
92.
93.             win_horiz[i] = u"\u2192"
94.             win_horiz[i] = u"\u2190"
95.
96.             if gv[i] == "X":
97.                 win = 1
98.
99.             else:
100.                 win = 2
101.
102.         # check if column has match
103.         if gv[i] == gv[i] and gv[i] == gv[i]:
104.
105.             win_vert[i] = u"\u2193"
106.             win_vert[i] = u"\u2191"
107.
108.             if gv[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 == gv and gv == gv:
119.
120.         win_diag = u"\u2198"
121.         win_diag = u"\u2196"
122.
123.         if gv == "X":
124.             win = 1
125.
126.         else:
127.             win = 2
128.
129.     #   diagonal win, right to left
130.     if gv == gv and gv == gv:
131.
132.         win_diag = u"\u2199"
133.         win_diag = u"\u2197"
134.
135.         if gv == "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:
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 and i != rmatch:
231.
232.                     new_move = rmatch
233.                     new_move = 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 and i != cmatch:
246.
247.                     new_move = cmatch
248.                     new_move = 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] == moves[j] 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] == moves[j] 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 == mv and mov != mv and row_match[i] != row_match[j] 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 == mv and mov != mv and col_match[i] != col_match[j] 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 = i
411.                 temp_player = j
412.
413.                 player_moves.append(temp_player)
414.
415.             if gv[i][j] == "O":
416.                 temp_cpu = i
417.                 temp_cpu = 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.

Top