亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python實現簡單五子棋游戲

系統 1585 0

本文實例為大家分享了python實現簡單五子棋游戲的具體代碼,供大家參考,具體內容如下

python實現簡單五子棋游戲_第1張圖片

            
from graphics import *
from math import *
import numpy as np
 
 
def ai():
  """
  AI計算落子位置
  """
  maxmin(True, DEPTH, -99999999, 99999999)
  return next_point[0], next_point[1]
 
 
def maxmin(is_ai, depth, alpha, beta):
  """
  負值極大算法搜索 alpha + beta剪枝
  """
  # 游戲是否結束 | | 探索的遞歸深度是否到邊界
  if game_win(list1) or game_win(list2) or depth == 0:
    return evaluation(is_ai)
 
  blank_list = list(set(list_all).difference(set(list3)))
  order(blank_list) # 搜索順序排序 提高剪枝效率
  # 遍歷每一個候選步
  for next_step in blank_list[0:60]:
 
    # 如果要評估的位置沒有相鄰的子, 則不去評估 減少計算
    if not has_neightnor(next_step):
      continue
 
    if is_ai:
      list1.append(next_step)
    else:
      list2.append(next_step)
    list3.append(next_step)
 
    value = -maxmin(not is_ai, depth - 1, -beta, -alpha)
    if is_ai:
      list1.remove(next_step)
    else:
      list2.remove(next_step)
    list3.remove(next_step)
 
    if value > alpha:
      if depth == DEPTH:
        next_point[0] = next_step[0]
        next_point[1] = next_step[1]
      # alpha + beta剪枝點
      if value >= beta:
        return beta
      alpha = value
  return alpha
 
 
def order(blank_list):
  """
  離最后落子的鄰居位置最有可能是最優點
  計算最后落子點的8個方向鄰居節點
  若未落子,則插入到blank列表的最前端
  :param blank_list: 未落子節點集合
  :return: blank_list
  """
  last_pt = list3[-1]
  # for item in blank_list:
  for i in range(-1, 2):
    for j in range(-1, 2):
      if i == 0 and j == 0:
        continue
      if (last_pt[0] + i, last_pt[1] + j) in blank_list:
        blank_list.remove((last_pt[0] + i, last_pt[1] + j))
        blank_list.insert(0, (last_pt[0] + i, last_pt[1] + j))
 
 
def has_neightnor(pt):
  """
  判斷是否有鄰居節點
  :param pt: 待評測節點
  :return:
  """
  for i in range(-1, 2):
    for j in range(-1, 2):
      if i == 0 and j == 0:
        continue
      if (pt[0] + i, pt[1] + j) in list3:
        return True
  return False
 
 
def evaluation(is_ai):
  """
  評估函數
  """
  if is_ai:
    my_list = list1
    enemy_list = list2
  else:
    my_list = list2
    enemy_list = list1
  # 算自己的得分
  score_all_arr = [] # 得分形狀的位置 用于計算如果有相交 得分翻倍
  my_score = 0
  for pt in my_list:
    m = pt[0]
    n = pt[1]
    my_score += cal_score(m, n, 0, 1, enemy_list, my_list, score_all_arr)
    my_score += cal_score(m, n, 1, 0, enemy_list, my_list, score_all_arr)
    my_score += cal_score(m, n, 1, 1, enemy_list, my_list, score_all_arr)
    my_score += cal_score(m, n, -1, 1, enemy_list, my_list, score_all_arr)
  # 算敵人的得分, 并減去
  score_all_arr_enemy = []
  enemy_score = 0
  for pt in enemy_list:
    m = pt[0]
    n = pt[1]
    enemy_score += cal_score(m, n, 0, 1, my_list, enemy_list, score_all_arr_enemy)
    enemy_score += cal_score(m, n, 1, 0, my_list, enemy_list, score_all_arr_enemy)
    enemy_score += cal_score(m, n, 1, 1, my_list, enemy_list, score_all_arr_enemy)
    enemy_score += cal_score(m, n, -1, 1, my_list, enemy_list, score_all_arr_enemy)
 
  total_score = my_score - enemy_score * 0.1
  return total_score
 
 
