Advertisement
Guest User

Untitled

a guest
Nov 16th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.49 KB | None | 0 0
  1. import numpy as np
  2. import random
  3.  
  4. class Game:
  5. mat = None
  6. rows = 6
  7. cols = 7
  8. turn = 0
  9. wins = 4
  10.  
  11.  
  12. game = Game()
  13.  
  14. def pop_check(game):
  15. pop_list = [] #tempory list for holding pop possibilities
  16. pop_col = [] #temp list for holding columns of each possibility
  17. pop_row = [] #need to know row list for diagonals
  18. critcol=0 #nothin if no pop possibilities
  19. #HORIZONTAL
  20. for r in range(0,game.rows,1): #iterating through all rows
  21. for c in range(0,game.cols-game.wins+1,1): #iterating all the columns for each row
  22. while c < game.cols-1 and game.mat[r][c] != 0:
  23. while len(pop_list) < game.wins:
  24. critrow = r
  25. pop_col.append (c)
  26. pop_list.append (game.mat [r][c])
  27. c+=1 #now poplist has the correct number of pieces
  28. if 0 in pop_list:
  29. continue
  30. if pop_list.count(game.turn)==1: #theres a potential for a pop for current turn.
  31. critcol = pop_col [pop_list.index(game.turn)] #this is the number of the column that'll be needed
  32. if game.mat [critrow+1][critcol] == game.turn and game.mat [0][critcol] == game.turn:#check above piece and bottom pieces for match
  33. return (critcol,1)#return to pop
  34.  
  35. elif pop_list.count(game.turn%2+1)==1: # potential for pop for other player
  36. critcol = pop_col [pop_list.index(game.turn%2+1)]
  37. if game.mat [critrow+1][critcol] and game.mat [0][critcol] == game.turn%2+1:#check above piece and bottom pieces for match
  38. for sidecol in pop_col: #pick the col list again
  39. if sidecol != critcol: #take each value thats NOT critcol
  40. if game.mat [critrow+1][sidecol] and game.mat [0][sidecol] == game.turn: #check for popping possibility
  41. return (sidecol,2) #pop it
  42. else:
  43. continue
  44. else:
  45. pop_list = []
  46. pop_col = []
  47. continue
  48. #DIAGONAL 1
  49. for r in range(0,game.rows-game.wins+1,1): #iterating through rows where starting of sequence is possible
  50. for c in range(0,game.cols-game.wins+1,1): #iterating through columns where starting of sequence is possible
  51. while r < game.rows-1 and c < game.cols-1 and game.mat[r][c] != 0:
  52. while len(pop_list) < game.wins:
  53. pop_row.append (r)
  54. pop_col.append (c)
  55. pop_list.append (game.mat [r][c])
  56. c+1
  57. r+1
  58. if 0 in pop_list:
  59. continue
  60. if pop_list.count(game.turn)==1: #theres a potential for a pop for current turn.
  61. critcol = pop_col [pop_list.index(game.turn)]
  62. critrow = pop_row [pop_list.index(game.turn)]
  63. if game.mat [critrow+1][critcol] == game.turn and game.mat [0][critcol] == game.turn:#check above piece and bottom pieces for match
  64. return (critcol,1)#return to pop
  65.  
  66. elif pop_list.count(game.turn%2+1)==1: # potential for pop for other player
  67. critcol = pop_col [pop_list.index(game.turn%2+1)]
  68. critrow = pop_row [pop_list.index(game.turn%2+1)]
  69. if game.mat [critrow+1][critcol] and game.mat [0][critcol] == game.turn%2+1:
  70. for sidecol in pop_col:
  71. siderow = pop_row[pop_col.index(sidecol)]
  72. if sidecol != critcol:
  73. if game.mat [critrow+1][sidecol] and game.mat [0][sidecol] == game.turn: #check for blocking possibility
  74. return (sidecol,2) #pop it
  75. else:
  76. continue
  77.  
  78.  
  79. else:
  80. pop_list = []
  81. pop_col = []
  82. continue
  83.  
  84. #DIAGONAL 2
  85. for r in range(0,game.rows-game.wins+1,1): #iterating through rows where starting of sequence is possible
  86. for c in range(0,game.cols-game.wins+1,1): #iterating through columns where starting of sequence is possible
  87. while r < game.rows-1 and c < game.cols-1 and game.mat[r][c] != 0:
  88. while len(pop_list) < game.wins:
  89. pop_row.append (r)
  90. pop_col.append (c)
  91. pop_list.append (game.mat [r][c])
  92. c-1
  93. r+1
  94. if 0 in pop_list:
  95. continue
  96. if pop_list.count(game.turn)==1: #theres a potential for a pop for current turn.
  97. critcol = pop_col [pop_list.index(game.turn)]
  98. critrow = pop_row [pop_list.index(game.turn)]
  99. if game.mat [critrow+1][critcol] == game.turn and game.mat [0][critcol] == game.turn:#check above piece and bottom pieces for match
  100. return (critcol,1)#return to pop
  101.  
  102. elif pop_list.count(game.turn%2+1)==1: # potential for pop for other player
  103. critcol = pop_col[pop_list.index(game.turn%2+1)]
  104. critrow = pop_row[pop_list.index(game.turn%2+1)]
  105. if game.mat [critrow+1][critcol] and game.mat [0][critcol] == game.turn%2+1:
  106. for sidecol in pop_col:
  107. siderow = pop_row[pop_col.index(sidecol)]
  108. if sidecol != critcol:
  109. if game.mat [critrow+1][sidecol] and game.mat [0][sidecol] == game.turn: #check for blocking possibility
  110. return (sidecol,2) #pop it
  111. else:
  112. continue
  113.  
  114.  
  115. else:
  116. pop_list = []
  117. pop_col = []
  118. continue
  119. def computer_check(game):
  120. temp_board = game.mat.copy()
  121. for i in range(game.cols):
  122. for j in range(2):
  123. if j == 0:
  124. pop_option = False
  125. else:
  126. pop_option = True
  127. move_validity = check_move(game,i,pop_option)
  128. if move_validity == True:
  129. apply_move(game,i,pop_option)
  130. possible_win = check_victory(game)
  131. game.mat = temp_board
  132. if possible_win == 1 and game.turn == 2:
  133. apply_move(game,i,pop_option)
  134. return i,pop_option
  135. elif possible_win == 2 and game.turn == 1:
  136. apply_move(game,i,pop_option)
  137. return i,pop_option
  138. else:
  139. continue
  140.  
  141.  
  142. def human_move(game):
  143. while True:
  144. while True:
  145. try:
  146. if game.turn == 1: #deciding whose turn it is
  147. player_move = input("Player 1 please pick a column: ")
  148. elif game.turn == 2:
  149. player_move = input("Player 2 please pick a column: ")
  150. int(player_move)
  151. if not 0 <= int(player_move) <= game.cols-1: #selected column must be within range
  152. print("Please pick a valid column!")
  153. continue #ask the question again for invalid input
  154. else:
  155. player_move = int(player_move)
  156. break #escapes the loop for valid input
  157. except ValueError:
  158. print("Please pick a valid column!")
  159. continue
  160. while True:
  161. pop_option = (input("Enter 1 if you'd like to pop; enter 2 otherwise: "))
  162. if pop_option == "1":
  163. pop_option = True #player wants to pop
  164. break
  165. elif pop_option == "2":
  166. pop_option = False #player does not want to pop
  167. break
  168. else:
  169. print("Please pick either 1 or 2!")
  170.  
  171. move_validity = check_move(game,player_move,pop_option)
  172. if not move_validity:
  173. print("Move not valid. Please try again")
  174. continue #if move is invalid, ask for a new column input
  175. else:
  176. apply_move(game,player_move,pop_option) #if move is valid, apply it
  177. break
  178.  
  179. def display_board(game):
  180. print(np.flip(game.mat,0))
  181.  
  182.  
  183. def check_victory(game):
  184. #input the if game = game.mat
  185. winlist = [] #list of win conditions to be used to determine winner and outcome
  186. tick = 0 #counter for consecutive disks in a row
  187. #horizontal check
  188. for r in range(0,game.rows,1): #iterating through all rows
  189. for c in range(0,game.cols-game.wins+1,1): #iterating all the columns for each row
  190. while c < game.cols-1 and game.mat[r][c] != 0:
  191. #checking all spaces that aren't empty until c+1 becomes invalid
  192. if game.mat[r][c] == game.mat[r][c+1]:
  193. tick += 1 #counter goes up if consecutive disks are equal
  194. if tick == game.wins-1:
  195. #when the counter hits game.wins-1, a win condition has been reached
  196. #said win condition is appended to the list
  197. winlist.append(game.mat[r][c])
  198. break
  199. c += 1 #c increases to continue checking consecutive disks
  200. continue
  201. else:
  202. tick = 0 #counter resets when consecutive disks aren't the same
  203. break
  204.  
  205. #vertical check
  206. for c in range(0,game.cols,1): #iterating through all columns
  207. for r in range(0,game.rows-game.wins+1,1): #iterating through all rows for each column
  208. while r < game.rows-1 and game.mat[r][c] != 0:
  209. #checking all spaces that aren't empty until r+1 becomes invalid
  210. if game.mat[r][c] == game.mat[r+1][c]:
  211. tick += 1 #counter goes up if consecutive disks are equal
  212. if tick == game.wins-1:
  213. #when counter hits game.wins-1, a win condition has been reached
  214. #said win condition is appended to list
  215. winlist.append(game.mat[r][c])
  216. break
  217. r += 1 #r increases to continue checking consecutive disks
  218. continue
  219. else:
  220. tick = 0 #counter resets when consecutive disks aren't the same
  221. break
  222.  
  223. #diagonal check 1
  224. for r in range(0,game.rows-game.wins+1,1): #iterating through rows where starting of sequence is possible
  225. for c in range(0,game.cols-game.wins+1,1): #iterating through columns where starting of sequence is possible
  226. while r < game.rows-1 and c < game.cols-1 and game.mat[r][c] != 0:
  227. #checking non-zero spaces until r+1 or c+1 becomes invalid
  228. if game.mat[r][c] == game.mat[r+1][c+1]:
  229. tick +=1 #counter goes up with consecutive disks being equal
  230. if tick == game.wins-1:
  231. winlist.append(game.mat[r][c])
  232. break
  233. r += 1 #both r and c increase to continue checking consecutive disks
  234. c += 1
  235. continue
  236. else:
  237. tick = 0
  238. break
  239.  
  240. #diagonal check 2
  241. for r in range(game.wins-1,game.rows,1): #iterating through rows where start of sequence is possiblke
  242. for c in range(0,game.cols-game.wins+1,1): #iterating through columns where start of sequence is possible
  243. while r > 0 and c < game.cols-1 and game.mat[r][c] != 0:
  244. #checking non-zero spaces until r-1 or c+1 becomes invalid
  245. if game.mat[r][c] ==game.mat[r-1][c+1]:
  246. tick +=1 #counter goes up with consecutive disks being equal
  247. if tick == game.wins-1:
  248. winlist.append(game.mat[r][c])
  249. break
  250. r -= 1 #r decreases and c increases to continue checking consecutive disks in that direction
  251. c += 1
  252. continue
  253. else:
  254. tick = 0
  255. break
  256.  
  257. #processing winning instances
  258. if len(winlist) == 0: #no winning instances
  259. if np.count_nonzero(game.mat) == game.mat.size: #entire board is filled
  260. win = 3 #it's a draw
  261. else:
  262. win = 0 #if board isn't filled, next turn commences
  263. elif len(winlist) >= 2: #if a single turn causes more than 1 win condition to be reached
  264. #if player 1 dropped the last disks, we check for 1s within the win conditions
  265. #if it exists, we know player 1 has a game.wins in a row and so they win
  266. #if it doesn't exist, we know player 1 gave the win to player 2
  267. if game.turn == 1:
  268. if 2 in winlist: #turn was changed in apply_move
  269. win = 2
  270. else:
  271. win = 1
  272. #vice versa for player 2
  273. else:
  274. if 1 in winlist:
  275. win = 1
  276. else:
  277. win = 2
  278. else:
  279. win = int(winlist[0]) #only 1 win condition, so we look at their values
  280. return (win)
  281.  
  282. def apply_move(game,col,pop):
  283. if pop == False: #
  284. for i in range(0,game.rows,1):
  285. if game.mat[i][col] == 0: #check for the first space from the bottom in that column that's empty
  286. game.mat[i][col] = game.turn #replace empty space with player's chip
  287. break
  288. else:
  289. for i in range(1,game.rows,1):
  290. game.mat[i-1][col] = game.mat[i][col] #replace every value in that column with the one above
  291. game.mat[game.rows-1][col] = 0 #set top row of the column as 0
  292. if game.turn == 1: #change of turn
  293. game.turn = 2
  294. elif game.turn == 2:
  295. game.turn = 1
  296. return game
  297.  
  298. def check_move(game,col,pop):
  299. if pop == False: #no popping, so the disk is dropped from the top
  300. if game.mat[game.rows-1][col] != 0: #checking top most space of the column; if it's not empty, the column is full
  301. move_validity = False #column is full so move is invalid
  302. else:
  303. move_validity = True #column isn't full so move is valid
  304. if pop == True: #popping so disk is removed from the bottom
  305. if game.mat[0][col] != game.turn: #checking bottom most space of column to see if it's the current player's
  306. move_validity = False #bottom disk isn't the player's so move is invalid
  307. else:
  308. move_validity = True #bottom disk belongs to the player so move is valid
  309. return move_validity
  310.  
  311. def computer_move(game,level):
  312. if level == 1:
  313. while True:
  314. player_move = random.randint(0,game.cols-1)
  315. pop_option = random.randint(1,2)
  316. if pop_option == 1:
  317. pop_option = True
  318. else:
  319. pop_option = False
  320. move_validity = check_move(game,player_move,pop_option)
  321. if not move_validity:
  322. continue
  323. else:
  324. apply_move(game,player_move,pop_option)
  325. break
  326. return player_move,pop_option
  327. if level == 2:
  328. output = computer_check(game)
  329. return output
  330.  
  331.  
  332.  
  333. def menu():
  334. print("Connect 4\n\nby Koh Si Yan, Gerald Ong, and Chen Zhixing")
  335. while True:
  336. new_game = (input("1. Start new game\n2. Quit\n\n"))
  337. if new_game == "2":
  338. print("Thank you for playing. Goodbye")
  339. return
  340. if new_game != "2" and new_game != "1":
  341. print("Please select 1 or 2!")
  342. continue
  343. else:
  344. break
  345. while True:
  346. try:
  347. game.rows = input("How many rows in the game? ") #user input for no. of rows
  348. int(game.rows)
  349. if int(game.rows) < 2: #min no. of rows is 2
  350. print("Please enter a valid number (2 or more)")
  351. else:
  352. game.rows = int(game.rows)
  353. break
  354. except ValueError: #if input isn't an integer, ask for a new input
  355. print("Please pick a valid number!")
  356. while True:
  357. try:
  358. game.cols = input("How many columns in the game? ") #user input for no. of columns
  359. int(game.cols)
  360. if int(game.cols) < 2: #min no. of columns is 2
  361. print("Please enter a valid number (2 or more)")
  362. else:
  363. game.cols = int(game.cols)
  364. break
  365. except ValueError: #if input isn't an integer, ask for a new input
  366. print("Please pick a valid number!")
  367.  
  368. while True:
  369. try:
  370. game.wins = input("How many disks in a row to win? ") #user input for no. of disks to win
  371. int(game.wins)
  372. if int(game.wins) > int(game.rows) or int(game.wins) > int(game.cols) or int(game.wins) < 2:
  373. #no. of disks in a row to win has to be within the range of columns and rows
  374. print("Pick a positive number > 1 and <= number of columns and rows")
  375. else:
  376. game.wins = int(game.wins)
  377. break
  378. except ValueError:
  379. print("Please pick a valid number!")
  380. game.mat = np.zeros((game.rows,game.cols)) #initialising the game board
  381. game.turn = 1 #set initial turn to be 1
  382. while True:
  383. opponent = input("Pick your opponent\n1. Computer(1P)\n2. Human(2P)\n")
  384. #choosing a human or compuoter opponent
  385. if opponent == "1":
  386. while True:
  387. turn_order = input("Who should go first?\n1. Player\n2. Computer\n3. Random\n")
  388. #choosing turn order for computer opponent
  389. if turn_order == "3":
  390. turn_order = str(random.randint(1,2))
  391. #for random turn order, random integer that leads to either human or computer starting first is generated
  392. if turn_order == "1":
  393. print("Human is Player 1 and goes first")
  394. break
  395. elif turn_order == "2":
  396. print("Computer is Player 1 and goes first")
  397. break
  398. else:
  399. print("Please pick 1, 2, or 3!")
  400. continue
  401.  
  402. while True:
  403. try:
  404. computer_level = input("What level should the computer be? 1 or 2: ")
  405. #comptuer difficulty
  406. int(computer_level)
  407. if int(computer_level) != 1 and int(computer_level) != 2:
  408. print("Invalid input; please try again!")
  409. else:
  410. computer_level = int(computer_level)
  411. break
  412. #limit integer values depending on levels
  413. except ValueError:
  414. print("Invalid input; please try again")
  415. if turn_order == "1":
  416. #human player goes first
  417. display_board(game)
  418. while True:
  419. human_move(game)
  420. check_victory(game)
  421. display_board(game)
  422. if check_victory(game) != 0:
  423. break
  424. else:
  425. print("\nComputer makes its move!")
  426. computer_move(game,computer_level)
  427. check_victory(game)
  428. display_board(game)
  429.  
  430. if check_victory(game) != 0:
  431. break
  432. else:
  433. continue
  434. if turn_order == "2":
  435. #computer goes first so order is reversed
  436. while True:
  437. computer_move(game,computer_level)
  438. check_victory(game)
  439. display_board(game)
  440. if check_victory(game) != 0:
  441. break
  442. else:
  443. game.turn
  444. human_move(game)
  445. check_victory(game)
  446. display_board(game)
  447. if check_victory(game) != 0:
  448. break
  449. else:
  450. print("\nComputer makes its move!")
  451. continue
  452. break
  453. break
  454. elif opponent == "2":
  455. #2 human player game
  456. display_board(game)
  457. while True:
  458. human_move(game)
  459. check_victory(game)
  460. display_board(game)
  461. if check_victory(game) == 0:
  462. continue
  463. else:
  464. break
  465. break
  466. else:
  467. print("Please pick 1 or 2!")
  468. continue
  469. if check_victory(game) == 1 or check_victory(game) == 2: #condition for someone winning
  470. print("Player",check_victory(game),"wins!")
  471. if check_victory(game) == 3: #condition for draw
  472. print("All slots filled. It's a draw!")
  473. while True:
  474. play_again = input("Would you like to play again?\n1. Yes please!\n2. No, I'd like to quit\n")
  475. if play_again == "1":
  476. menu()
  477. if play_again != "1" and play_again != "2":
  478. print("Not an option! Please try again!")
  479. continue
  480. if play_again == "2":
  481. print("Okay; goodbye!")
  482. return
  483.  
  484.  
  485. menu()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement