Advertisement
Guest User

Untitled

a guest
Mar 29th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 50.92 KB | None | 0 0
  1. # A one player Connect-4 game with an AI opponent.
  2. #
  3. from SimpleGraphics import *
  4. from random import randint, choice
  5. from pprint import pprint, pformat
  6. from time import sleep
  7.  
  8. import sys
  9. import copy
  10. import os
  11. import inspect
  12. import traceback
  13.  
  14. # Constants for each possible state for a location on the board
  15. BLANK = 0
  16. PLAYER_1 = 1
  17. PLAYER_2 = 2
  18.  
  19. SIZE = 75
  20. BUTTON_HEIGHT = 40
  21. STATUS_HEIGHT = 20
  22.  
  23. THINK_TIME = 0.5
  24.  
  25. ###############################################################################
  26. ##
  27. ## Insert your code for createBoard, columnFull, dropChecker, and gameTied
  28. ## here. Do not modify any code above this point in the file.
  29. ##
  30. ###############################################################################
  31.  
  32. def createBoard(rows, cols):
  33. board = []
  34. for row in range(rows):
  35. board.append([])
  36. for col in range(cols):
  37. board[row].append(BLANK)
  38. return board
  39.  
  40. def columnFull(board, col):
  41. if board[0][col] != 0:
  42. return True
  43.  
  44. else:
  45. return False
  46.  
  47. def dropChecker(board, col):
  48. for i in range(len(board)):
  49. if board [][col] != 0:
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56. ###############################################################################
  57. ##
  58. ## Modify the provided implementations of wonHorizontal, wonVertical,
  59. ## wonPosSlope, wonNegSlope and canWin so that they perform their required
  60. ## tasks instead of always returning the same value.
  61. ##
  62. ###############################################################################
  63.  
  64. #
  65. # Did the last move result in a 4 checker horizontal line?
  66. #
  67. # Parameters:
  68. # board: The board to check as a 2-D list.
  69. # column: The column in which the most recent checker was played.
  70. # row: The row in which the most recent checker was played.
  71. #
  72. # Returns: True if the last move caused a player to win, False otherwise.
  73. #
  74. def wonHorizontal(board, row, column):
  75. return False
  76.  
  77. #
  78. # Did the last move result in a 4 checker vertical line?
  79. #
  80. # Parameters:
  81. # board: The board to check as a 2-D list.
  82. # column: The column in which the most recent checker was played.
  83. # row: The row in which the most recent checker was played.
  84. #
  85. # Returns: True if the last move caused a player to win, False otherwise.
  86. #
  87. def wonVertical(board, row, column):
  88. return False
  89.  
  90. #
  91. # Did the last move result in a 4 checker line with positive slope?
  92. #
  93. # Parameters:
  94. # board: The board to check as a 2-D list.
  95. # column: The column in which the most recent checker was played.
  96. # row: The row in which the most recent checker was played.
  97. #
  98. # Returns: True if the last move caused a player to win, False otherwise.
  99. #
  100. def wonPosSlope(board, row, column):
  101. return False
  102.  
  103. #
  104. # Did the last move result in a 4 checker line with negative slope?
  105. #
  106. # Parameters:
  107. # board: The board to check as a 2-D list.
  108. # column: The column in which the most recent checker was played.
  109. # row: The row in which the most recent checker was played.
  110. #
  111. # Returns: True if the last move caused a player to win, False otherwise.
  112. #
  113. def wonNegSlope(board, row, column):
  114. return False
  115.  
  116. #
  117. # Is there a move that the player can make to win the game?
  118. #
  119. # Parameters:
  120. # board: The board as a 2D list.
  121. # player: The player that is going to make the move, either PLAYER_1 or
  122. # PLAYER_2.
  123. #
  124. # Returns:
  125. # -1 if there is no winning move. The column number in the board if there
  126. # is a winning move.
  127. #
  128. def canWin(board, player):
  129. return -1
  130.  
  131. ###############################################################################
  132. ##
  133. ## Do not modift any code below this point in the file.
  134. ##
  135. ###############################################################################
  136.  
  137. #
  138. # Did the last move cause a player to win?
  139. #
  140. # Parameters:
  141. # board: The board to check as a 2-D list.
  142. # column: The column in which the most recent checker was played.
  143. # row: The row in which the most recent checker was played.
  144. #
  145. # Returns: True if the last move caused a player to win, False otherwise.
  146. #
  147. def gameWon(board, row, column):
  148. return wonHorizontal(board, row, column) or wonVertical(board, row, column) or wonPosSlope(board, row, column) or wonNegSlope(board, row, column)
  149.  
  150. #
  151. # Display information about the command line parameters supported by the
  152. # program and then terminate its execution.
  153. #
  154. # Parameters: None.
  155. #
  156. # Returns: None.
  157. def usage():
  158. print()
  159. print("Usage: python %s [<predictable|easy|medium|hard> [<rows> <columns>]]" % sys.argv[0])
  160. print()
  161. close()
  162. quit()
  163.  
  164. #
  165. # Randomly determine which player is going to make the first move
  166. #
  167. # Parameters: None
  168. #
  169. # Returns: Either PLAYER_1 or PLAYER_2 with equal probability
  170. #
  171. def startingPlayer():
  172. value = randint(0, 1)
  173. if value == 0:
  174. return PLAYER_1
  175. else:
  176. return PLAYER_2
  177.  
  178. #
  179. # Identify the next player who is going to make a move
  180. #
  181. # Parameters:
  182. # player: The current player
  183. #
  184. # Returns: The next player who gets to move after the current player completes
  185. # their move.
  186. #
  187. def nextPlayer(player):
  188. if player == PLAYER_1:
  189. return PLAYER_2
  190. return PLAYER_1
  191.  
  192. #
  193. # Display the board in the graphics window
  194. #
  195. # Parameters:
  196. # board: The board to display
  197. # grid: The image to use for generating the grid
  198. #
  199. # Returns: None
  200. #
  201. def drawBoard(board, grid):
  202. for r in range(len(board)):
  203. for c in range(len(board[0])):
  204. if board[r][c] == PLAYER_1:
  205. setColor(192, 0, 0)
  206. ellipse(c * SIZE + 5, r * SIZE + 5 + BUTTON_HEIGHT, SIZE - 10, SIZE - 10)
  207. elif board[r][c] == PLAYER_2:
  208. setColor(255, 255, 0)
  209. ellipse(c * SIZE + 5, r * SIZE + 5 + BUTTON_HEIGHT, SIZE - 10, SIZE - 10)
  210. drawImage(grid, c * SIZE, r * SIZE + BUTTON_HEIGHT)
  211.  
  212. #
  213. # Draw the buttons across the top of the board.
  214. #
  215. # Parameters:
  216. # board: The game board, which is needed to know how many buttons need to
  217. # be drawn.
  218. #
  219. # Returns: None
  220. #
  221. def drawButtons(board):
  222. for c in range(len(board[0])):
  223. setColor(192, 192, 192)
  224. setWidth(1)
  225. setArrow(tk.NONE)
  226. rect(c * SIZE, 0, SIZE, BUTTON_HEIGHT)
  227. if columnFull(board, c) == False:
  228. setColor(0, 0, 0)
  229. line(c * SIZE, BUTTON_HEIGHT - 1, (c + 1) * SIZE - 1, BUTTON_HEIGHT - 1, (c + 1) * SIZE - 1, 0)
  230. setColor(255, 255, 255)
  231. line(c * SIZE, BUTTON_HEIGHT - 2, c * SIZE, 0, (c + 1) * SIZE - 2, 0)
  232. setColor(192, 0, 0)
  233. setWidth(3)
  234. setArrow(tk.LAST)
  235. line((c + 0.5) * SIZE, BUTTON_HEIGHT / 8, (c + 0.5) * SIZE, BUTTON_HEIGHT * 7 / 8)
  236.  
  237. #
  238. # Draws the status message at the bottom of the board
  239. #
  240. # Parameters:
  241. # message: The message to display
  242. # board: The board below which the message is displayed, needed so that
  243. # the vertical position can be calculated.
  244. #
  245. # Returns: None
  246. #
  247. def drawStatus(message, board):
  248. setColor(192, 192, 192)
  249. rect(0, BUTTON_HEIGHT + len(board) * SIZE, getWidth(), STATUS_HEIGHT)
  250.  
  251. setColor(0, 0, 0)
  252. text(10, BUTTON_HEIGHT + len(board) * SIZE + STATUS_HEIGHT / 2, message, "w")
  253.  
  254. #
  255. # Animate a checker dropping down in the board.
  256. #
  257. # Parameters:
  258. # board: The board, before the checker is in place
  259. # row, col: The position that the checker is going to land in
  260. # player: The player whose checker is being dropped
  261. # grid: The image used for drawing the grid
  262. #
  263. # Returns: None
  264. #
  265. def animateDrop(board, row, col, player, grid):
  266. top = BUTTON_HEIGHT - SIZE
  267. bottom = row * SIZE + 5 + BUTTON_HEIGHT
  268. for i in range(100):
  269. clear()
  270. drawStatus("", board)
  271. if player == PLAYER_1:
  272. drawButtons(board)
  273. setColor(192, 0, 0)
  274. else:
  275. setColor(192, 192, 192)
  276. rect(0, 0, (len(board) + 1) * SIZE, BUTTON_HEIGHT)
  277. setColor(255, 255, 0)
  278. ellipse(col * SIZE + 5, top + (bottom - top) / 99 * i, SIZE - 10, SIZE - 10)
  279. drawBoard(board, grid)
  280. update()
  281.  
  282. #
  283. # A node in a game state tree used by the medium and hard AIs
  284. #
  285. class node:
  286. def __init__(self, board):
  287. self._board = board
  288. self._successors = []
  289.  
  290. def __str__(self):
  291. return pformat(self._board) + "\n" + "Score: " + str(self.getScore()) + "\n" + str(self._successors) + "\n"
  292.  
  293. def getSuccessors(self):
  294. return self._successors
  295.  
  296. def getBoard(self):
  297. return self._board
  298.  
  299. def getScore(self):
  300. score = 0
  301. for r in range(0, len(self._board)):
  302. for c in range(0, len(self._board[0]) - 3):
  303. score += self.scoreRow(r, c)
  304. for r in range(0, len(self._board) - 3):
  305. for c in range(0, len(self._board[0])):
  306. score += self.scoreCol(r, c)
  307. for r in range(0, len(self._board) - 3):
  308. for c in range(0, len(self._board[0]) - 3):
  309. score += self.scoreNeg(r, c)
  310. for r in range(3, len(self._board)):
  311. for c in range(0, len(self._board[0]) - 3):
  312. score += self.scorePos(r, c)
  313.  
  314. return score
  315.  
  316. def scoreRow(self, r, c):
  317. p1 = 0
  318. p2 = 0
  319. b = 0
  320. for i in range(4):
  321. if self._board[r][c+i] == PLAYER_1:
  322. p1 += 1
  323. if self._board[r][c+i] == PLAYER_2:
  324. p2 += 1
  325. if self._board[r][c+i] == BLANK:
  326. b += 1
  327. return self.gs(p1, p2, b)
  328.  
  329. def scoreCol(self, r, c):
  330. p1 = 0
  331. p2 = 0
  332. b = 0
  333. for i in range(4):
  334. if self._board[r+i][c] == PLAYER_1:
  335. p1 += 1
  336. if self._board[r+i][c] == PLAYER_2:
  337. p2 += 1
  338. if self._board[r+i][c] == BLANK:
  339. b += 1
  340. return self.gs(p1, p2, b)
  341.  
  342. def scorePos(self, r, c):
  343. p1 = 0
  344. p2 = 0
  345. b = 0
  346. for i in range(4):
  347. if self._board[r-i][c+i] == PLAYER_1:
  348. p1 += 1
  349. if self._board[r-i][c+i] == PLAYER_2:
  350. p2 += 1
  351. if self._board[r-i][c+i] == BLANK:
  352. b += 1
  353. return self.gs(p1, p2, b)
  354.  
  355. def scoreNeg(self, r, c):
  356. p1 = 0
  357. p2 = 0
  358. b = 0
  359. for i in range(4):
  360. if self._board[r+i][c+i] == PLAYER_1:
  361. p1 += 1
  362. if self._board[r+i][c+i] == PLAYER_2:
  363. p2 += 1
  364. if self._board[r+i][c+i] == BLANK:
  365. b += 1
  366. return self.gs(p1, p2, b)
  367.  
  368. def appendSuccessor(self, successor):
  369. self._successors.append(successor)
  370.  
  371. def minScore(self):
  372. if self._successors == []:
  373. return self.getScore()
  374.  
  375. ms = 0
  376. for child in self._successors:
  377. if child != None:
  378. cms = child.minScore()
  379. if cms < ms:
  380. ms = cms
  381. return ms
  382.  
  383. def chooseCol(self):
  384. # Need to add a check that says if there is a winning move, take it
  385. cw = canWin(self.getBoard(), PLAYER_2)
  386. if cw != -1:
  387. return cw
  388.  
  389. #for c in range(0, len(self.getBoard()[0])):
  390. # if columnFull(self.getBoard(), c) == False:
  391. # pos = 0
  392. # while self.getSuccessors()[c].getBoard()[pos][c] == BLANK:
  393. # pos += 1
  394. # if gameWon(self.getSuccessors()[c].getBoard(), pos, c):
  395. # return c
  396.  
  397. scores = []
  398. for s in self.getSuccessors():
  399. if s == None:
  400. scores.append(0)
  401. else:
  402. scores.append(s.minScore())
  403.  
  404. # Need to make sure that we don't try and play into a full column
  405. for i in range(0, len(scores)):
  406. if columnFull(self.getBoard(), i):
  407. scores[i] = -1000000
  408. mx = max(scores)
  409.  
  410. choices = []
  411. for i in range(0, len(scores)):
  412. if scores[i] == mx:
  413. choices.append(i)
  414.  
  415. selection = choice(choices)
  416. return selection
  417.  
  418. #
  419. # Compute a score based on the number of player 1 checkers, the number of
  420. # player 2 checkers and the number of blank spots in a row
  421. #
  422. # Parameters:
  423. # p1: The number of player 1 checkers
  424. # p2: The number of player 2 checkers
  425. # b: The number of blank spots
  426. #
  427. def gs(self, p1, p2, b):
  428. if p1 == 4:
  429. return -10000
  430. if p2 == 4:
  431. return +10000
  432. if p1 == 3 and b == 1:
  433. return -720
  434. if p2 == 3 and b == 1:
  435. return 720
  436. if p1 == 2 and b == 2:
  437. return -6
  438. if p2 == 2 and b == 2:
  439. return 6
  440. return 0
  441.  
  442. #
  443. # Determine where the computer controlled player should drop a checker using
  444. # a predictable algorithm that always plays in the left-most column that
  445. # has space in it.
  446. #
  447. # Parameters:
  448. # board: The game board immediately before the computer controlled player
  449. # will make its move.
  450. #
  451. # Returns: The column in which the computer will play
  452. #
  453. def ai_predictable(board):
  454. for c in range(0, len(board[0])):
  455. if columnFull(board, c) == False:
  456. return c
  457.  
  458. #
  459. # Determine where the computer controlled player should drop a checker using
  460. # an easy to defeat algorithm.
  461. #
  462. # Parameters:
  463. # board: The game board immediately before the computer controlled player
  464. # will make its move.
  465. #
  466. # Returns: The column in which the computer will play
  467. #
  468. def ai_easy(board):
  469. cw = canWin(board, PLAYER_2)
  470. if cw != -1:
  471. return cw
  472.  
  473. col = randint(0, len(board[0]) - 1)
  474. while columnFull(board, col):
  475. col = randint(0, len(board[0]) - 1)
  476.  
  477. return col
  478.  
  479. #
  480. # Determine which column the computer player should chose, providing a moderate
  481. # level of difficulty for human players.
  482. #
  483. # Parameters:
  484. # board: The current game board as a 2D list
  485. #
  486. # Returns: The column in which the computer will play
  487. #
  488. def ai_medium(board):
  489. root = node(board)
  490. genSuccessors(root, 2, PLAYER_2)
  491. return root.chooseCol()
  492.  
  493. #
  494. # Determine which column the computer player should chose, providing a high
  495. # level of difficulty for human players.
  496. #
  497. # Parameters:
  498. # board: The current game board as a 2D list
  499. #
  500. # Returns: The column in which the computer will play
  501. #
  502. def ai_hard(board):
  503. root = node(board)
  504. genSuccessors(root, 4, PLAYER_2)
  505. return root.chooseCol()
  506.  
  507. #
  508. # Build a tree of possible future game states
  509. #
  510. # Parameters:
  511. # root: The starting state for the board. This parameter is modified by
  512. # this function call.
  513. # level: The number of additional moves to consider
  514. # player: The player who is going to make the next move
  515. #
  516. # Returns: The root node for the game state tree
  517. #
  518. def genSuccessors(root, level, player):
  519. board = root.getBoard()
  520. for c in range(len(board[0])):
  521. if board[0][c] == BLANK:
  522. nextBoard = copy.deepcopy(board)
  523. row = dropChecker(nextBoard, c)
  524. nextBoard[row][c] = player
  525. if level > 1:
  526. root.appendSuccessor(genSuccessors(node(nextBoard), level - 1, nextPlayer(player)))
  527. else:
  528. root.appendSuccessor(node(nextBoard))
  529. else:
  530. root.appendSuccessor(None)
  531. return root
  532.  
  533. ##############################################################################
  534. ##
  535. ## Code for testing the functions written by the students
  536. ##
  537. ##############################################################################
  538.  
  539. # Determine whether or not a function exists in the namespace at the time
  540. # this function is called
  541. # Parameters:
  542. # name: The name of the function to check the existence of
  543. # Returns: True if the function exists, False otherwise
  544. def functionExists(name):
  545. members = inspect.getmembers(sys.modules[__name__])
  546. for (n, m) in members:
  547. if n == name and inspect.isfunction(m):
  548. return True
  549. return False
  550.  
  551. # Run a series of tests on the createBoard function
  552. # Parameters: (None)
  553. # Returns: True if all tests passed. False if any test fails.
  554. def testCreateBoard():
  555. print("Testing createBoard...")
  556.  
  557. # Does the createBoard function exist?
  558. if functionExists("createBoard"):
  559. print(" The function seems to exist...")
  560. else:
  561. print(" The createBoard function doesn't seem to exist...")
  562. return False
  563.  
  564. for (rows, cols) in [(6, 7), (7, 6), (4, 4), (8, 10)]:
  565. # Try and call the function
  566. try:
  567. print(" Attempting to create a board with %d rows and %d columns... " % (rows, cols), end="")
  568. b = createBoard(rows, cols)
  569. except Exception as e:
  570. print("\n FAILED: An exception occurred during the attempt.")
  571. traceback.print_exc(file=sys.stdout)
  572. return False
  573.  
  574. # Does it have the correct return type?
  575. if type(b) is not list:
  576. print("\n FAILED: The value returned was a", str(type(b)) + ", not a list.")
  577. return False
  578.  
  579. # Does the list have the corret number of elements?
  580. if len(b) != rows:
  581. print("\n FAILED: The board had", len(b), "rows when", rows, "were expected.")
  582. return False
  583.  
  584. # Is each row a list? Does each row have the current length?
  585. for i in range(len(b)):
  586. if type(b[i]) is not list:
  587. print("\n FAILED: The row at index", i, "is a", str(type(b[i])) + ", not a list.")
  588. return False
  589. if len(b[i]) != cols:
  590. print("\n FAILED: The row at index", i, "had", len(b[i]), "elements when", cols, "were expected.")
  591. return False
  592.  
  593. # Is every element in the board a Blank?
  594. for r in range(0, len(b)):
  595. for c in range(0, len(b[r])):
  596. if type(b[r][c]) is not int:
  597. print(" FAILED: The value in row", r, "column", c, "is a", str(type(b[r][c])) + ", not an integer")
  598. return False
  599. if b[r][c] != BLANK:
  600. print("\n FAILED: The integer in row", r, "column", c, "is '%d', which is not a blank space. All spaces in the initial board must be BLANK." % b[r][c])
  601. return False
  602.  
  603. print("Success.")
  604.  
  605. print()
  606. return True
  607.  
  608. # Run a series of tests on the columnFull function
  609. # Parameters: (None)
  610. # Returns: True if all tests passed. False otherwise.
  611. def testColumnFull():
  612. print("Testing columnFull...")
  613.  
  614. # Does the columnFull function exist?
  615. if functionExists("columnFull"):
  616. print(" The function seems to exist...")
  617. else:
  618. print(" The columnFull function doesn't seem to exist...")
  619. return False
  620.  
  621. # Run a series of test cases
  622. for (b, c, a) in [([[0, 0], [0, 0]], 0, False), \
  623. ([[0, 0], [1, 2]], 0, False), \
  624. ([[1, 0], [1, 2]], 0, True), \
  625. ([[1, 0], [1, 2]], 1, False), \
  626. ([[1, 2], [1, 2]], 1, True), \
  627. ([[0, 0, 1], [0, 0, 2]], 0, False), \
  628. ([[0, 0, 1], [0, 0, 2]], 1, False), \
  629. ([[0, 0, 1], [0, 0, 2]], 2, True), \
  630. ([[0, 2, 0], [0, 1, 0], [0, 2, 0], [0, 1, 0]], 0, False), \
  631. ([[0, 2, 0], [0, 1, 0], [0, 2, 0], [0, 1, 0]], 1, True), \
  632. ([[0, 2, 0], [0, 1, 0], [0, 2, 0], [0, 1, 0]], 2, False)]:
  633. # Attempt the function call
  634. try:
  635. print(" Attempting to use columnFull on board:")
  636. print(" [%s," % str(b[0]))
  637. for i in range(1, len(b) - 1):
  638. print(" ", b[i], ",", sep="")
  639. print(" ", b[-1], "]", sep="")
  640. print(" at column %d... " % c, end="")
  641. result = columnFull(b, c)
  642. except Exception as e:
  643. print("\n FAILED: An exception occurred during the attempt.")
  644. traceback.print_exc(file=sys.stdout)
  645. return False
  646.  
  647. # Does it have the correct return type?
  648. if type(result) is not bool:
  649. print("\n FAILED: The value returned was a", str(type(result)) + ", not a Boolean.")
  650. return False
  651.  
  652. # Did it return the correct value
  653. if result != a:
  654. print("\n FAILED: The value returned was", str(result), "when", str(a), "was expected.")
  655. return False
  656.  
  657. print("Success.")
  658.  
  659. print()
  660. return True
  661.  
  662. # Run a series of tests on the dropChecker function
  663. # Parameters: (None)
  664. # Returns: True if all tests passed. False otherwise.
  665. def testDropChecker():
  666. print("Testing dropChecker...")
  667.  
  668. # Does the dropChecker function exist?
  669. if functionExists("dropChecker"):
  670. print(" The function seems to exist...")
  671. else:
  672. print(" The dropChecker function doesn't seem to exist...")
  673. return False
  674.  
  675. # Run a series of test cases
  676. for (b, c, a) in [([[0, 0], [0, 0]], 0, 1), \
  677. ([[0, 0], [1, 2]], 0, 0), \
  678. ([[1, 0], [1, 2]], 1, 0), \
  679. ([[0, 0, 1], [2, 0, 2]], 0, 0), \
  680. ([[0, 0, 1], [2, 0, 2]], 1, 1), \
  681. ([[0, 0, 1], [2, 1, 2]], 1, 0), \
  682. ([[0, 2, 0], [0, 1, 0], [0, 2, 0], [0, 1, 1]], 0, 3), \
  683. ([[0, 0, 0], [0, 1, 0], [0, 2, 0], [0, 1, 2]], 1, 0), \
  684. ([[0, 2, 0], [0, 1, 0], [0, 2, 0], [0, 1, 1]], 2, 2), \
  685. ([[0, 0, 0, 0, 0, 0, 0], \
  686. [0, 0, 0, 0, 0, 0, 0], \
  687. [0, 0, 0, 0, 0, 0, 0], \
  688. [0, 0, 0, 0, 0, 0, 0], \
  689. [0, 0, 0, 0, 0, 0, 0], \
  690. [0, 0, 0, 1, 0, 0, 0]], 3, 4), \
  691. ([[0, 0, 0, 0, 0, 0, 0], \
  692. [0, 0, 0, 0, 0, 0, 0], \
  693. [0, 0, 0, 0, 0, 0, 0], \
  694. [0, 0, 0, 0, 0, 0, 0], \
  695. [0, 0, 0, 0, 0, 0, 0], \
  696. [0, 0, 0, 1, 0, 0, 0]], 4, 5)]:
  697. # Attempt the function call
  698. try:
  699. print(" Attempting to use dropChecker on board:")
  700. print(" [%s," % str(b[0]))
  701. for i in range(1, len(b) - 1):
  702. print(" ", b[i], ",", sep="")
  703. print(" ", b[-1], "]", sep="")
  704. print(" at column %d... " % c, end="")
  705. result = dropChecker(b, c)
  706. except Exception as e:
  707. print("\n FAILED: An exception occurred during the attempt.")
  708. traceback.print_exc(file=sys.stdout)
  709. return False
  710.  
  711. # Does it have the correct return type?
  712. if type(result) is not int:
  713. print("\n FAILED: The value returned was a", str(type(result)) + ", not an integer.")
  714. return False
  715.  
  716. # Did it return the correct value
  717. if result != a:
  718. print("\n FAILED: The value returned was", str(result), "when", str(a), "was expected.")
  719. return False
  720.  
  721. print("Success.")
  722.  
  723. print()
  724. return True
  725.  
  726. # Run a series of tests on the gameTied function
  727. # Parameters: (None)
  728. # Returns: True if all tests passed. False otherwise.
  729. def testGameTied():
  730. print("Testing gameTied...")
  731.  
  732. # Does the gameTied function exist?
  733. if functionExists("gameTied"):
  734. print(" The function seems to exist...")
  735. else:
  736. print(" The gameTied function doesn't seem to exist...")
  737. return False
  738.  
  739. # Run a series of test cases
  740. for (b, a) in [([[0, 0], [0, 0]], False), \
  741. ([[1, 2], [1, 2]], True), \
  742. ([[0, 0, 1], [2, 0, 2]], False), \
  743. ([[0, 0, 1], [2, 0, 2]], False), \
  744. ([[0, 0, 1], [2, 1, 2]], False), \
  745. ([[2, 1, 1], [2, 1, 2]], True), \
  746. ([[0, 2, 0], [0, 1, 0], [0, 2, 0], [0, 1, 1]], False), \
  747. ([[1, 2, 1], [2, 1, 2], [1, 2, 1], [2, 1, 2]], True), \
  748. ([[0, 2, 1], [2, 1, 2], [1, 2, 1], [2, 1, 2]], False), \
  749. ([[1, 0, 1], [2, 1, 2], [1, 2, 1], [2, 1, 2]], False), \
  750. ([[1, 2, 0], [2, 1, 2], [1, 2, 1], [2, 1, 2]], False), \
  751. ([[1, 2, 1, 2, 1, 2, 1], \
  752. [1, 2, 1, 2, 1, 2, 1], \
  753. [1, 2, 1, 2, 1, 2, 1], \
  754. [1, 2, 1, 2, 1, 2, 1], \
  755. [1, 2, 1, 2, 1, 2, 1], \
  756. [1, 2, 1, 1, 2, 1, 2]], True), \
  757. ([[1, 0, 1, 2, 1, 2, 1], \
  758. [1, 2, 1, 2, 1, 2, 1], \
  759. [1, 2, 1, 2, 1, 2, 1], \
  760. [1, 2, 1, 2, 1, 2, 1], \
  761. [1, 2, 1, 2, 1, 2, 1], \
  762. [1, 2, 1, 1, 2, 1, 2]], False), \
  763. ([[1, 2, 1, 2, 0, 2, 1], \
  764. [1, 2, 1, 2, 1, 2, 1], \
  765. [1, 2, 1, 2, 1, 2, 1], \
  766. [1, 2, 1, 2, 1, 2, 1], \
  767. [1, 2, 1, 2, 1, 2, 1], \
  768. [1, 2, 1, 1, 2, 1, 2]], False)]:
  769. # Attempt the function call
  770. try:
  771. print(" Attempting to use gameTied on board:")
  772. print(" [%s," % str(b[0]))
  773. for i in range(1, len(b) - 1):
  774. print(" ", b[i], ",", sep="")
  775. print(" ", b[-1], "]... ", sep="", end="")
  776. result = gameTied(b)
  777. except Exception as e:
  778. print("\n FAILED: An exception occurred during the attempt.")
  779. traceback.print_exc(file=sys.stdout)
  780. return False
  781.  
  782. # Does it have the correct return type?
  783. if type(result) is not bool:
  784. print("\n FAILED: The value returned was a", str(type(result)) + ", not a Boolean.")
  785. return False
  786.  
  787. # Did it return the correct value
  788. if result != a:
  789. print("\n FAILED: The value returned was", str(result), "when", str(a), "was expected.")
  790. return False
  791.  
  792. print("Success.")
  793.  
  794. print()
  795. return True
  796.  
  797. #
  798. # Run a series of tests on the wonVertical function
  799. # Parameters: (None)
  800. # Returns: True if all tests passed. False otherwise.
  801. def testWonVertical():
  802. print("Testing wonVertical...")
  803.  
  804. # Does the wonVertical function exist?
  805. if functionExists("wonVertical"):
  806. print(" The function seems to exist...")
  807. else:
  808. print(" The wonVertical function doesn't seem to exist...")
  809. quit()
  810.  
  811. passed = 0
  812. failed = 0
  813. # Run a series of test cases
  814. for (b, r, c, a) in [ \
  815. ([[0, 0, 0, 0, 0, 0, 0], \
  816. [0, 0, 0, 0, 0, 0, 0], \
  817. [0, 0, 0, 0, 0, 0, 0], \
  818. [0, 0, 0, 0, 0, 0, 0], \
  819. [0, 0, 0, 0, 0, 0, 0], \
  820. [0, 0, 0, 1, 0, 0, 0]], 5, 3, False), \
  821. ([[0, 0, 0, 0, 0, 0, 0], \
  822. [0, 0, 0, 0, 0, 0, 0], \
  823. [0, 0, 0, 0, 0, 0, 0], \
  824. [0, 0, 0, 1, 0, 0, 0], \
  825. [0, 0, 0, 1, 0, 0, 0], \
  826. [0, 0, 2, 1, 2, 0, 0]], 3, 3, False), \
  827. ([[0, 0, 0, 0, 0, 0, 0], \
  828. [0, 0, 0, 0, 0, 0, 0], \
  829. [1, 0, 0, 0, 0, 0, 0], \
  830. [2, 1, 0, 0, 0, 0, 0], \
  831. [2, 2, 2, 0, 0, 0, 0], \
  832. [1, 2, 1, 1, 0, 0, 0]], 4, 2, False), \
  833. ([[0, 0, 0, 0, 0, 0, 0], \
  834. [1, 2, 0, 0, 0, 0, 0], \
  835. [1, 2, 2, 1, 0, 0, 0], \
  836. [2, 1, 1, 2, 1, 0, 0], \
  837. [2, 2, 2, 1, 1, 0, 0], \
  838. [1, 2, 2, 1, 1, 0, 1]], 2, 2, False), \
  839. ([[0, 0, 0, 0, 0, 0, 0], \
  840. [0, 0, 0, 0, 0, 0, 0], \
  841. [0, 0, 0, 0, 0, 0, 0], \
  842. [0, 0, 0, 0, 0, 0, 0], \
  843. [0, 0, 0, 0, 0, 0, 0], \
  844. [1, 0, 0, 0, 0, 0, 0]], 5, 0, False), \
  845. ([[0, 0, 0, 0], \
  846. [0, 0, 0, 0], \
  847. [0, 0, 0, 0], \
  848. [0, 0, 0, 2]], 3, 3, False), \
  849. ([[2, 1, 2, 1], \
  850. [2, 1, 2, 1], \
  851. [1, 2, 1, 2], \
  852. [1, 2, 1, 2]], 0, 3, False), \
  853.  
  854. # True Vertical
  855. ([[0, 0, 0, 0, 0, 0, 0], \
  856. [0, 0, 0, 0, 0, 0, 0], \
  857. [0, 0, 0, 1, 0, 0, 0], \
  858. [0, 0, 0, 1, 0, 0, 0], \
  859. [0, 0, 0, 1, 2, 0, 0], \
  860. [0, 0, 2, 1, 2, 0, 0]], 2, 3, True), \
  861. ([[0, 0, 0, 0, 0, 0, 0], \
  862. [0, 0, 0, 0, 0, 0, 0], \
  863. [1, 0, 0, 0, 0, 0, 0], \
  864. [1, 2, 0, 0, 0, 0, 0], \
  865. [1, 2, 0, 0, 0, 0, 0], \
  866. [1, 2, 0, 0, 0, 0, 0]], 2, 0, True), \
  867. ([[1, 0, 0, 0, 0, 0, 0], \
  868. [1, 2, 0, 0, 0, 0, 0], \
  869. [1, 2, 0, 0, 0, 0, 0], \
  870. [1, 2, 0, 0, 0, 0, 0], \
  871. [2, 1, 0, 0, 0, 0, 0], \
  872. [1, 2, 0, 0, 0, 0, 0]], 0, 0, True), \
  873. ([[0, 0, 0, 0, 0, 0, 0], \
  874. [0, 0, 0, 0, 0, 0, 0], \
  875. [1, 0, 0, 0, 0, 0, 2], \
  876. [2, 1, 0, 0, 0, 1, 2], \
  877. [1, 2, 0, 0, 0, 1, 2], \
  878. [1, 2, 0, 0, 0, 1, 2]], 2, 6, True), \
  879. ([[0, 0, 0, 0, 0, 0, 2], \
  880. [1, 2, 0, 0, 0, 1, 2], \
  881. [1, 2, 0, 0, 0, 1, 2], \
  882. [1, 2, 0, 0, 0, 2, 2], \
  883. [2, 1, 0, 0, 0, 1, 1], \
  884. [1, 2, 0, 0, 0, 1, 2]], 0, 6, True), \
  885. ]:
  886. # Attempt the function call
  887. try:
  888. print(" Attempting to use wonVertical on board:")
  889. print(" [%s," % str(b[0]))
  890. for i in range(1, len(b) - 1):
  891. print(" ", b[i], ",", sep="")
  892. print(" ", b[-1], "]... ", sep="", end="")
  893. result = wonVertical(b, r, c)
  894. except Exception as e:
  895. print("\nFAILED: An exception occurred during the attempt.")
  896. traceback.print_exc(file=sys.stdout)
  897. failed += 1
  898. continue
  899.  
  900. # Does it have the correct return type?
  901. if type(result) is not bool:
  902. print("\nFAILED: The value returned was a", str(type(result)) + ", not a Boolean.")
  903. failed += 1
  904. continue
  905.  
  906. # Did it return the correct value
  907. if result != a:
  908. print("\nFAILED: The value returned was", str(result), "when", str(a), "was expected.")
  909. failed += 1
  910. continue
  911.  
  912. print("Success.")
  913. passed += 1
  914.  
  915. print()
  916. return (passed, failed)
  917.  
  918. #
  919. # Run a series of tests on the wonHorizontal function
  920. # Parameters: (None)
  921. # Returns: True if all tests passed. False otherwise.
  922. def testWonHorizontal():
  923. print("Testing wonHorizontal...")
  924.  
  925. # Does the wonHorizontal function exist?
  926. if functionExists("wonHorizontal"):
  927. print(" The function seems to exist...")
  928. else:
  929. print(" The wonHorizontal function doesn't seem to exist...")
  930. quit()
  931.  
  932. passed = 0
  933. failed = 0
  934. # Run a series of test cases
  935. for (b, r, c, a) in [ \
  936. ([[0, 0, 0, 0, 0, 0, 0], \
  937. [0, 0, 0, 0, 0, 0, 0], \
  938. [0, 0, 0, 0, 0, 0, 0], \
  939. [0, 0, 0, 0, 0, 0, 0], \
  940. [0, 0, 0, 0, 0, 0, 0], \
  941. [0, 0, 0, 1, 0, 0, 0]], 5, 3, False), \
  942. ([[0, 0, 0, 0, 0, 0, 0], \
  943. [0, 0, 0, 0, 0, 0, 0], \
  944. [0, 0, 0, 0, 0, 0, 0], \
  945. [0, 0, 0, 1, 0, 0, 0], \
  946. [0, 0, 0, 1, 0, 0, 0], \
  947. [0, 0, 2, 1, 2, 0, 0]], 3, 3, False), \
  948. ([[0, 0, 0, 0, 0, 0, 0], \
  949. [0, 0, 0, 0, 0, 0, 0], \
  950. [1, 0, 0, 0, 0, 0, 0], \
  951. [2, 1, 0, 0, 0, 0, 0], \
  952. [2, 2, 2, 0, 0, 0, 0], \
  953. [1, 2, 1, 1, 0, 0, 0]], 4, 2, False), \
  954. ([[0, 0, 0, 0, 0, 0, 0], \
  955. [1, 2, 0, 0, 0, 0, 0], \
  956. [1, 2, 2, 1, 0, 0, 0], \
  957. [2, 1, 1, 2, 1, 0, 0], \
  958. [2, 2, 2, 1, 1, 0, 0], \
  959. [1, 2, 2, 1, 1, 0, 1]], 2, 2, False), \
  960. ([[0, 0, 0, 0, 0, 0, 0], \
  961. [0, 0, 0, 0, 0, 0, 0], \
  962. [0, 0, 0, 0, 0, 0, 0], \
  963. [0, 0, 0, 0, 0, 0, 0], \
  964. [0, 0, 0, 0, 0, 0, 0], \
  965. [1, 0, 0, 0, 0, 0, 0]], 5, 0, False), \
  966. ([[0, 0, 0, 0], \
  967. [0, 0, 0, 0], \
  968. [0, 0, 0, 0], \
  969. [0, 0, 0, 2]], 3, 3, False), \
  970. ([[2, 1, 2, 1], \
  971. [2, 1, 2, 1], \
  972. [1, 2, 1, 2], \
  973. [1, 2, 1, 2]], 0, 3, False), \
  974.  
  975. # True Horizontal
  976. ([[0, 0, 0, 0, 0, 0, 0], \
  977. [0, 0, 0, 0, 0, 0, 0], \
  978. [0, 0, 0, 0, 0, 0, 0], \
  979. [0, 0, 0, 0, 0, 0, 0], \
  980. [0, 0, 0, 0, 0, 0, 0], \
  981. [1, 1, 1, 1, 2, 2, 2]], 5, 1, True), \
  982. ([[0, 0, 0, 0, 0, 0, 0], \
  983. [0, 0, 0, 0, 0, 0, 0], \
  984. [0, 0, 0, 0, 0, 0, 0], \
  985. [0, 0, 0, 0, 0, 0, 0], \
  986. [0, 0, 0, 0, 0, 0, 0], \
  987. [1, 1, 1, 2, 2, 2, 2]], 5, 6, True), \
  988. ([[1, 1, 1, 1, 0, 0, 0], \
  989. [1, 2, 1, 2, 0, 0, 0], \
  990. [2, 1, 2, 1, 0, 0, 0], \
  991. [2, 1, 2, 2, 0, 0, 0], \
  992. [1, 2, 2, 2, 0, 0, 0], \
  993. [1, 2, 1, 2, 0, 0, 0]], 0, 3, True), \
  994. ([[0, 0, 0, 1, 1, 1, 1], \
  995. [0, 0, 0, 1, 2, 2, 2], \
  996. [0, 0, 0, 2, 1, 1, 2], \
  997. [0, 0, 0, 1, 2, 2, 2], \
  998. [0, 0, 0, 2, 1, 2, 1], \
  999. [0, 0, 0, 2, 1, 2, 1]], 0, 6, True), \
  1000.  
  1001. ]:
  1002. # Attempt the function call
  1003. try:
  1004. print(" Attempting to use wonHorizontal on board:")
  1005. print(" [%s," % str(b[0]))
  1006. for i in range(1, len(b) - 1):
  1007. print(" ", b[i], ",", sep="")
  1008. print(" ", b[-1], "]... ", sep="", end="")
  1009. result = wonHorizontal(b, r, c)
  1010. except Exception as e:
  1011. print("\nFAILED: An exception occurred during the attempt.")
  1012. traceback.print_exc(file=sys.stdout)
  1013. failed += 1
  1014. continue
  1015.  
  1016. # Does it have the correct return type?
  1017. if type(result) is not bool:
  1018. print("\nFAILED: The value returned was a", str(type(result)) + ", not a Boolean.")
  1019. failed += 1
  1020. continue
  1021.  
  1022. # Did it return the correct value
  1023. if result != a:
  1024. print("\nFAILED: The value returned was", str(result), "when", str(a), "was expected.")
  1025. failed += 1
  1026. continue
  1027.  
  1028. print("Success.")
  1029. passed += 1
  1030.  
  1031. print()
  1032. return (passed, failed)
  1033.  
  1034. #
  1035. # Run a series of tests on the wonPosSlope function
  1036. # Parameters: (None)
  1037. # Returns: True if all tests passed. False otherwise.
  1038. def testWonPosSlope():
  1039. print("Testing wonPosSlope...")
  1040.  
  1041. # Does the wonPosSlope function exist?
  1042. if functionExists("wonPosSlope"):
  1043. print(" The function seems to exist...")
  1044. else:
  1045. print(" The wonPosSlope function doesn't seem to exist...")
  1046. quit()
  1047.  
  1048. passed = 0
  1049. failed = 0
  1050. # Run a series of test cases
  1051. for (b, r, c, a) in [ \
  1052. ([[0, 0, 0, 0, 0, 0, 0], \
  1053. [0, 0, 0, 0, 0, 0, 0], \
  1054. [0, 0, 0, 0, 0, 0, 0], \
  1055. [0, 0, 0, 0, 0, 0, 0], \
  1056. [0, 0, 0, 0, 0, 0, 0], \
  1057. [0, 0, 0, 1, 0, 0, 0]], 5, 3, False), \
  1058. ([[0, 0, 0, 0, 0, 0, 0], \
  1059. [0, 0, 0, 0, 0, 0, 0], \
  1060. [0, 0, 0, 0, 0, 0, 0], \
  1061. [0, 0, 0, 1, 0, 0, 0], \
  1062. [0, 0, 0, 1, 0, 0, 0], \
  1063. [0, 0, 2, 1, 2, 0, 0]], 3, 3, False), \
  1064. ([[0, 0, 0, 0, 0, 0, 0], \
  1065. [0, 0, 0, 0, 0, 0, 0], \
  1066. [1, 0, 0, 0, 0, 0, 0], \
  1067. [2, 1, 0, 0, 0, 0, 0], \
  1068. [2, 2, 2, 0, 0, 0, 0], \
  1069. [1, 2, 1, 1, 0, 0, 0]], 4, 2, False), \
  1070. ([[0, 0, 0, 0, 0, 0, 0], \
  1071. [1, 2, 0, 0, 0, 0, 0], \
  1072. [1, 2, 2, 1, 0, 0, 0], \
  1073. [2, 1, 1, 2, 1, 0, 0], \
  1074. [2, 2, 2, 1, 1, 0, 0], \
  1075. [1, 2, 2, 1, 1, 0, 1]], 2, 2, False), \
  1076. ([[0, 0, 0, 0, 0, 0, 0], \
  1077. [0, 0, 0, 0, 0, 0, 0], \
  1078. [0, 0, 0, 0, 0, 0, 0], \
  1079. [0, 0, 0, 0, 0, 0, 0], \
  1080. [0, 0, 0, 0, 0, 0, 0], \
  1081. [1, 0, 0, 0, 0, 0, 0]], 5, 0, False), \
  1082. ([[0, 0, 0, 0], \
  1083. [0, 0, 0, 0], \
  1084. [0, 0, 0, 0], \
  1085. [0, 0, 0, 2]], 3, 3, False), \
  1086. ([[2, 1, 2, 1], \
  1087. [2, 1, 2, 1], \
  1088. [1, 2, 1, 2], \
  1089. [1, 2, 1, 2]], 0, 3, False), \
  1090. # True Pos Slope
  1091. ([[0, 0, 0, 0, 0, 0, 0], \
  1092. [0, 0, 0, 0, 0, 0, 0], \
  1093. [0, 0, 0, 1, 0, 0, 0], \
  1094. [0, 0, 1, 2, 0, 0, 0], \
  1095. [0, 1, 2, 2, 0, 0, 0], \
  1096. [1, 2, 2, 1, 0, 0, 0]], 3, 2, True), \
  1097. ([[0, 0, 0, 2, 0, 0, 0], \
  1098. [0, 0, 2, 2, 0, 0, 0], \
  1099. [0, 2, 1, 1, 0, 0, 0], \
  1100. [2, 1, 1, 2, 0, 0, 0], \
  1101. [1, 1, 2, 1, 0, 0, 0], \
  1102. [2, 2, 1, 1, 0, 0, 0]], 2, 1, True), \
  1103. ([[0, 0, 0, 0, 0, 0, 1], \
  1104. [0, 0, 0, 0, 0, 1, 2], \
  1105. [0, 0, 0, 0, 1, 1, 1], \
  1106. [0, 0, 0, 1, 2, 2, 2], \
  1107. [0, 0, 0, 2, 1, 2, 1], \
  1108. [0, 0, 0, 2, 1, 2, 2]], 1, 5, True), \
  1109. ([[0, 0, 0, 0, 0, 0, 0], \
  1110. [0, 0, 0, 0, 0, 0, 0], \
  1111. [0, 0, 0, 0, 0, 0, 2], \
  1112. [0, 0, 0, 0, 0, 2, 1], \
  1113. [0, 0, 0, 0, 2, 1, 2], \
  1114. [0, 0, 0, 2, 1, 1, 1]], 5, 3, True), \
  1115. ([[0, 0, 0, 1], \
  1116. [0, 0, 1, 2], \
  1117. [0, 1, 2, 1], \
  1118. [1, 2, 2, 2]], 0, 3, True), \
  1119.  
  1120. ]:
  1121. # Attempt the function call
  1122. try:
  1123. print(" Attempting to use wonPosSlope on board:")
  1124. print(" [%s," % str(b[0]))
  1125. for i in range(1, len(b) - 1):
  1126. print(" ", b[i], ",", sep="")
  1127. print(" ", b[-1], "]... ", sep="", end="")
  1128. result = wonPosSlope(b, r, c)
  1129. except Exception as e:
  1130. print("\nFAILED: An exception occurred during the attempt.")
  1131. traceback.print_exc(file=sys.stdout)
  1132. failed += 1
  1133. continue
  1134.  
  1135. # Does it have the correct return type?
  1136. if type(result) is not bool:
  1137. print("\nFAILED: The value returned was a", str(type(result)) + ", not a Boolean.")
  1138. failed += 1
  1139. continue
  1140.  
  1141. # Did it return the correct value
  1142. if result != a:
  1143. print("\nFAILED: The value returned was", str(result), "when", str(a), "was expected.")
  1144. failed += 1
  1145. continue
  1146.  
  1147. print("Success.")
  1148. passed += 1
  1149.  
  1150. print()
  1151. return (passed, failed)
  1152.  
  1153. #
  1154. # Run a series of tests on the wonNegSlope function
  1155. # Parameters: (None)
  1156. # Returns: True if all tests passed. False otherwise.
  1157. def testWonNegSlope():
  1158. print("Testing wonNegSlope...")
  1159.  
  1160. # Does the wonNegSlope function exist?
  1161. if functionExists("wonNegSlope"):
  1162. print(" The function seems to exist...")
  1163. else:
  1164. print(" The wonNegSlope function doesn't seem to exist...")
  1165. quit()
  1166.  
  1167. passed = 0
  1168. failed = 0
  1169. # Run a series of test cases
  1170. for (b, r, c, a) in [ \
  1171. ([[0, 0, 0, 0, 0, 0, 0], \
  1172. [0, 0, 0, 0, 0, 0, 0], \
  1173. [0, 0, 0, 0, 0, 0, 0], \
  1174. [0, 0, 0, 0, 0, 0, 0], \
  1175. [0, 0, 0, 0, 0, 0, 0], \
  1176. [0, 0, 0, 1, 0, 0, 0]], 5, 3, False), \
  1177. ([[0, 0, 0, 0, 0, 0, 0], \
  1178. [0, 0, 0, 0, 0, 0, 0], \
  1179. [0, 0, 0, 0, 0, 0, 0], \
  1180. [0, 0, 0, 1, 0, 0, 0], \
  1181. [0, 0, 0, 1, 0, 0, 0], \
  1182. [0, 0, 2, 1, 2, 0, 0]], 3, 3, False), \
  1183. ([[0, 0, 0, 0, 0, 0, 0], \
  1184. [0, 0, 0, 0, 0, 0, 0], \
  1185. [1, 0, 0, 0, 0, 0, 0], \
  1186. [2, 1, 0, 0, 0, 0, 0], \
  1187. [2, 2, 2, 0, 0, 0, 0], \
  1188. [1, 2, 1, 1, 0, 0, 0]], 4, 2, False), \
  1189. ([[0, 0, 0, 0, 0, 0, 0], \
  1190. [1, 2, 0, 0, 0, 0, 0], \
  1191. [1, 2, 2, 1, 0, 0, 0], \
  1192. [2, 1, 1, 2, 1, 0, 0], \
  1193. [2, 2, 2, 1, 1, 0, 0], \
  1194. [1, 2, 2, 1, 1, 0, 1]], 2, 2, False), \
  1195. ([[0, 0, 0, 0, 0, 0, 0], \
  1196. [0, 0, 0, 0, 0, 0, 0], \
  1197. [0, 0, 0, 0, 0, 0, 0], \
  1198. [0, 0, 0, 0, 0, 0, 0], \
  1199. [0, 0, 0, 0, 0, 0, 0], \
  1200. [1, 0, 0, 0, 0, 0, 0]], 5, 0, False), \
  1201. ([[0, 0, 0, 0], \
  1202. [0, 0, 0, 0], \
  1203. [0, 0, 0, 0], \
  1204. [0, 0, 0, 2]], 3, 3, False), \
  1205. ([[2, 1, 2, 1], \
  1206. [2, 1, 2, 1], \
  1207. [1, 2, 1, 2], \
  1208. [1, 2, 1, 2]], 0, 3, False), \
  1209.  
  1210. # True Neg Slope
  1211. ([[0, 0, 0, 0, 0, 0, 0], \
  1212. [0, 0, 0, 0, 0, 0, 0], \
  1213. [1, 0, 0, 0, 0, 0, 0], \
  1214. [2, 1, 0, 0, 0, 0, 0], \
  1215. [2, 2, 1, 0, 0, 0, 0], \
  1216. [1, 2, 2, 1, 0, 0, 0]], 4, 2, True), \
  1217. ([[2, 0, 0, 0, 0, 0, 0], \
  1218. [1, 2, 0, 0, 0, 0, 0], \
  1219. [1, 1, 2, 1, 0, 0, 0], \
  1220. [2, 2, 1, 2, 1, 0, 0], \
  1221. [2, 1, 2, 2, 1, 0, 0], \
  1222. [1, 2, 2, 1, 1, 0, 1]], 2, 2, True), \
  1223. ([[0, 0, 0, 2, 0, 0, 0], \
  1224. [0, 0, 0, 1, 2, 0, 0], \
  1225. [0, 0, 0, 1, 1, 2, 1], \
  1226. [0, 0, 0, 2, 1, 1, 2], \
  1227. [0, 1, 0, 2, 2, 2, 2], \
  1228. [0, 1, 0, 1, 2, 2, 1]], 0, 3, True), \
  1229. ([[0, 0, 0, 2, 0, 0, 0], \
  1230. [0, 0, 0, 1, 0, 0, 0], \
  1231. [0, 0, 0, 1, 0, 0, 0], \
  1232. [0, 0, 0, 2, 1, 1, 2], \
  1233. [0, 1, 0, 2, 2, 1, 2], \
  1234. [0, 1, 0, 1, 2, 2, 1]], 3, 4, True), \
  1235. ]:
  1236. # Attempt the function call
  1237. try:
  1238. print(" Attempting to use wonNegSlope on board:")
  1239. print(" [%s," % str(b[0]))
  1240. for i in range(1, len(b) - 1):
  1241. print(" ", b[i], ",", sep="")
  1242. print(" ", b[-1], "]... ", sep="", end="")
  1243. result = wonNegSlope(b, r, c)
  1244. except Exception as e:
  1245. print("\nFAILED: An exception occurred during the attempt.")
  1246. traceback.print_exc(file=sys.stdout)
  1247. failed += 1
  1248. continue
  1249.  
  1250. # Does it have the correct return type?
  1251. if type(result) is not bool:
  1252. print("\nFAILED: The value returned was a", str(type(result)) + ", not a Boolean.")
  1253. failed += 1
  1254. continue
  1255.  
  1256. # Did it return the correct value
  1257. if result != a:
  1258. print("\nFAILED: The value returned was", str(result), "when", str(a), "was expected.")
  1259. failed += 1
  1260. continue
  1261.  
  1262. print("Success.")
  1263. passed += 1
  1264.  
  1265. print()
  1266. return (passed, failed)
  1267.  
  1268. #
  1269. # Run a series of tests on the canWin function
  1270. # Parameters: (None)
  1271. # Returns: True if all tests passed. False otherwise.
  1272. def testCanWin():
  1273. print("Testing canWin...")
  1274.  
  1275. # Does the canWin function exist?
  1276. if functionExists("canWin"):
  1277. print(" The function seems to exist...")
  1278. else:
  1279. print(" The canWin function doesn't seem to exist...")
  1280. quit()
  1281.  
  1282. passed = 0
  1283. failed = 0
  1284. # Run a series of test cases
  1285. for (b, p, a) in [ \
  1286. ([[0, 0, 0, 0, 0, 0, 0], \
  1287. [0, 0, 0, 0, 0, 0, 0], \
  1288. [0, 0, 0, 0, 0, 0, 0], \
  1289. [0, 0, 0, 0, 0, 0, 0], \
  1290. [0, 0, 0, 0, 0, 0, 0], \
  1291. [0, 0, 0, 1, 0, 0, 0]], PLAYER_2, -1), \
  1292. ([[0, 0, 0, 0, 0, 0, 0], \
  1293. [0, 0, 0, 0, 0, 0, 0], \
  1294. [0, 0, 0, 0, 0, 0, 0], \
  1295. [0, 0, 0, 0, 0, 0, 0], \
  1296. [0, 0, 0, 1, 0, 0, 0], \
  1297. [0, 0, 2, 1, 2, 0, 0]], PLAYER_1, -1), \
  1298. ([[0, 0, 0, 0, 0, 0, 0], \
  1299. [0, 0, 0, 0, 0, 0, 0], \
  1300. [0, 0, 0, 0, 0, 0, 0], \
  1301. [0, 0, 0, 1, 0, 0, 0], \
  1302. [0, 0, 0, 1, 2, 0, 0], \
  1303. [0, 0, 2, 1, 2, 0, 0]], PLAYER_1, 3), \
  1304. ([[0, 0, 0, 0, 0, 0, 0], \
  1305. [0, 0, 0, 0, 0, 0, 0], \
  1306. [1, 0, 0, 0, 0, 0, 0], \
  1307. [2, 1, 0, 0, 0, 0, 0], \
  1308. [2, 2, 0, 0, 0, 0, 0], \
  1309. [1, 2, 2, 1, 0, 0, 0]], PLAYER_1, 2), \
  1310. ([[0, 0, 0, 0, 0, 0, 0], \
  1311. [0, 0, 0, 0, 0, 0, 0], \
  1312. [1, 0, 0, 0, 0, 0, 0], \
  1313. [2, 1, 0, 0, 0, 0, 0], \
  1314. [2, 2, 2, 0, 0, 0, 0], \
  1315. [1, 2, 1, 1, 0, 0, 0]], PLAYER_1, -1), \
  1316. ([[2, 0, 0, 0, 0, 0, 0], \
  1317. [1, 2, 0, 0, 0, 0, 0], \
  1318. [1, 1, 0, 1, 0, 0, 0], \
  1319. [2, 2, 1, 2, 1, 0, 2], \
  1320. [2, 1, 1, 2, 1, 0, 2], \
  1321. [1, 2, 2, 1, 1, 0, 1]], PLAYER_2, 2), \
  1322. ([[0, 0, 0, 0, 0, 0, 0], \
  1323. [1, 2, 0, 0, 0, 0, 0], \
  1324. [1, 2, 2, 1, 0, 0, 0], \
  1325. [2, 1, 1, 2, 0, 0, 0], \
  1326. [2, 2, 2, 1, 1, 0, 1], \
  1327. [1, 2, 2, 1, 2, 0, 1]], PLAYER_1, -1), \
  1328. ([[0, 0, 0, 2, 0, 0, 0], \
  1329. [0, 0, 0, 1, 2, 0, 0], \
  1330. [0, 0, 0, 1, 1, 0, 1], \
  1331. [0, 0, 0, 2, 1, 1, 2], \
  1332. [0, 1, 0, 2, 2, 2, 2], \
  1333. [0, 1, 0, 1, 2, 2, 1]], PLAYER_2, 5), \
  1334. ([[0, 0, 0, 2, 0, 0, 0], \
  1335. [0, 0, 0, 1, 0, 0, 0], \
  1336. [0, 0, 0, 1, 0, 0, 0], \
  1337. [0, 0, 0, 2, 0, 1, 2], \
  1338. [0, 1, 0, 2, 2, 1, 2], \
  1339. [0, 1, 0, 1, 2, 2, 1]], PLAYER_1, 4), \
  1340. ([[0, 0, 0, 0, 0, 0, 0], \
  1341. [0, 0, 0, 0, 0, 0, 0], \
  1342. [0, 0, 0, 0, 0, 0, 0], \
  1343. [1, 2, 0, 0, 0, 0, 0], \
  1344. [1, 2, 0, 0, 0, 0, 0], \
  1345. [1, 2, 0, 0, 0, 0, 0]], PLAYER_1, 0), \
  1346. ([[0, 0, 0, 0, 0, 0, 0], \
  1347. [1, 2, 0, 0, 0, 0, 0], \
  1348. [1, 2, 0, 0, 0, 0, 0], \
  1349. [1, 2, 0, 0, 0, 0, 0], \
  1350. [2, 1, 0, 0, 0, 0, 0], \
  1351. [1, 2, 0, 0, 0, 0, 0]], PLAYER_1, 0), \
  1352. ([[0, 0, 0, 0, 0, 0, 0], \
  1353. [0, 0, 0, 0, 0, 0, 0], \
  1354. [1, 0, 0, 0, 0, 0, 0], \
  1355. [2, 1, 0, 0, 0, 1, 2], \
  1356. [1, 2, 0, 0, 0, 1, 2], \
  1357. [1, 2, 0, 0, 0, 1, 2]], PLAYER_2, 6), \
  1358. ([[0, 0, 0, 0, 0, 0, 0], \
  1359. [1, 0, 0, 0, 0, 1, 2], \
  1360. [1, 2, 0, 0, 0, 1, 2], \
  1361. [1, 2, 0, 0, 0, 2, 2], \
  1362. [2, 1, 0, 0, 0, 1, 1], \
  1363. [1, 2, 2, 0, 0, 1, 2]], PLAYER_2, 6), \
  1364. ([[0, 0, 0, 0, 0, 0, 0], \
  1365. [0, 0, 0, 0, 0, 0, 0], \
  1366. [0, 0, 0, 1, 0, 0, 0], \
  1367. [0, 0, 0, 2, 0, 0, 0], \
  1368. [0, 1, 2, 2, 0, 0, 0], \
  1369. [1, 2, 2, 1, 0, 0, 0]], PLAYER_1, 2), \
  1370. ([[0, 0, 0, 2, 0, 0, 0], \
  1371. [0, 0, 2, 2, 0, 0, 0], \
  1372. [0, 0, 1, 1, 0, 0, 0], \
  1373. [2, 1, 1, 2, 0, 0, 0], \
  1374. [1, 1, 2, 1, 0, 0, 0], \
  1375. [2, 2, 1, 1, 0, 0, 0]], PLAYER_2, 1), \
  1376. ([[0, 0, 0, 0, 0, 0, 1], \
  1377. [0, 0, 0, 0, 0, 0, 1], \
  1378. [0, 0, 0, 0, 1, 2, 2], \
  1379. [0, 0, 0, 1, 2, 1, 2], \
  1380. [0, 0, 0, 2, 1, 2, 1], \
  1381. [0, 0, 0, 2, 1, 2, 2]], PLAYER_1, 5), \
  1382. ([[0, 0, 0, 0, 0, 0, 0], \
  1383. [0, 0, 0, 0, 0, 0, 0], \
  1384. [0, 0, 0, 0, 0, 0, 2], \
  1385. [0, 0, 0, 0, 0, 2, 1], \
  1386. [0, 0, 0, 0, 2, 1, 2], \
  1387. [0, 0, 0, 0, 1, 1, 1]], PLAYER_2, 3), \
  1388. ([[0, 0, 0, 0, 0, 0, 0], \
  1389. [0, 0, 0, 0, 0, 0, 0], \
  1390. [0, 0, 0, 0, 0, 0, 0], \
  1391. [0, 0, 0, 0, 0, 0, 0], \
  1392. [0, 0, 0, 0, 0, 0, 0], \
  1393. [1, 0, 1, 1, 2, 2, 2]], PLAYER_1, 1), \
  1394. ([[0, 0, 0, 0, 0, 0, 0], \
  1395. [0, 0, 0, 0, 0, 0, 0], \
  1396. [0, 0, 0, 0, 0, 0, 0], \
  1397. [0, 0, 0, 0, 0, 0, 0], \
  1398. [0, 0, 0, 0, 0, 0, 0], \
  1399. [1, 1, 1, 2, 2, 2, 0]], PLAYER_2, 6), \
  1400. ([[1, 1, 1, 0, 0, 0, 0], \
  1401. [1, 2, 1, 2, 0, 0, 0], \
  1402. [2, 1, 2, 1, 0, 0, 0], \
  1403. [2, 1, 2, 2, 0, 0, 0], \
  1404. [1, 2, 2, 2, 0, 0, 0], \
  1405. [1, 2, 1, 2, 0, 0, 0]], PLAYER_1, 3), \
  1406. ([[0, 0, 0, 1, 1, 1, 0], \
  1407. [0, 0, 0, 1, 2, 2, 2], \
  1408. [0, 0, 0, 2, 1, 1, 2], \
  1409. [0, 0, 0, 1, 2, 2, 2], \
  1410. [0, 0, 0, 2, 1, 2, 1], \
  1411. [0, 0, 0, 2, 1, 2, 1]], PLAYER_1, 6), \
  1412. ([[0, 0, 0, 0, 0, 0, 0], \
  1413. [0, 0, 0, 0, 0, 0, 0], \
  1414. [0, 0, 0, 0, 0, 0, 0], \
  1415. [0, 0, 0, 0, 0, 0, 0], \
  1416. [0, 0, 0, 0, 0, 0, 0], \
  1417. [1, 0, 0, 0, 0, 0, 0]], PLAYER_2, -1), \
  1418. ([[0, 0, 0, 0], \
  1419. [0, 0, 0, 0], \
  1420. [0, 0, 0, 0], \
  1421. [0, 0, 0, 2]], PLAYER_1, -1), \
  1422. ([[2, 1, 2, 0], \
  1423. [2, 1, 2, 1], \
  1424. [1, 2, 1, 2], \
  1425. [1, 2, 1, 2]], PLAYER_1, -1), \
  1426. ([[0, 0, 0, 0], \
  1427. [0, 0, 1, 2], \
  1428. [0, 1, 2, 1], \
  1429. [1, 2, 2, 2]], PLAYER_1, 3), \
  1430. ]:
  1431. # Attempt the function call
  1432. try:
  1433. print(" Attempting to use canWin on board with Player %d:" % p)
  1434. print(" [%s," % str(b[0]))
  1435. for i in range(1, len(b) - 1):
  1436. print(" ", b[i], ",", sep="")
  1437. print(" ", b[-1], "]... ", sep="", end="")
  1438. result = canWin(b, p)
  1439. except Exception as e:
  1440. print("\nFAILED: An exception occurred during the attempt.")
  1441. traceback.print_exc(file=sys.stdout)
  1442. failed += 1
  1443. continue
  1444.  
  1445. # Does it have the correct return type?
  1446. if type(result) is not int:
  1447. print("\nFAILED: The value returned was a", str(type(result)) + ", not an integer.")
  1448. failed += 1
  1449. continue
  1450.  
  1451. # Did it return the correct value
  1452. if result != a:
  1453. print("\nFAILED: The value returned was", str(result), "when", str(a), "was expected.")
  1454. failed += 1
  1455. continue
  1456.  
  1457. print("Success.")
  1458. passed += 1
  1459.  
  1460. print()
  1461. return (passed, failed)
  1462.  
  1463. #
  1464. # Play a game of connect 4 between the user and a computer AI.
  1465. #
  1466. # Parameters: None.
  1467. #
  1468. # Returns: None.
  1469. #
  1470. def main():
  1471. # Set the default board size
  1472. columns = 7
  1473. rows = 6
  1474. ai = ai_medium
  1475.  
  1476. # Process the command line parameters and reset the game board size if
  1477. # necessary
  1478. if len(sys.argv) == 3 or len(sys.argv) >= 5:
  1479. usage()
  1480. if len(sys.argv) >= 2:
  1481. if sys.argv[1].lower() == "predictable":
  1482. ai = ai_predictable
  1483. print("Setting the AI to predictable...")
  1484. elif sys.argv[1].lower() == "easy":
  1485. ai = ai_easy
  1486. print("Setting the AI to easy...")
  1487. elif sys.argv[1].lower() == "medium":
  1488. ai = ai_medium
  1489. print("Setting the AI to medium...")
  1490. elif sys.argv[1].lower() == "hard":
  1491. ai = ai_hard
  1492. print("Setting the AI to hard...")
  1493. else:
  1494. print("An invalid difficulty level was specified...\n")
  1495. usage()
  1496. if len(sys.argv) >= 3:
  1497. try:
  1498. rows = int(sys.argv[2])
  1499. if rows < 4:
  1500. print("\nThe game board must have at least 4 rows. Quitting...\n")
  1501. close()
  1502. quit()
  1503. except ValueError:
  1504. print("\n'%s' is not a valid number of rows. Quitting...\n" % sys.argv[2])
  1505. close()
  1506. quit()
  1507.  
  1508. try:
  1509. columns = int(sys.argv[3])
  1510. if columns < 4:
  1511. print("\nThe game board must have at least 4 columns. Quitting...\n")
  1512. close()
  1513. quit()
  1514. except ValueError:
  1515. print("\n'%s' is not a valid number of columns. Quitting...\n" % sys.argv[3])
  1516. close()
  1517. quit()
  1518.  
  1519. # Verify that the image files are present
  1520. if os.path.isfile("Win.gif") == False or \
  1521. os.path.isfile("Lose.gif") == False or \
  1522. os.path.isfile("Tie.gif") == False or \
  1523. os.path.isfile("Grid.gif") == False:
  1524. print("This program requires access to Win.gif, Lose.gif, Tie.gif and")
  1525. print("Grid.gif. Please download them from the course website and save")
  1526. print("them in the same directory as this program.")
  1527. close()
  1528. quit()
  1529.  
  1530. # Test the student's functions
  1531. if testCreateBoard() == False:
  1532. close()
  1533. quit()
  1534. if testColumnFull() == False:
  1535. close()
  1536. quit()
  1537. if testDropChecker() == False:
  1538. close()
  1539. quit()
  1540. if testGameTied() == False:
  1541. close()
  1542. quit()
  1543. (whp, whf) = testWonHorizontal()
  1544. (wvp, wvf) = testWonVertical()
  1545. (wpsp, wpsf) = testWonPosSlope()
  1546. (wnsp, wnsf) = testWonNegSlope()
  1547. (cwp, cwf) = testCanWin()
  1548.  
  1549. print("Summary:")
  1550. print(" createBoard passed all test cases!")
  1551. print(" columnFull passed all test cases!")
  1552. print(" dropChecker passed all test cases!")
  1553. print(" gameTied passed all test cases!")
  1554. failed = False
  1555. for (p, f, name) in [(whp, whf, "wonHorizontal"), (wvp, wvf, "wonVertical"), (wpsp, wpsf, "wonPosSlope"), (wnsp, wnsf, "wonNegSlope")]:
  1556. if f == 0:
  1557. print(" %s passed all test cases!" % name)
  1558. else:
  1559. print(" %s passed" % name, p, "test cases and failed", f, "test cases.")
  1560. failed = True
  1561. if cwf == 0:
  1562. print(" canWin passed all test cases!")
  1563. else:
  1564. print(" canWin passed", cwp, "test cases and failed", cwf, "test cases.")
  1565.  
  1566. if failed or cwf > 0:
  1567. print(" *****************************************************")
  1568. print(" ** **")
  1569. print(" ** WARNING: THERE WERE TEST CASES THAT FAILED!!! **")
  1570. print(" ** **")
  1571. print(" *****************************************************")
  1572. print()
  1573.  
  1574. gridImage = loadImage("Grid.gif")
  1575.  
  1576. # Resize the window so that it is exactly the right size for the board and
  1577. # user interface
  1578. resize(SIZE * columns, SIZE * rows + BUTTON_HEIGHT + STATUS_HEIGHT)
  1579. setAutoUpdate(False)
  1580.  
  1581. # Create the board
  1582. print("Creating the board...")
  1583. board = createBoard(rows, columns)
  1584.  
  1585. # Identify the starting player
  1586. turn = startingPlayer()
  1587. print("The starting player will be Player %d..." % turn)
  1588.  
  1589. # Continue playing until there is a winner
  1590. col = -1
  1591. row = -1
  1592. while gameTied(board) == False and (col == -1 or gameWon(board, row, col) == False) and not closed():
  1593. # Update the user interface
  1594. drawBoard(board, gridImage)
  1595. pprint(board)
  1596. if turn == PLAYER_1:
  1597. drawButtons(board)
  1598. drawStatus("It's your turn!", board)
  1599. print("It's your turn!")
  1600. clearMouseEvents()
  1601. else:
  1602. setColor(192, 192, 192)
  1603. rect(0, 0, (len(board) + 1) * SIZE, BUTTON_HEIGHT)
  1604. drawStatus("Player 2 is thinking...", board)
  1605. print("Player 2 is about to make it's move...")
  1606. update()
  1607.  
  1608. if turn == PLAYER_1:
  1609. # Get a column from the user
  1610. col = -1
  1611. while col == -1 and not closed():
  1612. me = getMouseEvent()
  1613. while not closed() and (me == None or me[0] != "<ButtonRelease-1>"):
  1614. update()
  1615. me = getMouseEvent()
  1616.  
  1617. col = mouseX() // SIZE
  1618. if col >= len(board[0]) or col < 0 or columnFull(board, col):
  1619. col = -1
  1620.  
  1621. if turn == PLAYER_2:
  1622. sleep(THINK_TIME)
  1623. col = ai(board)
  1624.  
  1625. row = dropChecker(board, col)
  1626. animateDrop(board, row, col, turn, gridImage)
  1627. board[row][col] = turn
  1628.  
  1629. # Make it the other player's turn
  1630. if turn == PLAYER_1:
  1631. turn = PLAYER_2
  1632. else:
  1633. turn = PLAYER_1
  1634.  
  1635. # The game is over
  1636. drawBoard(board, gridImage)
  1637. drawButtons(board)
  1638. drawStatus("", board)
  1639. update()
  1640.  
  1641. # Need to display the winner, or a message that indicates that it was a tie
  1642. if gameWon(board, row, col):
  1643. if turn == PLAYER_2:
  1644. resultImage = loadImage("Win.gif")
  1645. drawStatus("The human player won the game!", board)
  1646. else:
  1647. resultImage = loadImage("Lose.gif")
  1648. drawStatus("The human player lost the game :(", board)
  1649. sleep(0.1)
  1650. drawImage(resultImage, getWidth() // 2 - getWidth(resultImage) // 2, getHeight() // 2 - getHeight(resultImage) // 2)
  1651. else:
  1652. drawStatus("It was a tie!", board)
  1653. sleep(0.1)
  1654. resultImage = loadImage("Tie.gif")
  1655. drawImage(resultImage, getWidth() // 2 - getWidth(resultImage) // 2, getHeight() // 2 - getHeight(resultImage) // 2)
  1656.  
  1657. # Get the game started
  1658. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement