You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1065 lines
54 KiB

5 months ago
import random
from PIL import Image, ImageTk
import math
import random
import time
from tkinter import W
Chessimgx = 0 # 玩家落子的横坐标
Chessimgy = 0 # 玩家落子的纵坐标
xregretFLAG = [0 for x in range(365)] # 悔棋的数组x坐标
yregretFLAG = [0 for y in range(365)] # 悔棋的数组y坐标
class Chess:
def __init__(self):
self.chessData = [[{"Cstate": 0, "Cstep": 0} for j in range(19)] for i in
range(19)] # Cstate=0无棋子1有黑棋子2有白棋子Cstep为该棋子落子的步骤
self.currentStep = 0 # 棋子当前进行的步数
self.Chessimg = [[0 for y in range(19)] for x in range(19)]
self.Reviewflag = 0 # 复盘的标签flag 0为没有复盘 1为已经复盘防止重复复盘导致无法消除新建的标签
self.Reviewlabel = [[0 for y in range(19)] for x in range(19)] # 复盘的数字标签
self.score = [[0 for y in range(19)] for x in range(19)] # 初始化计分数组
self.maxScore = 0 # 落子分数
self.counts = 0
self.newCount = 0
self.OvaloneNew = [] # 棋子对象列表
self.winFlag = 0 # 判断是否取得胜利
self.Gameover = 0 # 判断游戏是否结束1 黑方胜2 白方胜利3 平局
self.depth = 0 # 搜索的深度
self.player = 0 # 轮到下棋的标志1=下0=不下
self.player2 = 0 # 玩家2
self.currentPlayer = 1 # =1黑方=2白方
self.myColor = 0 # 玩家选择的棋子颜色
self.chessMode = 3 # 对弈方式标志 chessMode=0,人-人对弈; =1, 人-机白对弈; =2,机黑-人对弈, =4,测试模式)
self.player2Color = 0 # 玩家2的棋子颜色
self.maxScorePos = ()
# 结果展示的图片,以用于删除
self.PicLocIds = []
def gameEnd(self):
if self.Gameover == 1 or self.winFlag == 1:
return True
else:
return False
# 计算某个位置得分
def countScore(self, x, y, computerColor):
# global sum,count,value
global s
sum = 0
# count = 0
value = [0, 0, 0, 0]
upcount = [0, 0, 0, 0] # 左、上、左斜上、左斜下 棋子数
downcount = [0, 0, 0, 0] # 右、下、右斜向下、右斜向上 棋子数
upflag = [0, 0, 0, 0] # 左、上、左斜上、左斜下 空格数
downflag = [0, 0, 0, 0] # 右、下、右斜向下、右斜向上 空格数
message = ''# 存储得分信息的字符串
for color in range(1, 3):
# 假设当前位置为当前遍历的棋子颜色
self.chessData[x][y]['Cstate'] = color
for i in range(x - 1, -1, -1): # 计算左边棋子数量 upcount[0]表示左侧同类棋子 用upflag[0] 记录
if self.chessData[i][y]['Cstate'] == color:
upcount[0] += 1 # 左侧有自己棋子
elif self.chessData[i][y]['Cstate'] != 0 and self.chessData[i][y]['Cstate'] != color: # 左侧有对方棋子
upflag[0] = -1
break
elif self.chessData[i][y]['Cstate'] == 0: # 左侧没有棋子
upflag[0] = 1
if i - 1 >= 0 and self.chessData[i - 1][y]['Cstate'] == 0:
upflag[0] = 2 # 表示有两个空格
else:
break
if i - 2 >= 0 and self.chessData[i - 2][y]['Cstate'] == 0:
upflag[0] = 3 # 表示有三个空格
else:
break
break
for i in range(x + 1, 19): # 计算右边棋子数量 downcount[0]表示右侧同类棋子 用downflag[0] 记录
if self.chessData[i][y]['Cstate'] == color:
downcount[0] += 1 # 右侧有自己棋子
elif self.chessData[i][y]['Cstate'] != 0 and self.chessData[i][y]['Cstate'] != color: # 右侧有对方棋子
downflag[0] = -1
break
elif self.chessData[i][y]['Cstate'] == 0: # 右侧没有棋子
downflag[0] = 1
if i + 1 < 19 and self.chessData[i + 1][y]['Cstate'] == 0:
downflag[0] = 2 # 表示有两个空格
else:
break
if i + 2 < 19 and self.chessData[i + 2][y]['Cstate'] == 0:
downflag[0] = 3 # 表示有三个空格
else:
break
break
for i in range(y - 1, -1, -1): # 计算方向向上 upcount[1]表示上方同类棋子 用upflag[1] 记录
if self.chessData[x][i]['Cstate'] == color:
upcount[1] += 1 # 上有自己棋子
elif self.chessData[x][i]['Cstate'] != 0 and self.chessData[x][i]['Cstate'] != color: # 上有对方棋子
upflag[1] = -1
break
elif self.chessData[x][i]['Cstate'] == 0: # 上没有棋子
upflag[1] = 1
if i - 1 >= 0 and self.chessData[x][i - 1]['Cstate'] == 0:
upflag[1] = 2 # 表示上有两个空格
else:
break
if i - 2 >= 0 and self.chessData[x][i - 2]['Cstate'] == 0:
upflag[1] = 3 # 表示上有三个空格
else:
break
break
for i in range(y + 1, 19): # 计算下棋子数量 downcount[0]表示下同类棋子 用downflag[0] 记录
if self.chessData[x][i]['Cstate'] == color:
downcount[1] += 1 # 下有自己棋子
elif self.chessData[x][i]['Cstate'] != 0 and self.chessData[x][i]['Cstate'] != color: # 下有对方棋子
downflag[1] = -1
break
elif self.chessData[x][i]['Cstate'] == 0: # 下侧没有棋子
downflag[1] = 1
if i + 1 < 19 and self.chessData[x][i + 1]['Cstate'] == 0:
downflag[1] = 2 # 表示下有两个空格
else:
break
if i + 2 < 19 and self.chessData[x][i + 2]['Cstate'] == 0:
downflag[1] = 3 # 表示下有三个空格
else:
break
break
j = 1
for i in range(x - 1, -1, -1): # // 计算左斜向上 upcount[2]表示左斜向上同类棋子 用upflag[2]记录
# for j in range(y - 1, -1, -1):
if y - j >= 0 and self.chessData[i][y - j]['Cstate'] == color:
upcount[2] += 1 # 左斜向上有自己棋子
j += 1
elif y - j >= 0 and self.chessData[i][y - j]['Cstate'] != 0 and self.chessData[i][y - j][
'Cstate'] != color: # 左斜向上有对方棋子
upflag[2] = -1
j += 1
break
elif y - j >= 0 and self.chessData[i][y - j]['Cstate'] == 0: # 左斜向上没有棋子
upflag[2] = 1
if i - 1 >= 0 and y - j - 1 >= 0 and self.chessData[i - 1][y - j - 1]['Cstate'] == 0:
upflag[2] = 2 # 表示有两个空格
j += 1
else:
j += 1
break
if i - 2 >= 0 and y - j - 2 >= 0 and self.chessData[i - 2][y - j - 2]['Cstate'] == 0:
upflag[2] = 3 # 表示有三个空格
j += 1
else:
j += 1
break
j += 1
break
j = 1
for i in range(x + 1, 19): # // 计算右斜向下 downcount[2]表示右斜向下同类棋子 用downflag[2]记录
if y + j < 19 and self.chessData[i][y + j]['Cstate'] == color:
downcount[2] += 1 # 右斜向下有自己棋子
j += 1
elif y + j < 19 and self.chessData[i][y + j]['Cstate'] != 0 and self.chessData[i][y + j][
'Cstate'] != color: # 右斜向下有对方棋子
downflag[2] = -1
j += 1
break
elif y + j < 19 and self.chessData[i][y + j]['Cstate'] == 0: # 右斜向下没有棋子
downflag[2] = 1
if i + 1 < 19 and y + j + 1 < 19 and self.chessData[i + 1][y + j + 1]['Cstate'] == 0:
downflag[2] = 2 # 表示有两个空格
j += 1
else:
j += 1
break
if i + 2 < 19 and y + j + 2 < 19 and self.chessData[i + 2][y + j + 2]['Cstate'] == 0:
downflag[2] = 3 # 表示有三个空格
j += 1
else:
j += 1
break
j += 1
break
j = 1
for i in range(x + 1, 19): # // 计算右斜向上 downcount[3]表示右斜向上同类棋子 用downflag[3]记录
# for j in range(y - 1, -1, -1):
if y - j >= 0 and self.chessData[i][y - j]['Cstate'] == color:
downcount[3] += 1 # 右斜向上有自己棋子
j += 1
elif y - j >= 0 and self.chessData[i][y - j]['Cstate'] != 0 and self.chessData[i][y - j][
'Cstate'] != color: # 右斜向上有对方棋子
downflag[3] = -1
j += 1
break
elif y - j >= 0 and self.chessData[i][y - j]['Cstate'] == 0: # 右斜向上没有棋子
downflag[3] = 1
if i + 1 < 19 and y - j - 1 >= 0 and self.chessData[i][y - j]['Cstate'] == 0:
downflag[3] = 2 # 表示有两个空格
j += 1
else:
j += 1
break
if i + 2 < 19 and y - j - 2 >= 0 and self.chessData[i][y - j]['Cstate'] == 0:
downflag[3] = 3 # 表示有三个空格
j += 1
else:
j += 1
break
j += 1
break
j = 1
for i in range(x - 1, -1, -1): # 计算左斜向下 upcount[3]表示左斜向下同类棋子 用upflag[3]记录
# for j in range(y + 1, 15):
if y + j < 19 and self.chessData[i][j + y]['Cstate'] == color:
upcount[3] += 1 # 左斜向下有自己棋子
j += 1
elif y + j < 19 and self.chessData[i][j + y]['Cstate'] != 0 and self.chessData[i][j + y][
'Cstate'] != color: # 左斜向下有对方棋子
upflag[3] = -1
j += 1
break
elif y + j < 19 and self.chessData[i][j + y]['Cstate'] == 0: # 左斜向下没有棋子
upflag[3] = 1
if i - 1 >= 0 and j + y + 1 < 19 and self.chessData[i][j + y]['Cstate'] == 0:
upflag[3] = 2 # 表示有两个空格
j += 1
else:
j += 1
break
if i - 2 >= 0 and j + y + 2 < 19 and self.chessData[i - 1][j + y + 1]['Cstate'] == 0:
upflag[3] = 3 # 表示有三个空格
j += 1
else:
j += 1
break
j += 1
break
# 根据上述统计的同色棋子数量和两端的空位情况,对当前假设的棋子颜色进行得分计算
# 如果是电脑方的棋子
if computerColor == self.chessData[x][y]['Cstate']: # 详细的得分规则计算,包括成五、活四、死四、活三等情况
for i in range(4):
count = upcount[i] + downcount[i] + 1
if count == 5: # 成五
message += '五子连珠得分加4000\n'
value[i] = 4000
elif count == 4:
if upflag[i] >= 1 and downflag[i] >= 1: # 活四
message += '四子连珠且有两端未被对方封堵得分加1900\n'
value[i] = 1900
if (upflag[i] >= 1 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] >= 1): # 眠四
message += '四子连珠且有一端未被对方封堵得分加300\n'
value[i] = 300
if upflag[i] == -1 and downflag[i] == -1: # 死四
message += '四子连珠但两端都被封堵得分减5\n'
value[i] = -5
# 其他3子2子情况类似
elif count == 3:
if (upflag[i] >= 2 and downflag[i] >= 1) or (upflag[i] >= 1 and downflag[i] >= 2): # 活三
message += '三子连珠且有两端未被对方封堵得分加400\n'
value[i] = 400
if (upflag[i] >= 2 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] >= 2) or (
upflag[i] == 1 and downflag[i] == 1): # 眠三
message += '三子连珠且有有一端未被对方封堵得分加80\n'
value[i] = 80
if upflag[i] == -1 and downflag[i] == -1: # 死三
message += '三子连珠但两端都被封堵得分减5\n'
value[i] = -5
elif count == 2:
if (upflag[i] >= 3 and downflag[i] >= 1) or (upflag[i] >= 1 and downflag[i] >= 3) or (
upflag[i] >= 2 and downflag[i] >= 2): # 活二
message += '二子连珠且有两端未被对方封堵得分加105\n'
value[i] = 105
if (upflag[i] >= 3 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] >= 3) or (
upflag[i] == 2 and downflag[i] == 1) or (upflag[i] == 1 and downflag[i] == 2): # 眠三
message += '二子连珠且有有一端未被对方封堵得分加35\n'
value[i] = 35
if upflag[i] == -1 and downflag[i] == -1: # 死二
message += '二子连珠但两端都被封堵得分减5\n'
value[i] = -5
else:
if (upflag[i] >= 3 and downflag[i] >= 2) or (upflag[i] >= 2 and downflag[i] >= 3): # 活一
value[i] = 8
if (upflag[i] == 2 and downflag[i] == 2) or (upflag[i] == 1 and downflag[i] == 3) or (
upflag[i] == 3 and downflag[i] == 1): # 眠一
value[i] = 2
if (upflag[i] <= 1 and downflag[i] <= 2) or (upflag[i] <= 2 and downflag[i] <= 1): # 死一
value[i] = -5
else:# 如果是玩家方的棋子
# 同上,但得分标准可能有所不同
for i in range(4):
count = upcount[i] + downcount[i] + 1
if count == 5: # 成五
value[i] = 3000
elif count == 4:
if upflag[i] >= 1 and downflag[i] >= 1: # 活四
value[i] = 1500
if (upflag[i] >= 1 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] >= 1): # 眠四
value[i] = 250
if upflag[i] == -1 and downflag[i] == -1: # 死四
value[i] = -5
elif count == 3:
if (upflag[i] >= 2 and downflag[i] >= 1) or (upflag[i] >= 1 and downflag[i] >= 2): # 活三
value[i] = 300
if (upflag[i] >= 2 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] >= 2) or (
upflag[i] == 1 and downflag[i] == 1): # 眠三
value[i] = 50
if upflag[i] == -1 and downflag[i] == -1: # 死三
value[i] = -5
elif count == 2:
if (upflag[i] >= 3 and downflag[i] >= 1) or (upflag[i] >= 1 and downflag[i] >= 3) or (
upflag[i] >= 2 and downflag[i] >= 2): # 活二
value[i] = 65
if (upflag[i] >= 3 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] >= 3) or (
upflag[i] == 2 and downflag[i] == 1) or (upflag[i] == 1 and downflag[i] == 2): # 眠二
value[i] = 15
if (upflag[i] == -1 and downflag[i] == -1) or (upflag[i] == 1 and downflag[i] == 1) or (
upflag[i] == -1 and downflag[i] == 2) or (upflag[i] == 2 and downflag[i] == -1): # 死二
value[i] = -5
else:
if (upflag[i] >= 3 and downflag[i] >= 2) or (upflag[i] >= 2 and downflag[i] >= 3): # 活一
value[i] = 5
if (upflag[i] == 2 and downflag[i] == 2) or (upflag[i] == 1 and downflag[i] == 3) or (
upflag[i] == 3 and downflag[i] == 1): # 眠一
value[i] = 1
if (upflag[i] <= 1 and downflag[i] <= 2) or (upflag[i] <= 2 and downflag[i] <= 1) or (
upflag[i] <= 3 and downflag[i] == -1) or (upflag[i] == -1 and downflag[i] <= 3): # 死三
value[i] = -5
# 汇总得分,并重置变量以便下一轮计算
for i in range(4):
sum += value[i]
value[i] = 0
upcount[i] = 0
downcount[i] = 0
upflag[i] = 0
downflag[i] = 0
# 恢复棋盘状态并返回得分及得分信息
self.chessData[x][y]['Cstate'] = 0
return sum, message
# 根据估值函数计算最佳落子点
def returnChess(self, Depth, computercolor):
time.sleep(0.5)
self.newCount = 0
self.maxScore = 0
self.counts = 0
pos = [[0 for y in range(2)] for x in range(10)]
evaFLAG = 0
position = [0, 0] # 初始化位置坐标数组
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if 0 <= i < 19 and 0 <= j < 19:
if self.chessData[i][j]['Cstate'] == 0:
self.score[i][j], s = self.countScore(i, j, computercolor)
self.newCount += 1
if self.score[i][j] > 0:
self.counts += 1
if self.maxScore < self.score[i][j]:
self.maxScore = self.score[i][j] # 记录当前棋盘分数的最大值
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if self.chessData[i][j]['Cstate'] != 0:
self.score[i][j] = self.chessData[i][j]['Cstate']
if i < 19 and j < 19 and self.score[i][j] == self.maxScore and self.chessData[i][j]['Cstate'] == 0:
pos[evaFLAG][0] = i
pos[evaFLAG][1] = j
evaFLAG += 1
m = random.randint(0, evaFLAG - 1)
position[0] = pos[m][0]
position[1] = pos[m][1]
return position
# 落子建议下一步,
def returnChessNew(self, Depth, computercolor):
time.sleep(0.5)
self.newCount = 0
self.maxScore = 0
self.counts = 0
pos = [[0 for y in range(2)] for x in range(10)]
evaFLAG = 0
position = [0, 0] # 初始化位置坐标数组
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if 0 <= i < 19 and 0 <= j < 19:
if self.chessData[i][j]['Cstate'] == 0:
self.score[i][j] = self.countScore(i, j, computercolor)
self.newCount += 1
if self.score[i][j] > 0:
self.counts += 1
if self.maxScore < self.score[i][j]:
self.maxScore = self.score[i][j] # 记录当前棋盘分数的最大值
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if self.chessData[i][j]['Cstate'] != 0:
self.score[i][j] = self.chessData[i][j]['Cstate']
if i < 19 and j < 19 and self.score[i][j] >= self.maxScore - 5000 and self.chessData[i][j][
'Cstate'] == 0:
pos[evaFLAG][0] = i
pos[evaFLAG][1] = j
evaFLAG += 1
m = random.randint(0, evaFLAG - 1)
position[0] = pos[m][0]
position[1] = pos[m][1]
return position
# 判断玩家点击的位置是否可以落子如果可以落子则进行self.make_move()移动返回self.make_move()的值否则返回False
def playerLocation(self, playerx, playery, canvas, blackch, whitech):
if 0 <= playerx <= 706 and 0 <= playery <= 640:
m = (playerx - 40) / 37
n = (playery - 21) / 34
intm = int(m)
intn = int(n)
if m - intm >= 0.5 or m - intm <= -0.5:
pointi = intm + 1
else:
pointi = intm
if n - intn >= 0.5 or n - intn <= -0.5:
pointj = intn + 1
else:
pointj = intn
# print(pointi, pointj)
if 0 <= pointi <= 18 and 0 <= pointj <= 18:
# print("1:%d" % self.currentStep)
print("准备makeMove")
return self.makeMove(pointi, pointj, canvas, blackch, whitech)
# print("2:%d" % self.currentStep)
return False
def getPlayerMoveLocation_xy(self, playerx, playery, canvas, blackch, whitech):
if 0 <= playerx <= 706 and 0 <= playery <= 640:
m = (playerx - 40) / 37
n = (playery - 21) / 34
intm = int(m)
intn = int(n)
if m - intm >= 0.5 or m - intm <= -0.5:
pointi = intm + 1
else:
pointi = intm
if n - intn >= 0.5 or n - intn <= -0.5:
pointj = intn + 1
else:
pointj = intn
# print(pointi, pointj)
if 0 <= pointi <= 18 and 0 <= pointj <= 18:
# print("1:%d" % self.currentStep)
return self.makeMove(pointi, pointj, canvas, blackch, whitech), pointi, pointj
# print("2:%d" % self.currentStep)
return self.makeMove(pointi, pointj, canvas, blackch, whitech), pointi, pointj
# # 在pointi, pointj位置进行落子返回落子是否成功的标记
# def makeMove(self, pointi, pointj, canvas, blackch, whitech):
#
# print("self.chessData[pointi][pointj]['Cstate']", self.chessData[pointi][pointj]['Cstate'])
# print("self.myColor",self.myColor)
# print("self.currentStep % 2",self.currentStep % 2)
# print("self.player2Color",self.player2Color)
#
# # 如果pointi, pointj位置没有棋子且当前执白子
# if self.chessData[pointi][pointj]['Cstate'] == 0 and self.myColor == 2 and self.currentStep % 2 == 0:
# # 计算得到需要落子画图位置,并画棋子
# Chessimgx = pointi*36.8 + 41
# Chessimgy = pointj*34.3 + 20
# oval = canvas.create_image(Chessimgx - 14, Chessimgy, image=blackch, anchor=W)
# self.Chessimg[pointi][pointj] = oval
# self.chessData[pointi][pointj]['Cstate'] = 2
# xregretFLAG[self.currentStep] = pointi
# yregretFLAG[self.currentStep] = pointj
# self.player = 0 # 玩家下棋标志置0
# self.player2 = 1 # 玩家2下棋标志置1
# self.currentStep += 1
# self.chessData[pointi][pointj]['Cstep'] = self.currentStep
# a = max(abs(pointi - 9), abs(pointj - 9))
# self.depth = max(self.depth, a)
# print("makeMove True")
# return True
# # 如果pointi, pointj位置没有棋子且当前执黑子
# elif (self.chessData[pointi][pointj]['Cstate'] == 0 and self.myColor == 1 and self.currentStep % 2 != 0) or \
# (self.chessData[pointi][pointj]['Cstate'] == 0 and self.player2Color == 1 and self.currentStep % 2 != 0):
# # 计算得到需要落子画图位置,并画棋子
# Chessimgx = pointi*36.8 + 41
# Chessimgy = pointj*34.6 + 20
# oval = canvas.create_image(Chessimgx - 14, Chessimgy, image=whitech, anchor=W)
# self.Chessimg[pointi][pointj] = oval
# self.chessData[pointi][pointj]['Cstate'] = 1
# xregretFLAG[self.currentStep] = pointi
# yregretFLAG[self.currentStep] = pointj
# self.currentStep += 1
# self.player = 0
# self.player2 = 1 # 玩家2下棋标志置1
# # self.computer = 1
# self.chessData[pointi][pointj]['Cstep'] = self.currentStep
# a = max(abs(pointi - 9), abs(pointj - 9))
# self.depth = max(self.depth, a)
# print("makeMove True")
# return True
# # 如果pointi, pointj位置有棋子无法落子
# elif self.chessData[pointi][pointj]['Cstate'] != 0:
# print("makeMove False")
# return False
# 在pointi, pointj位置进行落子返回落子是否成功的标记
def makeMove(self, pointi, pointj, canvas, blackch, whitech):
print("self.chessData[pointi][pointj]['Cstate']", self.chessData[pointi][pointj]['Cstate'])
print("self.myColor", self.myColor)
print("self.currentStep % 2", self.currentStep % 2)
print("self.player2Color", self.player2Color)
# 检查是否可以在pointi, pointj位置落子
if self.chessData[pointi][pointj]['Cstate'] != 0:
print("makeMove False")
return False
# 检查是否轮到当前玩家落子
is_player_turn = (self.myColor == 2 and self.currentStep % 2 == 0) or \
(self.myColor == 1 and self.currentStep % 2 != 0)
is_player2_turn = (self.player2Color == 1 and self.currentStep % 2 != 0)
# 如果不是当前玩家的轮次则不能落子函数返回False
if not is_player_turn and not is_player2_turn:
print("makeMove False")
return False
# 根据当前执棋方选择棋子图
image = blackch if self.currentStep % 2 == 0 else whitech
# 计算得到需要落子画图位置,并画棋子
Chessimgx = pointi * 36.8 + 41
Chessimgy = pointj * 34.3 + 20
# Chessimgy = pointj * 34.3 + 20 if self.myColor == 2 else pointj * 34.6 + 20
oval = canvas.create_image(Chessimgx - 14, Chessimgy, image=image, anchor=W)
# 更新棋盘数据,记录棋子信息
self.Chessimg[pointi][pointj] = oval
self.chessData[pointi][pointj]['Cstate'] = self.myColor
xregretFLAG[self.currentStep] = pointi
yregretFLAG[self.currentStep] = pointj
self.currentStep += 1
self.player = 0
self.player2 = 1
self.chessData[pointi][pointj]['Cstep'] = self.currentStep
a = max(abs(pointi - 9), abs(pointj - 9))# 计算落子距离棋盘中心的距离
self.depth = max(self.depth, a) # 更新搜索深度用于AI决策等场景
print("makeMove True")
return True
def getDirectionScore(self, y, x, y_offset, x_offset):
nowcount = 0 # 落子处我方连续子数
_nowcount = 0 # 落子处对方连续子数
space = None # 我方连续子中有无空格
_space = None # 对方连续子中有无空格
both = 0 # 我方连续子两端有无阻挡
_both = 0 # 对方连续子两端有无阻挡
tmp_x = x
tmp_y = y
# 如果是 2 表示是边上是我方子1 表示敌方子
if 0 <= y + y_offset <= 18 and 0 <= x + x_offset <= 18:
Cflag = self.chessData[y + y_offset][x + x_offset]['Cstate']
if Cflag != 0:
for step in range(1, 6):
x += x_offset
y += y_offset
if 0 <= x < 18 and 0 <= y < 18:
if Cflag == 2:
if self.chessData[y][x]['Cstate'] == 2 and self.myColor == 2: # ) or (self.chessData[y][x]['Cstate'] == 1 and self.myColor == 1)
nowcount += 1
if space is False:
space = True
elif self.chessData[y][x]['Cstate'] == 1 and self.myColor == 2: # ) or (self.chessData[y][x]['Cstate'] == 1 and self.myColor == 1)
_both += 1
break
else:
if space is None:
space = False
else:
break # 遇到第二个空格退出
elif Cflag == 1:
if self.chessData[y][x]['Cstate'] == 2 and self.myColor == 1:
_both += 1
break
elif self.chessData[y][x]['Cstate'] == 1 and self.myColor == 1:
_nowcount += 1
if _space is False:
_space = True
else:
if _space is None:
_space = False
else:
break
else:
# 遇到边也就是阻挡
if Cflag == 2:
both += 1
elif Cflag == 1:
_both += 1
if space is False:
space = None
if _space is False:
_space = None
x = tmp_x
y = tmp_y
if 0 <= y - y_offset <= 18 and 0 <= x - x_offset <= 18:
_flag = self.chessData[y - y_offset][x - x_offset]['Cstate']
if _flag != 0:
for step in range(1, 6):
x -= x_offset
y -= y_offset
if 0 <= x < 18 and 0 <= y < 18:
if _flag == 2:
if self.chessData[y][x]['Cstate'] == 2 and self.myColor == 2:
nowcount += 1
if space is False:
space = True
elif self.chessData[y][x]['Cstate'] == 1 and self.myColor == 2:
_both += 1
break
else:
if space is None:
space = False
else:
break # 遇到第二个空格退出
elif _flag == 1:
if self.chessData[y][x]['Cstate'] == 2 and self.myColor == 1:
_both += 1
break
elif self.chessData[y][x]['Cstate'] == 1 and self.myColor == 1:
_nowcount += 1
if _space is False:
_space = True
else:
if _space is None:
_space = False
else:
break
else:
# 遇到边也就是阻挡
if _flag == 1:
both += 1
elif _flag == 2:
_both += 1
Score = 0
if nowcount == 4:
Score = 10000
elif _nowcount == 4:
Score = 9000
elif nowcount == 3:
if both == 0:
Score = 1000
elif both == 1:
Score = 100
else:
Score = 0
elif _nowcount == 3:
if _both == 0:
Score = 900
elif _both == 1:
Score = 90
else:
Score = 0
elif nowcount == 2:
if both == 0:
Score = 100
elif both == 1:
Score = 10
else:
Score = 0
elif _nowcount == 2:
if _both == 0:
Score = 90
elif _both == 1:
Score = 9
else:
Score = 0
elif nowcount == 1:
Score = 10
elif _nowcount == 1:
Score = 9
else:
Score = 0
if space or _space:
Score /= 2
return Score
def getPointScore(self, y, x):
Score = 0
offset = [(1, 0), (0, 1), (1, 1), (1, -1)]
for os in offset:
Score += self.getDirectionScore(y, x, os[0], os[1])
return Score
def atuoActive(self):
_Score = 0
position = [-1 for x in range(2)]
for i in range(0, 18):
for j in range(0, 18):
if self.chessData[i][j]['Cstate'] == 0:
Score = self.getPointScore(i, j)
if Score > _Score:
position[0] = i
position[1] = j
_Score = Score
elif Score == _Score:
r = random.randint(0, 100)
if r % 2 == 0:
position[0] = i
position[1] = j
return position
# 设置的策略ai落子
def aiLocation(self, canvas, blackChPieceImg, whiteChPieceImg):
print("do aiLocation")
if self.depth >= 9:
self.depth = 8
position = self.returnChess(self.depth, self.player2Color) # 调用估值函数
# position = self.atuoactive()
if self.chessData[position[0]][position[1]]['Cstate'] == 0:
# print("3:%d"%self.currentStep)
if self.player2Color == 2 and self.currentStep % 2 == 0:
self.chessData[position[0]][position[1]]['Cstate'] = 2
oval = canvas.create_image(position[0] * 36.8 + 41 - 14, position[1] * 34.6 + 20, image=blackChPieceImg, anchor=W)
self.Chessimg[position[0]][position[1]] = oval
self.chessData[position[0]][position[1]]['Cstep'] = self.currentStep
elif self.player2Color == 1 and self.currentStep % 2 != 0:
self.chessData[position[0]][position[1]]['Cstate'] = 1
oval = canvas.create_image(position[0] * 36.8 + 41 - 14, position[1] * 34.6 + 20, image=whiteChPieceImg, anchor=W)
self.Chessimg[position[0]][position[1]] = oval
self.chessData[position[0]][position[1]]['Cstep'] = self.currentStep
xregretFLAG[self.currentStep] = position[0]
yregretFLAG[self.currentStep] = position[1]
self.player = 1 # 玩家下棋标志置0
self.player2 = 0 # 玩家2下棋标志置1
self.currentStep += 1
self.chessData[position[0]][position[1]]['Cstep'] = self.currentStep
a = max(abs(position[0] - 9), abs(position[1] - 9)) # 计算该点到中心的最大的距离
self.depth = max(self.depth, a) # 不断更新Depth的值
# print("4:%d" % self.currentStep)
return True
# 判断对局是否结束,如果结束则返回胜负信息
def chessCheck(self):
for x in range(15): # 1.判断x-轴是否连续五子
for y in range(19):
if self.chessData[x][y]['Cstate'] == 1 and self.chessData[x + 1][y]['Cstate'] == 1 and \
self.chessData[x + 2][y]['Cstate'] == 1 and self.chessData[x + 3][y]['Cstate'] == 1 and \
self.chessData[x + 4][y]['Cstate'] == 1:
self.winFlag = 1
return 1
if self.chessData[x][y]['Cstate'] == 2 and self.chessData[x + 1][y]['Cstate'] == 2 and \
self.chessData[x + 2][y]['Cstate'] == 2 and self.chessData[x + 3][y]['Cstate'] == 2 and \
self.chessData[x + 4][y]['Cstate'] == 2:
self.winFlag = 1
return 2
# 2.判断y-轴是否连续五子
for x in range(19):
for y in range(15):
if self.chessData[x][y]['Cstate'] == 1 and self.chessData[x][y + 1]['Cstate'] == 1 and \
self.chessData[x][y + 2]['Cstate'] == 1 and self.chessData[x][y + 3]['Cstate'] == 1 and \
self.chessData[x][y + 4]['Cstate'] == 1:
self.winFlag = 1
return 1
if self.chessData[x][y]['Cstate'] == 2 and self.chessData[x][y + 1]['Cstate'] == 2 and \
self.chessData[x][y + 2]['Cstate'] == 2 and self.chessData[x][y + 3]['Cstate'] == 2 and \
self.chessData[x][y + 4]['Cstate'] == 2:
self.winFlag = 1
return 2
# 3.判断右上-左下是否连续五子
for x in range(15):
for y in range(4, 19):
if self.chessData[x][y]['Cstate'] == 1 and self.chessData[x + 1][y - 1]['Cstate'] == 1 and \
self.chessData[x + 2][y - 2]['Cstate'] == 1 and self.chessData[x + 3][y - 3]['Cstate'] == 1 and \
self.chessData[x + 4][y - 4]['Cstate'] == 1:
self.winFlag = 1
return 1
if self.chessData[x][y]['Cstate'] == 2 and self.chessData[x + 1][y - 1]['Cstate'] == 2 and \
self.chessData[x + 2][y - 2]['Cstate'] == 2 and self.chessData[x + 3][y - 3]['Cstate'] == 2 and \
self.chessData[x + 4][y - 4]['Cstate'] == 2:
self.winFlag = 1
return 2
# 4.判断左上-右下是否连续五子
for x in range(15):
for y in range(15):
if self.chessData[x][y]['Cstate'] == 1 and self.chessData[x + 1][y + 1]['Cstate'] == 1 and \
self.chessData[x + 2][y + 2]['Cstate'] == 1 and self.chessData[x + 3][y + 3]['Cstate'] == 1 and \
self.chessData[x + 4][y + 4]['Cstate'] == 1:
self.winFlag = 1
return 1
if self.chessData[x][y]['Cstate'] == 2 and self.chessData[x + 1][y + 1]['Cstate'] == 2 and \
self.chessData[x + 2][y + 2]['Cstate'] == 2 and self.chessData[x + 3][y + 3]['Cstate'] == 2 and \
self.chessData[x + 4][y + 4]['Cstate'] == 2:
self.winFlag = 1
return 2
# 5.判断是否是平局
avanum = 0
for x in range(19):
for y in range(19):
if self.chessData[x][y]['Cstate'] == 0: # 判断棋盘中是否有空位,有空位则非平局
break
elif self.chessData[x][y]['Cstate'] != 0:
avanum += 1
if avanum == 365:
return 3
# 展示结果
def resultshow(self, root, canvas, whitech, blackch):
global photo, text
if self.winFlag == 1:
print("resultshow")
# if self.myColor == 1 and self.Gameover == 1 and self.computerColor == 2:
# photo = canvas.create_image(800, 300, image=whitech, anchor=W)
# text = canvas.create_text(850, 300, text='玩家 胜利', font='Arial,10', fill='#AE0000', anchor=W)
# elif self.myColor == 2 and self.Gameover == 2 and self.computerColor == 1:
# photo = canvas.create_image(800, 300, image=blackch, anchor=W)
# text = canvas.create_text(850, 300, text='玩家 胜利', font='Arial,10', fill='#AE0000', anchor=W)
# elif self.myColor == 2 and self.Gameover == 1 and self.computerColor == 1:
# photo = canvas.create_image(800, 300, image=whitech, anchor=W)
# text = canvas.create_text(850, 300, text='电脑 胜利', font='Arial,10', fill='#AE0000', anchor=W)
# elif self.myColor == 1 and self.Gameover == 2 and self.computerColor == 2:
# photo = canvas.create_image(800, 300, image=blackch, anchor=W)
# text = canvas.create_text(850, 300, text='电脑 胜利', font='Arial,10', fill='#AE0000', anchor=W)
if self.myColor == 2 and self.player2Color == 1 and self.Gameover == 2:
photo = canvas.create_image(800, 300, image=blackch, anchor=W)
text = canvas.create_text(850, 300, text='玩家1 胜利', font='Arial,10', fill='#AE0000', anchor=W)
elif self.myColor == 1 and self.player2Color == 2 and self.Gameover == 2:
photo = canvas.create_image(800, 300, image=whitech, anchor=W)
text = canvas.create_text(850, 300, text='玩家1 胜利', font='Arial,10', fill='#AE0000', anchor=W)
elif self.myColor == 2 and self.player2Color == 1 and self.Gameover == 1:
photo = canvas.create_image(800, 300, image=whitech, anchor=W)
text = canvas.create_text(850, 300, text='玩家2 胜利', font='Arial,10', fill='#AE0000', anchor=W)
elif self.myColor == 1 and self.player2Color == 2 and self.Gameover == 1:
photo = canvas.create_image(800, 300, image=blackch, anchor=W)
text = canvas.create_text(850, 300, text='玩家2 胜利', font='Arial,10', fill='#AE0000', anchor=W)
elif self.Gameover != 1 or self.Gameover != 2 or self.Gameover != 3:
canvas.delete(photo)
canvas.delete(text)
elif self.Gameover == 3 and self.winFlag == 0:
canvas.create_text(850, 300, text='平 局', font='Arial,10', fill='#AE0000', anchor=W)
def clearLocation(self, canvas):
image_positions = [(750, 145), (870, 145)]
# Delete images and texts at specified positions
for position in image_positions:
canvas.delete(canvas.find_closest(*position))
canvas.delete(canvas.find_closest(*position))
canvas.delete(canvas.find_closest(*position))
canvas.delete(canvas.find_closest(*position))
# canvas.delete(canvas.find_closest(position[0] + 50, 150))
canvas.update()
# 设置右上方当前落子方状态显示
def curLocation(self, canvas, player, player2, ChessMode, blackch, whitech, photos1, photos2):
print("curLocation !!")
# 删除原来的图片,以便于更新展示现在的状态
for item_id in self.PicLocIds:
canvas.delete(item_id)
# 清空ID列表以避免重复删除
self.PicLocIds.clear()
text_options = {'fill': 'white', 'font': 'Arial,9', 'anchor': W}
image_positions = [(750, 145), (870, 145)]
image_data = []
if ChessMode == 0 or ChessMode == 1:
print("player and player2", player,player2)
if player == 1 and player2 == 0:
image_data = [(blackch, '玩家1'), (None, '玩家2')]
else:
image_data = [(None, '玩家1'), (whitech, '玩家2')]
elif ChessMode == 2:
if player == 1 and player2 == 0:
image_data = [(whitech, '玩家1'), (None, '玩家2')]
else:
image_data = [(None, '玩家1'), (blackch, '玩家2')]
# 创建图像
for i, (image, text) in enumerate(image_data):
id = canvas.create_image(*image_positions[i], image=photos1, anchor=W)
self.PicLocIds.append(id) # 保存图像id
id = canvas.create_image(*image_positions[i], image=image, anchor=W)
self.PicLocIds.append(id)
id = canvas.create_text(image_positions[i][0] + 50, 150, text=text, **text_options)
self.PicLocIds.append(id)
canvas.update()
def playing(self, Chess_Mode, root, canvas, blackch, whitech, photos1, photos2):
if Chess_Mode == 1:
self.myColor = 2 # 先手玩家选择的棋子颜色
self.player2Color = 1 # 后手玩家选择的棋子颜色
# print("self.player2Color set", self.player2Color)
self.player = 1
self.player2 = 0
self.winFlag = 0
self.curLocation(canvas, 1, 1, 1, blackch, whitech, photos1, photos2)
elif Chess_Mode == 2:
self.myColor = 1 # 先手玩家选择的棋子颜色
self.player2Color = 2 # 后手玩家选择的棋子颜色
self.chessData[9][9]['Cstate'] = 2
oval = canvas.create_image(9*36.8 + 41 - 14, 9*34.6 + 20, image=blackch, anchor=W)
self.Chessimg[9][9] = oval
xregretFLAG[self.currentStep] = 9
yregretFLAG[self.currentStep] = 9
# print("self.player2Color set", self.player2Color)
self.player = 1 # 玩家下棋标志置0
self.player2 = 0 # 电脑下棋标志置1
self.currentStep += 1
self.winFlag = 0
self.chessData[9][9]['Cstep'] = self.currentStep
a = max(abs(9 - 9), abs(9 - 9)) # 计算该点到中心的最大的距离
self.depth = max(self.depth, a) # 不断更新Depth的值
self.curLocation(canvas, 1, 0, 2, blackch, whitech, photos1, photos2)
elif Chess_Mode == 0:
self.myColor = 2 # 先手玩家选择的棋子颜色
self.player2Color = 1 # 后手玩家选择的棋子颜色
print("self.player2Color set", self.player2Color)
self.player = 1
self.player2 = 0
self.winFlag = 0
self.curLocation(canvas, 1, 1, 1, blackch, whitech, photos1, photos2)
# def playGameBlack(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2):
# if self.winFlag == 0 and self.player == 1 and self.computer == 0 and self.currentStep % 2 == 0:
# # 判断玩家点击的位置是否可以落子,并落子
# if self.playerLocation(playerx, playery, canvas, blackch, whitech):
# # 如果使用了落子建议,则删除掉所画的落子点
# for i in self.OvaloneNew:
# canvas.delete(i)
# # 设置右上方面板当前落子方状态显示
# self.curLocation(canvas, 0, 1, 2, blackch, whitech, photos1, photos2)
# # 判断此次落子是否结束游戏
# self.Gameover = self.chessCheck()
# root.update()
# if self.winFlag == 0 and self.player == 0 and self.computer == 1 and self.currentStep % 2 != 0:
# root.update()
# self.aiLocation(canvas, blackch, whitech)
# self.Gameover = self.chessCheck()
# self.curLocation(canvas, 1, 0, 1, blackch, whitech, photos1, photos2)
#
# root.update()
# if self.winFlag == 1:
# self.resultshow(root, canvas, whitech, blackch)
# root.update()
#
# def playGameWhite(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2):
# if self.winFlag == 0 and self.player == 1 and self.computer == 0 and self.currentStep % 2 == 1:
# if self.playerLocation(playerx, playery, canvas, blackch, whitech):
# # if self.OvaloneNew != 0:
# # print(self.Ovalone)
# # 如果使用了落子建议,则删除掉所画的落子点
# for i in self.OvaloneNew:
# canvas.delete(i)
# self.curLocation(canvas, 0, 1, 1, blackch, whitech, photos1, photos2)
# self.Gameover = self.chessCheck()
# if self.winFlag == 0 and self.player == 0 and self.computer == 1:
# root.update()
# self.aiLocation(canvas, blackch, whitech)
# self.curLocation(canvas, 1, 0, 2, blackch, whitech, photos1, photos2)
# self.Gameover = self.chessCheck()
# if self.winFlag == 1:
# self.resultshow(root, canvas, whitech, blackch)
# root.update()
#
#
# def doublePeople(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2):
# if self.winFlag == 0:
# if self.player == 1 and self.player2 == 0 and self.currentStep % 2 == 0:
# if self.playerLocation(playerx, playery, canvas, blackch, whitech):
# for i in self.OvaloneNew:
# canvas.delete(i)
# self.player2 = 1
# self.Gameover = self.chessCheck()
# self.curLocation(canvas, 0, 0, 2, blackch, whitech, photos1, photos2)
# if self.winFlag == 1:
# self.resultshow(root, canvas, whitech, blackch)
# root.update()
# elif self.player2 == 1 and self.player == 0 and self.currentStep % 2 != 0:
# if self.playerLocation(playerx, playery, canvas, blackch, whitech):
# for i in self.OvaloneNew:
# canvas.delete(i)
# self.player = 1
# self.player2 = 0
# self.curLocation(canvas, 1, 1, 1, blackch, whitech, photos1, photos2)
# self.Gameover = self.chessCheck()
# if self.winFlag == 1:
# self.resultshow(root, canvas, whitech, blackch)
# root.update()
# 返回一个位置数组
def returnPostion(self, Depth, computercolor):
time.sleep(0.5)
self.newCount = 0
self.maxScore = 0
self.counts = 0
pos = [[0 for y in range(2)] for x in range(10)]
evaFLAG = 0
position = [0, 0] # 初始化位置坐标数组
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if 0 <= i < 19 and 0 <= j < 19:
if self.chessData[i][j]['Cstate'] == 0:
self.score[i][j] = self.countScore(i, j, computercolor)
self.newCount += 1
if self.score[i][j] > 0:
self.counts += 1
if self.maxScore < self.score[i][j]:
self.maxScore = self.score[i][j] # 记录当前棋盘分数的最大值
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if self.chessData[i][j]['Cstate'] != 0:
self.score[i][j] = self.chessData[i][j]['Cstate']
if i < 19 and j < 19 and self.score[i][j] == self.maxScore and self.chessData[i][j]['Cstate'] == 0:
pos[evaFLAG][0] = i
pos[evaFLAG][1] = j
evaFLAG += 1
return pos
# 返回建议落子点的位置和原因
def returnPostionNew(self, Depth, computercolor):
Depth = 8
# depth = 2
time.sleep(0.5)
self.newCount = 0
self.maxScore = 0
self.counts = 0
tempPos = []
tempVal = []
Pos_get = []
pos = [[0 for y in range(2)] for x in range(100)]
evaFLAG = 0
position = [0, 0] # 初始化位置坐标数组
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if 0 <= i < 19 and 0 <= j < 19:
if self.chessData[i][j]['Cstate'] == 0:
self.score[i][j], message = self.countScore(i, j, computercolor) # 计算点的得分
self.newCount += 1
if self.score[i][j] > 0:
self.counts += 1
if self.maxScore < self.score[i][j]:
self.maxScore = self.score[i][j] # 记录当前棋盘分数的最大值
self.maxScorePos = (i, j)
score, message = self.countScore(self.maxScorePos[0], self.maxScorePos[1], computercolor) # 计算点的得分
# print(self.maxScorePos)
for i in range(8 - Depth, 11 + Depth):
for j in range(8 - Depth, 11 + Depth):
if self.chessData[i][j]['Cstate'] != 0:
self.score[i][j] = self.chessData[i][j]['Cstate']
if i < 19 and j < 19 and self.score[i][j] >= self.maxScore - 100 and self.chessData[i][j][
'Cstate'] == 0:
pos[evaFLAG][0] = i
pos[evaFLAG][1] = j
tempPos.append([i, j])
tempVal.append(self.score[i][j])
evaFLAG += 1
# print('\n'.join([' '.join([f'{item:4}' for item in row]) for row in self.score]))
# print(pos)
sorted_id = sorted(range(len(tempVal)), key=lambda k: tempVal[k], reverse=True)
for i in range(min(5,evaFLAG)):
Pos_get.append(tempPos[sorted_id[i]])
return Pos_get, message
# return pos[:5], message