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.chess_state = [[0 for y in range(19)] for x in range(19)] # 15x15的大小,存储棋子的状态,0为没有棋子,1为白色棋子,2为黑色棋子 # self.chess_step = [[0 for y in range(19)] for x in range(19)] # 15x15的大小,存储当前棋子的步骤 self.Currently_step = 0 # 棋子当前进行的步数 self.Chessimg = [[0 for y in range(19)] for x in range(19)] self.Relabel = [[0 for y in range(19)] for x in range(19)] # 复盘的标签 # self.promptBoxFlag = [[[0 for z in range(8)] for y in range(15)] for x in range(15)] self.Score = [[0 for y in range(19)] for x in range(19)] # 初始化计分数组 self.Max_Score = 0 self.Counts = 0 self.New_count = 0 self.Ovalone = 0 # 代表棋子 self.Ovalone_new = [] self.WinFLAG = 0 # 判断是否取得胜利 self.Gameover = 0 # 判断游戏是否结束 self.Depth = 0 # 搜索的深度 self.player = 0 # 轮到下棋的标志,1=下,0=不下 self.computer = 0 # 轮到下棋的标志,1=下,0=不下 self.Current_Player = 1 # (=1,黑方;=2,白方) self.myColor = 0 # 玩家选择的棋子颜色 self.computercolor = 0 # 电脑的棋子颜色 self.Chess_Mode = 3 # 对弈方式标志 Chess_Mode(=0,人-人对弈; =1, 人-机白对弈; =2,机黑-人对弈, =4,测试模式) self.player2color = 0 # 玩家2的棋子颜色 self.showHistory = False # 当为False时,不展示下棋的步骤,当为True时展示下棋的步骤 self.Max_Score_pos = () # self.choice = 0 def game_end(self): if self.Gameover == 1 or self.WinFLAG == 1: return True else: return False # 计算某个位置得分 def count_Score(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 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 return_chess(self, Depth, computercolor): time.sleep(0.5) self.New_count = 0 self.Max_Score = 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.count_Score(i, j, computercolor) self.New_count += 1 if self.Score[i][j] > 0: self.Counts += 1 if self.Max_Score < self.Score[i][j]: self.Max_Score = 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.Max_Score 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 return_chess_new(self, Depth, computercolor): time.sleep(0.5) self.New_count = 0 self.Max_Score = 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.count_Score(i, j, computercolor) self.New_count += 1 if self.Score[i][j] > 0: self.Counts += 1 if self.Max_Score < self.Score[i][j]: self.Max_Score = 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.Max_Score - 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 player_location(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.Currently_step) return self.make_move(pointi, pointj, canvas, blackch, whitech) # print("2:%d" % self.Currently_step) return False def get_player_move_location_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.Currently_step) return self.make_move(pointi, pointj, canvas, blackch, whitech),pointi,pointj # print("2:%d" % self.Currently_step) return self.make_move(pointi, pointj, canvas, blackch, whitech),pointi,pointj # def make_move(self, pointi, pointj, canvas, blackch, whitech): if self.ChessData[pointi][pointj]['Cstate'] == 0 and self.myColor == 2 and self.Currently_step % 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.Currently_step] = pointi yregretFLAG[self.Currently_step] = pointj self.player = 0 # 玩家下棋标志置0 self.computer = 1 # 电脑下棋标志置1 self.Currently_step += 1 self.ChessData[pointi][pointj]['Cstep'] = self.Currently_step a = max(abs(pointi - 9), abs(pointj - 9)) self.Depth = max(self.Depth, a) return True elif (self.ChessData[pointi][pointj]['Cstate'] == 0 and self.myColor == 1 and self.Currently_step % 2 != 0) or \ (self.ChessData[pointi][pointj][ 'Cstate'] == 0 and self.player2color == 1 and self.Currently_step % 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.Currently_step] = pointi yregretFLAG[self.Currently_step] = pointj self.Currently_step += 1 self.player = 0 self.computer = 1 self.ChessData[pointi][pointj]['Cstep'] = self.Currently_step a = max(abs(pointi - 9), abs(pointj - 9)) self.Depth = max(self.Depth, a) return True elif self.ChessData[pointi][pointj]['Cstate'] != 0: return False def get_direction_Score(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 get_point_Score(self, y, x): Score = 0 offset = [(1, 0), (0, 1), (1, 1), (1, -1)] for os in offset: Score += self.get_direction_Score(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.get_point_Score(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 ai_location(self, canvas, blackch, whitech): if self.Depth >= 9: self.Depth = 8 position = self.return_chess(self.Depth, self.computercolor) # 调用估值函数 # position = self.atuoactive() if self.ChessData[position[0]][position[1]]['Cstate'] == 0: # print("3:%d"%self.Currently_step) if self.computercolor == 2 and self.Currently_step % 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=blackch, anchor=W) self.Chessimg[position[0]][position[1]] = oval self.ChessData[position[0]][position[1]]['Cstep'] = self.Currently_step elif self.computercolor == 1 and self.Currently_step % 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=whitech, anchor=W) self.Chessimg[position[0]][position[1]] = oval self.ChessData[position[0]][position[1]]['Cstep'] = self.Currently_step xregretFLAG[self.Currently_step] = position[0] yregretFLAG[self.Currently_step] = position[1] self.player = 1 # 玩家下棋标志置0 self.computer = 0 # 电脑下棋标志置1 self.Currently_step += 1 self.ChessData[position[0]][position[1]]['Cstep'] = self.Currently_step a = max(abs(position[0] - 9), abs(position[1] - 9)) # 计算该点到中心的最大的距离 self.Depth = max(self.Depth, a) # 不断更新Depth的值 # print("4:%d" % self.Currently_step) 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: 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) elif 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 curlocation(self, canvas, player, computer, Current_Player, blackch, whitech, photos1, photos2): text_options = {'fill': 'white', 'font': 'Arial,9', 'anchor': W} image_positions = [(750, 145), (870, 145)] if player == 1 and computer == 0: if Current_Player == 1: image_data = [(blackch, '玩家'), (whitech, '电脑')] else: image_data = [(whitech, '玩家'), (blackch, '电脑')] elif player == 0 and computer == 1: if Current_Player == 1: image_data = [(blackch, '玩家'), (whitech, '电脑')] else: image_data = [(whitech, '玩家'), (blackch, '电脑')] elif player == 1 and computer == 1: image_data = [(blackch, '玩家1'), (whitech, '玩家2')] else: image_data = [(blackch, '玩家1'), (whitech, '玩家2')] for i, (image, text) in enumerate(image_data): canvas.create_image(*image_positions[i], image=photos1, anchor=W) canvas.create_image(*image_positions[i], image=image, anchor=W) canvas.create_text(image_positions[i][0] + 50, 150, text=text, **text_options) canvas.update() def clear_location(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[0] + 50, 150)) canvas.update() def playing(self, Chess_Mode, root, canvas, blackch, whitech, photos1, photos2): if Chess_Mode == 1: self.myColor = 2 # 玩家选择的棋子颜色 黑 self.computercolor = 1 # 电脑的棋子颜色 白 self.player = 1 self.computer = 0 self.WinFLAG = 0 self.curlocation(canvas, 1, 0, 1, blackch, whitech, photos1, photos2) elif Chess_Mode == 2: self.myColor = 1 # 玩家选择的棋子颜色 self.computercolor = 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.Currently_step] = 9 yregretFLAG[self.Currently_step] = 9 self.player = 1 # 玩家下棋标志置0 self.computer = 0 # 电脑下棋标志置1 self.Currently_step += 1 self.WinFLAG = 0 self.ChessData[9][9]['Cstep'] = self.Currently_step 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 # 后手玩家选择的棋子颜色 self.player = 1 self.player2 = 0 self.WinFLAG = 0 self.curlocation(canvas, 1, 1, 1, blackch, whitech, photos1, photos2) # 由于在存储的棋局中都是Mode1,这里先按照Mode1实现功能 elif Chess_Mode == 4: self.myColor = 2 # 玩家选择的棋子颜色 黑 self.computercolor = 1 # 电脑的棋子颜色 白 self.player = 1 self.computer = 0 self.WinFLAG = 0 self.curlocation(canvas, 1, 0, 1, blackch, whitech, photos1, photos2) def playgame_black(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2): if self.WinFLAG == 0 and self.player == 1 and self.computer == 0 and self.Currently_step % 2 == 0: if self.player_location(playerx, playery, canvas, blackch, whitech): if self.Ovalone_new != 0: for i in self.Ovalone_new: 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.Currently_step % 2 != 0: root.update() self.ai_location(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 playgame_white(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2): if self.WinFLAG == 0 and self.player == 1 and self.computer == 0 and self.Currently_step % 2 == 1: if self.player_location(playerx, playery, canvas, blackch, whitech): if self.Ovalone_new != 0: # print(self.Ovalone) for i in self.Ovalone_new: 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.ai_location(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.Currently_step % 2 == 0: if self.player_location(playerx, playery, canvas, blackch, whitech): if self.Ovalone != 0: canvas.delete(self.Ovalone) 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.Currently_step % 2 != 0: if self.player_location(playerx, playery, canvas, blackch, whitech): if self.Ovalone != 0: canvas.delete(self.Ovalone) 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 studenttest_playgame_white(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2): if self.WinFLAG == 0 and self.player == 1 and self.computer == 0 and self.Currently_step % 2 == 1: flag,x,y = self.get_player_move_location_xy(playerx, playery, canvas, blackch, whitech) if flag: if self.Ovalone_new != 0: # print(self.Ovalone) for i in self.Ovalone_new: 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.ai_location(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() # 返回xy坐标 return x,y def studenttest_playgame_black(self, root, playerx, playery, canvas, blackch, whitech, result, photos1, photos2): if self.WinFLAG == 0 and self.player == 1 and self.computer == 0 and self.Currently_step % 2 == 0: flag,x,y = self.get_player_move_location_xy(playerx, playery, canvas, blackch, whitech) # print("get_player_move_location_xy:flag,x,y",flag,x,y) if flag: if self.Ovalone_new != 0: for i in self.Ovalone_new: 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.Currently_step % 2 != 0: root.update() self.ai_location(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() return x,y # 返回一个位置数组 def return_postion(self, Depth, computercolor): time.sleep(0.5) self.New_count = 0 self.Max_Score = 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.count_Score(i, j, computercolor) self.New_count += 1 if self.Score[i][j] > 0: self.Counts += 1 if self.Max_Score < self.Score[i][j]: self.Max_Score = 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.Max_Score and self.ChessData[i][j]['Cstate'] == 0: pos[evaFLAG][0] = i pos[evaFLAG][1] = j evaFLAG += 1 return pos def return_postion_new(self, Depth, computercolor): Depth = 8 # Depth = 2 time.sleep(0.5) self.New_count = 0 self.Max_Score = 0 self.Counts = 0 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.count_Score(i, j, computercolor) # 计算点的得分 self.New_count += 1 if self.Score[i][j] > 0: self.Counts += 1 if self.Max_Score < self.Score[i][j]: self.Max_Score = self.Score[i][j] # 记录当前棋盘分数的最大值 self.Max_Score_pos = (i, j) score, message = self.count_Score(self.Max_Score_pos[0], self.Max_Score_pos[1], computercolor) # 计算点的得分 # print(self.Max_Score_pos) 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.Max_Score - 100 and self.ChessData[i][j][ 'Cstate'] == 0: pos[evaFLAG][0] = i pos[evaFLAG][1] = j evaFLAG += 1 # print('\n'.join([' '.join([f'{item:4}' for item in row]) for row in self.Score])) return pos, message # 获得当前一步的最大估值落子点和落子原因以及除了最大值以外估值最高的4个落子点 def return_postion_test_module(self, Depth, computercolor): Depth = 8 # Depth = 2 time.sleep(0.5) self.New_count = 0 self.Max_Score = 0 self.Counts = 0 tempPos = [] tempVal = [] Pos_get = [] pos = [[0 for y in range(2)] for x in range(361)] 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.count_Score(i, j, computercolor) # 计算点的得分 self.New_count += 1 if self.Score[i][j] > 0: self.Counts += 1 if self.Max_Score < self.Score[i][j]: self.Max_Score = self.Score[i][j] # 记录当前棋盘分数的最大值 self.Max_Score_pos = (i, j) score, message = self.count_Score(self.Max_Score_pos[0], self.Max_Score_pos[1], computercolor) # 计算点的得分 # print(self.Max_Score_pos) 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] >= 36 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])) sorted_id = sorted(range(len(tempVal)), key=lambda k: tempVal[k], reverse=True) for i in range(5): Pos_get.append(tempPos[sorted_id[i]]) return Pos_get, message