python实现简单五子棋游戏


Posted in Python onJune 18, 2019

本文实例为大家分享了python实现简单五子棋游戏的具体代码,供大家参考,具体内容如下

python实现简单五子棋游戏

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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python常用模块介绍
Nov 21 Python
查看Python安装路径以及安装包路径小技巧
Apr 28 Python
Python读写unicode文件的方法
Jul 10 Python
Python爬虫框架Scrapy常用命令总结
Jul 26 Python
对TensorFlow的assign赋值用法详解
Jul 30 Python
使用python绘制3维正态分布图的方法
Dec 29 Python
解决python3中的requests解析中文页面出现乱码问题
Apr 19 Python
python目标检测给图画框,bbox画到图上并保存案例
Mar 10 Python
Pandas之read_csv()读取文件跳过报错行的解决
Apr 21 Python
3种适用于Python的疯狂秘密武器及原因解析
Apr 29 Python
Python select及selectors模块概念用法详解
Jun 22 Python
python生成xml时规定dtd实例方法
Sep 21 Python
Python基础学习之函数方法实例详解
Jun 18 #Python
pyqt5 实现在别的窗口弹出进度条
Jun 18 #Python
Python弹出输入框并获取输入值的实例
Jun 18 #Python
python使用tkinter库实现五子棋游戏
Jun 18 #Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
Jun 18 #Python
python 弹窗提示警告框MessageBox的实例
Jun 18 #Python
python实现五子棋小程序
Jun 18 #Python
You might like
php带密码功能并下载远程文件保存本地指定目录 修改加强版
2010/05/16 PHP
PHP __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
CI框架装载器Loader.php源码分析
2014/11/04 PHP
PHP实现支持加盐的图片加密解密
2016/09/09 PHP
PHP实现的多维数组排序算法分析
2018/02/10 PHP
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
Javascript面向对象扩展库代码分享
2012/03/27 Javascript
JavaScript如何实现对数字保留两位小数一位自动补零
2015/12/18 Javascript
JS中使用DOM来控制HTML元素
2016/07/31 Javascript
简单实现js浮动框
2016/12/13 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
关于Sequelize连接查询时inlude中model和association的区别详解
2017/02/27 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
jquery.picsign图片标注组件实例详解
2018/02/02 jQuery
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
vue 使用axios 数据请求第三方插件的使用教程详解
2019/07/05 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
[11:33]DAC2018 4.5SOLO赛决赛 MidOne vs Paparazi第二场
2018/04/06 DOTA
Windows下使Python2.x版本的解释器与3.x共存的方法
2015/10/25 Python
python linecache 处理固定格式文本数据的方法
2019/01/08 Python
Python中一些深不见底的“坑”
2019/06/12 Python
Python中字典与恒等运算符的用法分析
2019/08/22 Python
如何Tkinter模块编写Python图形界面
2020/10/14 Python
HTML 5 input placeholder 属性如何完美兼任ie
2014/05/12 HTML / CSS
CK美国官网:Calvin Klein
2016/08/26 全球购物
应聘编辑职位自荐信范文
2014/01/05 职场文书
作弊检讨书1000字
2014/02/01 职场文书
工程力学专业自荐信范文
2014/03/17 职场文书
小学生家长寄语
2014/04/02 职场文书
领导班子三严三实对照检查材料
2014/09/25 职场文书
2015年车间安全管理工作总结
2015/05/13 职场文书
手术室消毒隔离制度
2015/08/05 职场文书
未来,这5大方向都很适合创业
2019/07/22 职场文书
小学四年级作文之最感动的一件事
2019/11/01 职场文书
Java 中的 Unsafe 魔法类的作用大全
2021/06/26 Java/Android
用JS创建一个录屏功能
2021/11/11 Javascript