基于Python的五子棋人机对战 您所在的位置:网站首页 switchnba2k21怎么双人对战 基于Python的五子棋人机对战

基于Python的五子棋人机对战

2024-01-20 15:48| 来源: 网络整理| 查看: 265

文章目录 人机对战计算机算法源码运行结果引用

人机对战

在之前的博文基于tkinter的五子棋游戏中使用tkinter做了一个简单的五子棋游戏,只能实现人人对战,后来想着加上人机对战的功能。 不过,最初想想还是挺麻烦的,计算机怎么评估当前的棋局,找到最佳或者较佳的落子点呢,脑子真是越来越不灵光了。站在巨人的肩膀上,科学技术才在这几百年发展的如此迅速,先看看别人怎么做的吧,果然别人实现起来也就那么几行代码,真是惭愧啊,也感谢这个开源的时代,让我们可以站得更高,看得更远。

计算机算法

计算机根据黑白双方现有落子情况进行棋局评估,给出各空白落子点处的分数。五子棋的几种基本棋形包括连五,活四,冲四,活三,眠三,活二,眠二等,不同的棋形打不同的分数。这个分数不但要考虑到了己方的棋子,还要考虑对方的局势,即要分别给双方打分,并求和,这样就兼具了攻击和防守的能力。不过,这里算法上与原算法相比略去一部分,这大概也导致了这个计算机有点傻😂 对于空位的遍历也是很费资源的,所以这里参考了引用博文中做法,仅遍历了已有棋子周边的空位。

源码

保留了原程序的架构,有些地方又偷懒,所以代码有点乱

from tkinter import * import random offset = [(1, 0), (0, 1), (1, 1), (1, -1)] class GoBang(): def __int__(self): self.window = Tk() self.window.title("五子棋") self.window.iconbitmap('./gobang.ico') self.window.geometry("500x560") self.window.canvas = Canvas(self.window, width=480, height=480, bg='peachpuff') self.window.canvas.pack() for num in range(1, 16): if num == 1 or num == 15: self.window.canvas.create_line(num * 30, 30, num * 30, 450, width=2) else: self.window.canvas.create_line(num * 30, 30, num * 30, 450, width=1) for num in range(1, 16): if num == 1 or num == 15: self.window.canvas.create_line(30, num * 30, 450, num * 30, width=2) else: self.window.canvas.create_line(30, num * 30, 450, num * 30, width=1) self.window.canvas.create_oval(8 * 30 - 2, 8 * 30 - 2, 8 * 30 + 2, 8 * 30 + 2, fill='black') self.window.canvas.create_oval(5 * 30 - 2, 5 * 30 - 2, 5 * 30 + 2, 5 * 30 + 2, fill='black') self.window.canvas.create_oval(5 * 30 - 2, 11 * 30 - 2, 5 * 30 + 2, 11 * 30 + 2, fill='black') self.window.canvas.create_oval(11 * 30 - 2, 5 * 30 - 2, 11 * 30 + 2, 5 * 30 + 2, fill='black') self.window.canvas.create_oval(11 * 30 - 2, 11 * 30 - 2, 11 * 30 + 2, 11 * 30 + 2, fill='black') self.startBtn = Button(self.window, text='Start', bg="DeepSkyBlue", width=8, height=1, command=self.chessGo) self.quitBtn = Button(self.window, text='Quit', bg="OrangeRed", width=8, height=1, command=self.window.quit) self.withDrawBtn = Button(self.window, text='Withdraw', bg="cyan", width=8, height=1, command=self.withDraw) self.startBtn.place(relx=0.2, rely=0.89) self.quitBtn.place(relx=0.6, rely=0.89) self.withDrawBtn.place(relx=0.4, rely=0.89) self.game_print = StringVar() self.labelInfo = Label(self.window, width=12, textvariable=self.game_print, font=("Arial", 10, "bold"), justify="center") self.labelInfo.place(relx=0.36, rely=0.95) self.window.canvas.bind("", self.place) self.game_print.set("请开始新局") self.chess = [([0] * 15) for i in range(15)] # 悔棋用的顺序列表 self.order = [] # 棋子颜色 self.color_count = 0 self.color = 'black' self.flag_win = 0 self.flag_go = 0 self.window.mainloop() def chessGo(self): if self.startBtn['text'] == "Start": # self.flag_go = 1 self.startBtn['text'] = "Going" self.game_print.set('请black落子') self.labelInfo['fg'] = 'black' elif self.startBtn['text'] == "New": self.startBtn['text'] = "Start" self.newGame() def newGame(self): self.window.canvas.delete("chessman") self.chess = [([0] * 15) for i in range(15)] self.order = [] self.color_count = 0 self.color = 'black' self.flag_win = 0 self.flag_go = 0 self.game_print.set('请开始新局') self.labelInfo['fg'] = 'black' def withDraw(self): if len(self.order) == 0 or self.flag_win == 1: self.game_print.set("Can't Withdraw") self.labelInfo['fg'] = 'sandybrown' return else: self.window.canvas.delete("chessman") # add for machine xylist = self.order.pop() self.chess[xylist[0]][xylist[1]] = 0 ##### xylist = self.order.pop() self.chess[xylist[0]][xylist[1]] = 0 self.color_count = 0 for xylist in self.order: y = xylist[0] x = xylist[1] if self.color_count == 0: self.chess[y][x] = 1 self.color = 'black' elif self.color_count == 1: self.chess[y][x] = 2 self.color = 'white' self.color_count = 1 - self.color_count self.window.canvas.create_oval((x + 1) * 30 - 12, (y + 1) * 30 - 12, (x + 1) * 30 + 12, (y + 1) * 30 + 12, fill=self.color, tags="chessman") if self.color_count: self.color = 'white' else: self.color = 'black' self.game_print.set("请" + self.color + "落子") self.labelInfo['fg'] = 'black' def place(self, event): if (self.flag_win == 0 and self.flag_go == 1): print("enter place") x, y = event.x, event.y x = round(x / 30 - 1) y = round(y / 30 - 1) if x 14 or y 14: # tkinter.messagebox.INFO('提示', '请在棋盘上落子!') self.game_print.set('越界落子!') self.labelInfo['fg'] = "darkorange" return # add for machine 221109 self.color_count = 0 if self.chess[y][x] == 0: print("enter paint oval") if self.color_count == 0: self.chess[y][x] = 1 self.color = 'black' elif self.color_count == 1: self.chess[y][x] = 2 self.color = 'white' self.color_count = 1 - self.color_count self.window.canvas.create_oval((x + 1) * 30 - 12, (y + 1) * 30 - 12, (x + 1) * 30 + 12, (y + 1) * 30 + 12, fill=self.color, tags="chessman") self.order.append([y, x]) else: # tkinter.messagebox.INFO('提示', '此处已有棋子!') self.game_print.set('请别处落子!') self.labelInfo['fg'] = "darkorange" return if self.win(x, y): self.flag_win = 1 self.startBtn['text'] = "New" if self.color_count == 1: self.color = 'black' else: self.color = 'white' # self.messagebox.INFO('提示', '白棋胜!') self.game_print.set(self.color + "胜!") self.labelInfo['fg'] = "red" else: if self.color_count: self.color = 'white' else: self.color = 'black' self.game_print.set("请" + self.color + "落子") self.labelInfo['fg'] = "black" point = self.machine_drop() y = point[0] x = point[1] self.chess[y][x] = 2 self.color = 'white' self.color_count = 0 self.window.canvas.create_oval((x + 1) * 30 - 12, (y + 1) * 30 - 12, (x + 1) * 30 + 12, (y + 1) * 30 + 12, fill=self.color, tags="chessman") self.order.append([y, x]) if self.win(x, y): self.flag_win = 1 self.startBtn['text'] = "New" if self.color_count == 1: self.color = 'black' else: self.color = 'white' # self.messagebox.INFO('提示', '白棋胜!') self.game_print.set(self.color + "胜!") self.labelInfo['fg'] = "red" else: if self.color_count: self.color = 'white' else: self.color = 'black' self.game_print.set("请" + self.color + "落子") self.labelInfo['fg'] = "black" def machine_drop(self): _score = 0 point = [-1,-1] for i in range(0,15): for j in range(0,15): if self.can_drop(i,j): score = self.get_point_score(i,j) print(i,j,score) if score > _score: point[0] = i point[1] = j _score = score elif score == _score: r = random.randint(0, 100) if r % 2 == 0: point[0] = i point[1] = j print(point) return point def can_drop(self, y, x): if self.chess[y][x] != 0: return False else: for i in (-1, 0, 1): for j in (-1, 0, 1): if y + i >= 0 and y + i = 0 and x + j


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有