def cal_score(m, n, x_decrict, y_derice, enemy_list, my_list, score_all_arr):
  """
  每個方向上的分值計算
  :param m:
  :param n:
  :param x_decrict:
  :param y_derice:
  :param enemy_list:
  :param my_list:
  :param score_all_arr:
  :return:
  """
  add_score = 0 # 加分項
  # 在一個方向上, 只取最大的得分項
  max_score_shape = (0, None)
 
  # 如果此方向上,該點已經有得分形狀,不重復計算
  for item in score_all_arr:
    for pt in item[1]:
      if m == pt[0] and n == pt[1] and x_decrict == item[2][0] and y_derice == item[2][1]:
        return 0
 
  # 在落子點 左右方向上循環查找得分形狀
  for offset in range(-5, 1):
    # offset = -2
    pos = []
    for i in range(0, 6):
      if (m + (i + offset) * x_decrict, n + (i + offset) * y_derice) in enemy_list:
        pos.append(2)
      elif (m + (i + offset) * x_decrict, n + (i + offset) * y_derice) in my_list:
        pos.append(1)
      else:
        pos.append(0)
    tmp_shap5 = (pos[0], pos[1], pos[2], pos[3], pos[4])
    tmp_shap6 = (pos[0], pos[1], pos[2], pos[3], pos[4], pos[5])
 
    for (score, shape) in shape_score:
      if tmp_shap5 == shape or tmp_shap6 == shape:
        if score > max_score_shape[0]:
          max_score_shape = (score, ((m + (0 + offset) * x_decrict, n + (0 + offset) * y_derice),
                        (m + (1 + offset) * x_decrict, n + (1 + offset) * y_derice),
                        (m + (2 + offset) * x_decrict, n + (2 + offset) * y_derice),
                        (m + (3 + offset) * x_decrict, n + (3 + offset) * y_derice),
                        (m + (4 + offset) * x_decrict, n + (4 + offset) * y_derice)),
                    (x_decrict, y_derice))
 
  # 計算兩個形狀相交, 如兩個3活 相交, 得分增加 一個子的除外
  if max_score_shape[1] is not None:
    for item in score_all_arr:
      for pt1 in item[1]:
        for pt2 in max_score_shape[1]:
          if pt1 == pt2 and max_score_shape[0] > 10 and item[0] > 10:
            add_score += item[0] + max_score_shape[0]
 
    score_all_arr.append(max_score_shape)
 
  return add_score + max_score_shape[0]
 
 
def game_win(list):
  """
  勝利條件判斷
  """
  # for m in range(COLUMN):
  #   for n in range(ROW):
  #     if n < ROW - 4 and (m, n) in list and (m, n + 1) in list and (m, n + 2) in list and (
  #         m, n + 3) in list and (m, n + 4) in list:
  #       return True
  #     elif m < ROW - 4 and (m, n) in list and (m + 1, n) in list and (m + 2, n) in list and (
  #         m + 3, n) in list and (m + 4, n) in list:
  #       return True
  #     elif m < ROW - 4 and n < ROW - 4 and (m, n) in list and (m + 1, n + 1) in list and (
  #         m + 2, n + 2) in list and (m + 3, n + 3) in list and (m + 4, n + 4) in list:
  #       return True
  #     elif m < ROW - 4 and n > 3 and (m, n) in list and (m + 1, n - 1) in list and (
  #         m + 2, n - 2) in list and (m + 3, n - 3) in list and (m + 4, n - 4) in list:
  #       return True
  return False
 
 
def draw_window():
  """
  繪制棋盤
  """
  # 繪制畫板
  win = GraphWin("五子棋", GRAPH_HEIGHT, GRAPH_WIDTH)
  win.setBackground("gray")
  # 繪制列
  i1 = 0
  while i1 <= GRID_WIDTH * COLUMN:
    i1 = i1 + GRID_WIDTH
    l = Line(Point(i1, GRID_WIDTH), Point(i1, GRID_WIDTH * COLUMN))
    l.draw(win)
  # 繪制行
  i2 = 0
  while i2 <= GRID_WIDTH * ROW:
    i2 = i2 + GRID_WIDTH
    l = Line(Point(GRID_WIDTH, i2), Point(GRID_WIDTH * ROW, i2))
    l.draw(win)
  return win
 
 
