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

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

(0)

相关推荐

  • python实现五子棋小程序

    本文实例为大家分享了python实现五子棋小程序的具体代码,供大家参考,具体内容如下 一.结合书上例子,分三段编写: wuziqi.py #coding:utf-8 from win_notwin import * from show_qipan import * maxx=10 #10行10列 maxy=10 qipan=[[0,0,0,0,1,0,0,2,0,0],[0,1,2,1,1,0,2,0,0,0],[0,0,0,0,1,1,0,2,0,0],[0,0,0,0,2,0,0,1,0,0

  • python实现五子棋游戏

    本文实例为大家分享了python实现五子棋游戏的具体代码,供大家参考,具体内容如下 话不多说,直接上代码: 全部工程文件,在GitHub:五子棋 效果预览: #!/usr/bin/env python3 #-*- coding:utf-8 -*- import pygame from pygame.locals import * from sys import exit import numpy background_image = 'qipan.png' white_image = 'whit

  • python使用tkinter库实现五子棋游戏

    本文实例为大家分享了python实现五子棋游戏的具体代码,供大家参考,具体内容如下 一.运行截图: 二.代码 # 用数组定义一个棋盘,棋盘大小为 15×15 # 数组索引代表位置, # 元素值代表该位置的状态:0代表没有棋子,1代表有黑棋,-1代表有白棋. from tkinter import * from tkinter.messagebox import * class Chess(object): def __init__(self): ############# # param # #

  • python实现五子棋小游戏

    本文实例为大家分享了python实现五子棋小游戏的具体代码,供大家参考,具体内容如下 暑假学了十几天python,然后用pygame模块写了一个五子棋的小游戏,代码跟有缘人分享一下. import numpy as np import pygame import sys import traceback import copy from pygame.locals import * pygame.init() pygame.mixer.init() #颜色 background=(201,202

  • python版本五子棋的实现代码

    正文之前 前阵子做了个<人工智能> 的课程作业,然后写了个人工智障...大概就是个可以跟你下五子棋的傻儿子...下面是代码和效果 正文 1. 摘要 机器博弈是人工智能领域的重要分支,它的研究对象多以复杂的棋牌类智力游戏为主,已经得到解决的棋类游戏,几乎全部都应归功于机器博弈近半个世纪的发展.计算机解决问题的优势在于能把不易解析的问题,借助于现代计算机的运算速度优势枚举出所有的合理情形而得解;然而,博弈问题的复杂程度决定了它不能过度依赖机器的计算能力.许多待解决的或已经解决的棋类,其状态空间复杂

  • 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

  • 使用python实现简单五子棋游戏

    用python实现五子棋简单人机模式的练习过程,供大家参考,具体内容如下 第一次写博客,我尽力把它写好. 最近在初学python,今天就用自己的一些粗浅理解,来记录一下这几天的python简单人机五子棋游戏的练习,下面是实现过程的理解(是在cmd中运行的): 主要流程: *重点内容* - 首先是模块及类的划分 - 棋子类和棋盘类的方法 - 对策略类里的功能进行细分,调用棋子类和棋盘类 - 写出判断输赢的方法 - 用main函数进行整个游戏进度的控制 模块及类的划分 类的划分涉及到了面向对象的内容

  • python制作简单五子棋游戏

    本文实例为大家分享了python五子棋游戏的具体代码,供大家参考,具体内容如下 #五子棋 ''' 矩阵做棋盘 16*16 "+" 打印棋盘 for for 游戏是否结束 开始下棋 while 游戏是否结束: 黑白交替 player=0 p%2==0 ==1 p+=1 下棋动作一样 但是棋子不一样 ''' 代码 #创建棋盘的程序 def initBoard(): global board #调用全局的board board=[None]*16 for i in range(len(boa

  • Android开发实现的简单五子棋游戏示例

    本文实例讲述了Android开发实现的简单五子棋游戏.分享给大家供大家参考,具体如下: 我刚刚在Android上写的一个五子棋的小程序,在这里跟大家分享一下. 写完以后感觉Android的SDK,虽然也是使用Java的,但是跟Java ME还是有很大不一样. 首先就是Android的SDK没有实现所有的Java ME标准,原来运行在KJava上的应用程序是不能在Android上直接跑的. 另外就是Android的SDK有大量的API是Android自己的,需要开发人员去了解. Android的开

  • VUE+Canvas实现简单五子棋游戏的全过程

    前言 在布局上,五子棋相比那些目标是随机运动的游戏,实现起来相对简单许多,思路也很清晰,总共分为: (1)画棋盘: (2)监听点击事件画黑白棋子: (3)每次落子之后判断是否有5子相连,有则赢. 最复杂的恐怕就是如何判断五子棋赢了,那么就先从简单的开始,画个棋盘吧~ 1.画棋盘 棋盘很简单,我们画个15*15的棋盘,横线竖线相交错: drawCheckerboard() { // 画棋盘 let _this = this; _this.ctx.beginPath(); _this.ctx.fil

  • QT实现简单五子棋游戏

    本文实例为大家分享了QT实现简单五子棋游戏的具体代码,供大家参考,具体内容如下 FIR.pro #------------------------------------------------- # # Project created by QtCreator 2012-09-01T15:09:11 # #------------------------------------------------- QT += core gui TARGET = FIR TEMPLATE = app SO

  • 原生JavaScript实现简单五子棋游戏

    本文实例为大家分享了JavaScript实现简单五子棋游戏的具体代码,供大家参考,具体内容如下 HTML页面 注释都很明确了,大家好好学习. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, height=d

  • python实现简单俄罗斯方块游戏

    本文实例为大家分享了python实现简单俄罗斯方块游戏的具体代码,供大家参考,具体内容如下 import pygame,sys,random,time all_block = [[[0,0],[0,-1],[0,1],[0,2]],         [[0,0],[0,1],[1,1],[1,0]],         [[0,0],[0,-1],[-1,0],[-1,1]],          [[0,0],[0,1],[-1,-1],[-1,0]],           [[0,0],[0,1

  • pygame实现简单五子棋游戏

    本文实例为大家分享了pygame实现简单五子棋游戏的具体代码,供大家参考,具体内容如下 看代码: ①Gomuku2.py: import sys import random import pygame from pygame.locals import * import pygame.gfxdraw from checkerboard import Checkerboard, BLACK_CHESSMAN, WHITE_CHESSMAN, offset, Point SIZE = 30  # 棋

  • 基于C语言实现简单五子棋游戏

    本文实例为大家分享了C语言实现简单五子棋游戏的具体代码,供大家参考,具体内容如下 五子棋大家都玩儿过,所以规则就不介绍了 今天遇到一个学弟在实现的时候遇到一些问题,所以将实现的过程记录下 水平有限,仅供参考,互相交流,共同进步. #include<stdio.h> #include<windows.h>   int main() {       int i,j;//表示棋盘横纵坐标     /*********************************************

随机推荐