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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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