当前位置:   article > 正文

Pygame——AI重力四子棋_重力四子棋ai平台

重力四子棋ai平台

突然奇想,什么时候可以自己实现一个机器对战的小游戏,但一直不敢去尝试,直到偶尔发现了重力四子棋的规则,有限的空间棋盘正好可以拿来练手。

有关下棋AI的算法,说来说去也就那么几种,随机蒙特卡罗方法、UCT信心上限树、博弈论(Alpha−Beta剪枝)...

这个小游戏我时间更多的花在ui界面和游戏逻辑的实现,可以切换先后手顺序,添加了重置游戏和暂停游戏的规则,可落子节点辅助提示,以及对应的文字提示信息。

算法采用了无忧化的蒙特卡罗方法,模拟当前棋盘状态可落子节点扩展的胜利可能性,模拟的次数越多,时间自然也就越久,但智能度相应着也会提高。

源代码:https://download.csdn.net/download/qq_40204582/11212878

代码开源了,如果有复制过去的朋友,可以顺手点个赞吗^_^

  1. import pygame, sys
  2. from pygame.locals import *
  3. import time
  4. import random
  5. import copy
  6. # game parameters
  7. pygame.init()
  8. win_width, win_height = 930, 700
  9. displaysurf = pygame.display.set_mode((win_width, win_height), 0, 32)
  10. pygame.display.set_caption('Connect_4')
  11. # color parameters
  12. backgroundcolor_chess = (244, 171, 102)
  13. color_white = (255, 255, 255)
  14. color_black = (0, 0, 0)
  15. color_tip_white = (225, 225, 225)
  16. color_tip_black = (25, 25, 25)
  17. color_green = (0, 255, 0)
  18. # chess parameters
  19. chess_grid_row, chess_grid_col = 6, 8
  20. chess_list = []
  21. for i in range(chess_grid_row):
  22. new_line = [0 for j in range(chess_grid_col)]
  23. chess_list.append(new_line)
  24. player = True
  25. play_flag = False
  26. # draw chessboard
  27. def draw_chessboard():
  28. displaysurf.fill(color_white)
  29. fontobj = pygame.font.SysFont('SimHei',70)
  30. text = fontobj.render("重力四子棋", True, color_black, color_white)
  31. textrect = text.get_rect()
  32. textrect.center = (430, 70)
  33. displaysurf.blit(text, textrect)
  34. pygame.draw.rect(displaysurf, backgroundcolor_chess, (50, 170, 640, 480))
  35. for pix_row in range(7):
  36. pygame.draw.line(displaysurf, color_black, (50, 170 + pix_row * 80), (690, 170 + pix_row * 80))
  37. for pix_col in range(9):
  38. pygame.draw.line(displaysurf, color_black, (50 + pix_col * 80, 170), (50 + pix_col * 80, 650))
  39. def draw_tip_chess(mousex, mousey, type):
  40. for row in range(chess_grid_row):
  41. for col in range(chess_grid_col):
  42. if chess_list[row][col] in [3, 4]:
  43. chess_list[row][col] = 0
  44. col = int((mousex - 50) / 80)
  45. row = int((mousey - 170) / 80)
  46. if row == chess_grid_row:
  47. row -= 1
  48. if col == chess_grid_col:
  49. col -= 1
  50. if row < chess_grid_row - 1:
  51. if chess_list[row + 1][col] == 0:
  52. return
  53. if chess_list[row][col] == 0:
  54. chess_list[row][col] = type
  55. def clear_tip_chess():
  56. for row in range(chess_grid_row):
  57. for col in range(chess_grid_col):
  58. if chess_list[row][col] in [3, 4]:
  59. chess_list[row][col] = 0
  60. def draw_check_chess(mousex, mousey, type):
  61. for row in range(chess_grid_row):
  62. for col in range(chess_grid_col):
  63. if chess_list[row][col] in [3, 4]:
  64. chess_list[row][col] = 0
  65. col = int((mousex - 50) / 80)
  66. row = int((mousey - 170) / 80)
  67. if row == chess_grid_row:
  68. row -= 1
  69. if col == chess_grid_col:
  70. col -= 1
  71. if row < chess_grid_row - 1:
  72. if chess_list[row + 1][col] == 0:
  73. return
  74. if chess_list[row][col] in [1, 2]:
  75. return False
  76. else:
  77. chess_list[row][col] = type
  78. return True
  79. def draw_chess():
  80. for row in range(chess_grid_row):
  81. for col in range(chess_grid_col):
  82. if chess_list[row][col] == 0:
  83. pygame.draw.circle(displaysurf, backgroundcolor_chess, (90 + col * 80, 210 + row * 80), 38)
  84. elif chess_list[row][col] == 1:
  85. pygame.draw.circle(displaysurf, color_black, (90 + col * 80, 210 + row * 80), 38)
  86. elif chess_list[row][col] == 2:
  87. pygame.draw.circle(displaysurf, color_white, (90 + col * 80, 210 + row * 80), 38)
  88. elif chess_list[row][col] == 3:
  89. pygame.draw.circle(displaysurf, color_tip_black, (90 + col * 80, 210 + row * 80), 38)
  90. elif chess_list[row][col] == 4:
  91. pygame.draw.circle(displaysurf, color_tip_white, (90 + col * 80, 210 + row * 80), 38)
  92. def is_win(temp_chess_list):
  93. not_null_sum = 0
  94. for row in range(chess_grid_row):
  95. for col in range(chess_grid_col):
  96. if temp_chess_list[row][col] in [3, 4]:
  97. temp_chess_list[row][col] = 0
  98. if temp_chess_list[row][col] != 0:
  99. not_null_sum += 1
  100. # horizontal
  101. if col < chess_grid_col - 3:
  102. if temp_chess_list[row][col] == temp_chess_list[row][col + 1] == temp_chess_list[row][col + 2] == \
  103. temp_chess_list[row][col + 3] and temp_chess_list[row][col] != 0:
  104. return temp_chess_list[row][col]
  105. # vertical
  106. if row < chess_grid_row - 3:
  107. if temp_chess_list[row][col] == temp_chess_list[row + 1][col] == temp_chess_list[row + 2][col] == \
  108. temp_chess_list[row + 3][col] and temp_chess_list[row][col] != 0:
  109. return temp_chess_list[row][col]
  110. # right slant
  111. if col < chess_grid_col - 3 and row < chess_grid_row - 3:
  112. if temp_chess_list[row][col] == temp_chess_list[row + 1][col + 1] == temp_chess_list[row + 2][
  113. col + 2] == \
  114. temp_chess_list[row + 3][col + 3] and temp_chess_list[row][col] != 0:
  115. return temp_chess_list[row][col]
  116. # left slant
  117. if col >= 3 and row < chess_grid_row - 3:
  118. if temp_chess_list[row][col] == temp_chess_list[row + 1][col - 1] == temp_chess_list[row + 2][
  119. col - 2] == \
  120. temp_chess_list[row + 3][col - 3] and temp_chess_list[row][col] != 0:
  121. return temp_chess_list[row][col]
  122. if not_null_sum == chess_grid_row*chess_grid_col:
  123. return 3
  124. return 0
  125. def AI(chess_list, type):
  126. node_list = []
  127. chess_null_sum = 0
  128. for col in range(chess_grid_col):
  129. for row in range(chess_grid_row):
  130. if chess_list[row][col] == 0:
  131. chess_null_sum += 1
  132. if row == chess_grid_row -1:
  133. temp_chess_list = copy.deepcopy(chess_list)
  134. temp_chess_list[row][col] = type
  135. node_list.append([row, col])
  136. flag = is_win(temp_chess_list)
  137. if flag != 0:
  138. chess_list[row][col] = type
  139. return row, col
  140. elif chess_list[row+1][col] != 0:
  141. temp_chess_list = copy.deepcopy(chess_list)
  142. temp_chess_list[row][col] = type
  143. node_list.append([row, col])
  144. flag = is_win(temp_chess_list)
  145. if flag != 0:
  146. chess_list[row][col] = type
  147. return row, col
  148. print(node_list)
  149. range_sum = 500 + int((chess_grid_row*chess_grid_col-chess_null_sum)/(chess_grid_row*chess_grid_col)*100)
  150. print(range_sum)
  151. win_list = [0 for j in range(chess_grid_col)]
  152. tip_list = [0 for j in range(chess_grid_col)]
  153. start = time.clock()
  154. for i in range(len(node_list)):
  155. for j in range(100):
  156. temp_type = type
  157. temp_chess_list = copy.deepcopy(chess_list)
  158. temp_node_list = copy.deepcopy(node_list)
  159. temp_chess_list[temp_node_list[i][0]][temp_node_list[i][1]] = temp_type
  160. flag_win = is_win(temp_chess_list)
  161. if flag_win != 0:
  162. if flag_win == type:
  163. win_list[i] += 1
  164. continue
  165. elif flag_win == 3:
  166. tip_list[i] += 1
  167. if temp_node_list[i][0] == 0:
  168. del temp_node_list[i]
  169. else:
  170. temp_node_list[i][0] -= 1
  171. while True:
  172. if temp_type == 1:
  173. temp_type = 2
  174. else:
  175. temp_type = 1
  176. try:
  177. temp_index = random.randint(0, len(temp_node_list)-1)
  178. except:
  179. break
  180. temp_chess_list[temp_node_list[temp_index][0]][temp_node_list[temp_index][1]] = temp_type
  181. flag_win = is_win(temp_chess_list)
  182. if flag_win != 0:
  183. if flag_win == type:
  184. win_list[i] += 1
  185. elif flag_win == 3:
  186. tip_list[i] += 1
  187. break
  188. if temp_node_list[temp_index][0] == 0:
  189. del temp_node_list[temp_index]
  190. else:
  191. temp_node_list[temp_index][0] -= 1
  192. end = time.clock()
  193. print(end - start)
  194. if max(win_list) > range_sum*0.1:
  195. print(win_list)
  196. check = win_list.index(max(win_list))
  197. print(node_list)
  198. print(check)
  199. else:
  200. check = tip_list.index(max(tip_list))
  201. print("选择平局")
  202. chess_list[node_list[check][0]][node_list[check][1]] = type
  203. def draw_player(player):
  204. fontobj = pygame.font.SysFont('SimHei', 25)
  205. if player:
  206. text = fontobj.render("先手: 电脑 棋色: 黑色", True, color_black, color_white)
  207. else:
  208. text = fontobj.render("先手: 玩家 棋色: 黑色", True, color_black, color_white)
  209. textrect = text.get_rect()
  210. textrect.center = (260, 140)
  211. displaysurf.blit(text, textrect)
  212. def button():
  213. pygame.draw.rect(displaysurf, color_green, (730, 200, 160, 80))
  214. fontobj1 = pygame.font.SysFont('SimHei', 30)
  215. text1 = fontobj1.render("切换先手", True, color_white, color_green)
  216. textrect1 = text1.get_rect()
  217. textrect1.center = (810, 240)
  218. displaysurf.blit(text1, textrect1)
  219. pygame.draw.rect(displaysurf, color_green, (730, 360, 160, 80))
  220. fontobj2 = pygame.font.SysFont('SimHei', 30)
  221. if play_flag == False:
  222. text2 = fontobj2.render("开始游戏", True, color_white, color_green)
  223. else:
  224. text2 = fontobj2.render("暂停游戏", True, color_white, color_green)
  225. textrect2 = text2.get_rect()
  226. textrect2.center = (810, 400)
  227. displaysurf.blit(text2, textrect2)
  228. pygame.draw.rect(displaysurf, color_green, (730, 520, 160, 80))
  229. fontobj3 = pygame.font.SysFont('SimHei', 30)
  230. text3 = fontobj3.render("重置游戏", True, color_white, color_green)
  231. textrect3 = text3.get_rect()
  232. textrect3.center = (810, 560)
  233. displaysurf.blit(text3, textrect3)
  234. def play_type():
  235. fontobj = pygame.font.SysFont('SimHei', 25)
  236. if play_flag == False:
  237. win_flag = is_win(chess_list)
  238. pygame.draw.rect(displaysurf, color_white, (400, 120, 300, 45))
  239. if win_flag == 0:
  240. text = fontobj.render("状态: 未开始游戏", True, color_black, color_white)
  241. elif win_flag == 1:
  242. if player:
  243. text = fontobj.render("状态: 电脑胜利", True, color_black, color_white)
  244. else:
  245. text = fontobj.render("状态: 玩家胜利", True, color_black, color_white)
  246. elif win_flag == 2:
  247. if player:
  248. text = fontobj.render("状态: 玩家胜利", True, color_black, color_white)
  249. else:
  250. text = fontobj.render("状态: 电脑胜利", True, color_black, color_white)
  251. elif win_flag == 3:
  252. text = fontobj.render("状态: 平局", True, color_black, color_white)
  253. else:
  254. null_sum = 0
  255. for row in range(chess_grid_row):
  256. for col in range(chess_grid_col):
  257. if chess_list[row][col] in [0, 3, 4]:
  258. null_sum += 1
  259. if player:
  260. if (chess_grid_row*chess_grid_col-null_sum) % 2 == 0:
  261. text = fontobj.render("状态: 请电脑落子", True, color_black, color_white)
  262. else:
  263. text = fontobj.render("状态: 请玩家落子", True, color_black, color_white)
  264. else:
  265. if (chess_grid_row*chess_grid_col-null_sum) % 2 == 1:
  266. text = fontobj.render("状态: 请电脑落子", True, color_black, color_white)
  267. else:
  268. text = fontobj.render("状态: 请玩家落子", True, color_black, color_white)
  269. textrect = text.get_rect()
  270. textrect.center = (570, 140)
  271. displaysurf.blit(text, textrect)
  272. def new_play():
  273. global player, play_flag
  274. draw_chessboard()
  275. # AI(chess_list, 1)
  276. # main game loop
  277. while True:
  278. for event in pygame.event.get():
  279. # close game
  280. if event.type == QUIT:
  281. pygame.quit()
  282. sys.exit()
  283. elif event.type == MOUSEMOTION:
  284. mousex, mousey = event.pos
  285. if play_flag:
  286. if mousex > 50 and mousex < 690 and mousey > 170 and mousey < 730:
  287. if player:
  288. draw_tip_chess(mousex, mousey, 4)
  289. else:
  290. draw_tip_chess(mousex, mousey, 3)
  291. else:
  292. clear_tip_chess()
  293. elif event.type == MOUSEBUTTONUP:
  294. mousex, mousey = event.pos
  295. if play_flag:
  296. if mousex > 50 and mousex < 690 and mousey > 170 and mousey < 730:
  297. if player:
  298. flag = draw_check_chess(mousex, mousey, 2)
  299. draw_chess()
  300. pygame.display.update()
  301. if flag:
  302. if is_win(chess_list) != 0:
  303. play_flag = False
  304. play_type()
  305. pygame.display.update()
  306. if play_flag:
  307. AI(chess_list, 1)
  308. if is_win(chess_list) != 0:
  309. play_flag = False
  310. else:
  311. flag = draw_check_chess(mousex, mousey, 1)
  312. draw_chess()
  313. pygame.display.update()
  314. if flag:
  315. if is_win(chess_list) != 0:
  316. play_flag = False
  317. play_type()
  318. pygame.display.update()
  319. if play_flag:
  320. AI(chess_list, 2)
  321. if is_win(chess_list) != 0:
  322. play_flag = False
  323. else:
  324. if mousex > 730 and mousex < 890 and mousey > 200 and mousey < 280:
  325. if is_win(chess_list) == 0:
  326. if player:
  327. player = False
  328. else:
  329. player = True
  330. draw_player(player)
  331. if mousex > 730 and mousex < 890 and mousey > 360 and mousey < 440:
  332. if play_flag:
  333. play_flag = False
  334. else:
  335. if is_win(chess_list) == 0:
  336. play_flag = True
  337. play_type()
  338. button()
  339. pygame.display.update()
  340. if player and sum(chess_list[-1]) == 0:
  341. AI(chess_list, 1)
  342. elif mousex > 730 and mousex < 890 and mousey > 520 and mousey < 600:
  343. play_flag = False
  344. for row in range(chess_grid_row):
  345. for col in range(chess_grid_col):
  346. chess_list[row][col] = 0
  347. draw_player(player)
  348. button()
  349. draw_chess()
  350. play_type()
  351. pygame.display.update()
  352. def main():
  353. new_play()
  354. main()

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/353629
推荐阅读
  

闽ICP备14008679号