def main():
  """
  程序循環
  :return:
  """
  mode = int(input("先手 AI先手 ? 1 0 \n"))
  # 繪制棋盤
  win = draw_window()
  # 添加棋盤所有點
  for i in range(COLUMN + 1):
    for j in range(ROW + 1):
      list_all.append((i, j))
  # 循環條件
  g = 0
  change = 0
  # 開始循環
  while g == 0:
    # AI
    if change % 2 == mode:
      # AI先手 走天元
      if change == 0:
        pos = (6, 6)
      else:
        pos = ai()
      # 添加落子
      list1.append(pos)
      list3.append(pos)
      # 繪制白棋
      piece = Circle(Point(GRID_WIDTH * (pos[0]), GRID_WIDTH * (pos[1])), 12)
      piece.setFill('white')
      piece.draw(win)
      # AI勝利
      if game_win(list1):
        message = Text(Point(GRAPH_WIDTH / 2, GRID_WIDTH / 2), "AI獲勝")
        message.draw(win)
        g = 1
      change = change + 1
 
    # User
    else:
      p2 = win.getMouse()
      x = round((p2.getX()) / GRID_WIDTH)
      y = round((p2.getY()) / GRID_WIDTH)
 
      # 若點未被選取過
      if not (x, y) in list3:
        # 添加落子
        list2.append((x, y))
        list3.append((x, y))
        # 繪制黑棋
        piece = Circle(Point(GRID_WIDTH * x, GRID_WIDTH * y), 12)
        piece.setFill('black')
        piece.draw(win)
        # 勝利
        if game_win(list2):
          message = Text(Point(GRAPH_WIDTH / 2, GRID_WIDTH / 2), "人類勝利")
          message.draw(win)
          g = 1
        change = change + 1
 
  message = Text(Point(GRAPH_WIDTH / 2 + 100, GRID_WIDTH / 2), "游戲結束")
  message.draw(win)
  win.getMouse()
  win.close()
 
 
if __name__ == '__main__':
  GRID_WIDTH = 40
  COLUMN = 11
  ROW = 11
  GRAPH_WIDTH = GRID_WIDTH * (ROW + 1)
  GRAPH_HEIGHT = GRID_WIDTH * (COLUMN + 1)
 
  list1 = [] # AI
  list2 = [] # human
  list3 = [] # all
  list_all = [] # 整個棋盤的點
  next_point = [0, 0] # AI下一步最應該下的位置
 
  mode=int(input("請選擇: 快不準 或 慢卻準 ? 1 : 0 \n"))
  if mode==1:
    DEPTH=1
  elif mode==0:
    DEPTH=3
  else:
    DEPTH=3
 
  shape_score = [(50, (0, 1, 1, 0, 0)),
          (50, (0, 0, 1, 1, 0)),
          (200, (1, 1, 0, 1, 0)),
          (500, (0, 0, 1, 1, 1)),
          (500, (1, 1, 1, 0, 0)),
          (5000, (0, 1, 1, 1, 0)),
          (5000, (0, 1, 0, 1, 1, 0)),
          (5000, (0, 1, 1, 0, 1, 0)),
          (5000, (1, 1, 1, 0, 1)),
          (5000, (1, 1, 0, 1, 1)),
          (5000, (1, 0, 1, 1, 1)),
          (5000, (1, 1, 1, 1, 0)),
          (5000, (0, 1, 1, 1, 1)),
          (50000, (0, 1, 1, 1, 1, 0)),
          (99999999, (1, 1, 1, 1, 1))]
  main()
          

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 中文字幕日本不卡 | 99久热re在线精品视频 | 欧美精品久久久久久久免费观看 | 91午夜精品亚洲一区二区三区 | 中文字幕伦理聚合第一页 | 免费网站看v片在线成人国产系列 | 亚洲欧美综合乱码精品成人网 | 99爱在线精品视频网站 | 成年人性生活免费视频 | 中文字幕一区二区三区在线观看 | 亚洲一二三区在线观看 | 91精品国产综合久久婷婷 | 欧美激情视频一区 | 九九热视频在线观看 | 欧美成人在线免费视频 | 手机在线看片国产日韩生活片 | 草莓视频在线观看精品最新 | 99热国内精品| 久久久久免费精品视频 | 日韩亚洲一区中文字幕在线 | 精品哟哟国产在线观看 | 91视频青青草 | 三级天堂| 95视频在线观看在线分类h片 | 麻豆国产原创 | 欧美成人香蕉在线观看 | 国产精品视频一区二区三区不卡 | 日本在线一区二区 | 尻逼片| 午夜视频在线网站 | 国产欧美日韩精品专区 | 99热久久久久久久免费观看 | 欧美三级成人理伦 | 日本在线精品视频 | 美国一级毛片免费看成人 | 国产精品视频第一区二区 | 777奇米影视视频在线播放 | 天天做天天玩天天爽天天 | 亚洲国产综合网 | 国产精彩视频在线 | 精品免费视在线视频观看 |