运用博弈树算法编写的黑白棋游戏,运行环境为Python3.9。
树的搜索深度默认为3(下一步向前分析2步),往前随着搜索深度的增大,算法更加聪明,但是分析时间会长很多。
可以通过修改源码中的以下部分search_depth的值来设置树的搜索深度:
#####################设置搜索深度###############
global search_depth
search_depth=3 #修改search_depth的值以改变搜索深度
#####################设置搜索深度###############
当搜索深度为4时,程序胜率较高,但由于没有启动多线程,下子后算法分析时会卡住,一般要等待半分钟左右(时间关系,没有进行剪枝处理)。由于本程序主要关注算法,用户体验先忽略不计。勿喷。
运行如下:
源码如下:
import tkinter as tk
import numpy as np
from collections import Counter
from tkinter import StringVar, IntVar
current_player=0;#0 represents the user while 1 represents the algrithm
current_situation=np.zeros([10,10])
current_situation[4][4]=1
current_situation[5][4]=-1
current_situation[4][5]=-1
current_situation[5][5]=1
#current_situation[5][6]=-1
#current_situation[6][6]=1
#current_situation[4][3]=-1
#current_situation[3][5]=-1
'''
current_situation[3][6]=-1
current_situation[5][7]=1
current_situation[5][8]=1
current_situation[4][7]=-1
current_situation[3][7]=-1
current_situation[6][9]=-1'''
def dropchess(event):
global current_player,current_situation,depth,depthr,turn
row=int(event.y/50)
col=int(event.x/50)
drop_points,change_points=get_avalible_drop(current_player,current_situation)
set_change_points_on(drop_points,change_points,[row,col])
if current_player==0 and [row,col] in drop_points:
current_situation[row][col]=-1
if current_player==0:
current_player=1
else:
current_player=0
#算法下子
situation=current_situation.copy()
#print(situation)
bestdrop=getbestdrop(situation)
#print(bestdrop)
drop_points,change_points=get_avalible_drop(current_player,current_situation)
set_change_points_on(drop_points,change_points,bestdrop)
current_situation[bestdrop[0]][bestdrop[1]]=1
current_player=0
depth=0
depthr=0
#turn.set('轮到你下子o...')
#算法下子
drop_points,change_points=get_avalible_drop(current_player,current_situation)
set_avalible_drop_on(drop_points)
draw_Chess_from_Maxtrix(current_situation)
clear_avalible_drop(drop_points)
statistical_num(current_situation)
turn.set(' ')
def draw_Chess_from_Maxtrix(current_situation):
for i in range(len(current_situation)):
for j in range(len(current_situation[0])):
if current_situation[i][j]==1:
canvas.create_oval(j*50+6,i*50+6,j*50+44,i*50+44,fill='white')#白色是算法,黑色是用户
if current_situation[i][j]==-1:
canvas.create_oval(j*50+6,i*50+6,j*50+44,i*50+44,fill='black')
if current_situation[i][j]==2:
canvas.create_oval(j*50+6,i*50+6,j*50+44,i*50+44,outline='red')
if current_situation[i][j]==0:
canvas.create_oval(j*50+6,i*50+6,j*50+44,i*50+44,outline='green')
def set_avalible_drop_on(drop_points):#通过可下子位置列表绘制可下子标识
global current_situation
for point in drop_points:
current_situation[point[0]][point[1]]=2
def clear_avalible_drop(drop_points):#每一次绘制完棋子以及可下子标识后,清空当前局面矩阵可下子点
global current_situation
for point in drop_points:
current_situation[point[0]][point[1]]=0
def set_change_points_on(avalible_drop,change_points,coordinate):
global current_situation
idx=avalible_drop.index(coordinate)
points=change_points[idx]
for point in points:
if current_situation[point[0]][point[1]]==1:
current_situation[point[