# 简易的围棋 **Repository Path**: lwf808/simple-go ## Basic Information - **Project Name**: 简易的围棋 - **Description**: 简易的围棋,实现了围棋下棋、复盘功能,在下棋或者复盘过程中,程序自动进行提子功能。为更易适用于TensorFlow.js等人工智能程序框架,秉持简单易用的原则进行编写。 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 8 - **Forks**: 0 - **Created**: 2022-04-05 - **Last Updated**: 2025-05-22 ## Categories & Tags **Categories**: games **Tags**: None ## README # 简易的围棋 #### 介绍 简易的围棋,实现了围棋下棋、复盘功能,在下棋或者复盘过程中,程序自动进行提子功能。为更易适用于TensorFlow.js等人工智能程序框架,秉持简单易用的原则进行编写。 #### 软件架构 程序以html、bootstrap、jquery和TensorFlow.js作为客户端界面的程序架构,完善界面后,计划后台使用Flask增加numpy、scipy、scikit-learn等进行棋局的局面分析。 #### 安装教程 1. 当前使用浏览器打开既可以使用。 #### 使用说明 1. 浏览器打开后,默认已经进行了开局,可以在直接进行下棋作业。 2. 悔棋可以删除最后下的棋步。 3. 下载棋谱记录,当前下载的是下方日志记录的所有内容。 4. 游戏健康忠告栏,属于日志记录,可以使用上方的下载棋谱记录保存,其右侧记录有网页打开的总计时,以及当前下棋的一方。 显示每5秒更新一次,所以数据显示有所延时,后台的数据保存不受时间影响。 5. 文件栏有三个可以上传的区域,从左到右分别是棋谱、TensorFlow.js用的(模型、权重)文件,其中棋谱域更改后,自动进行复盘。 6. 进行下棋或者复盘后,下方有速览和定速复盘两种功能,其中速览,点击左右两侧的“《“、”》”按步进行浏览,或者拉动中间的进度条进行速览。 7. 定速复盘,右侧为速度控制,计量单位是秒,定速复盘按钮点击后,程序后台按计时间隔进行复盘。复盘过程中可以修改时间,以及速览进度。 8. 右上方的建模和[上传],用于创建TensorFlow.js模型,使用其中一个即可,两个功能相互覆盖模型。 9. 使用[上传]功能,需要首先在下方的文件栏选择模型和权重文件。否则报错。 10. 建模和[上传]当前自动进行训练和预测功能,也可以在下棋过程中按步进行训练和预测。 11. 左上方可以修改网页页面的背景色。 12. 程序在半点和整点进行报警弹窗。 #### 模拟围棋(Go)游戏的基本逻辑,JavaScript 代码 ``` class simpleGo { constructor() { this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"]; this.newWeiQi(); this.goString = { string: [], empty: [] }; } go_handler(item="B[qd]") { var position = item.slice(2, 4); if (this.posColor.hasOwnProperty(position)) { return false; }else{ this.posColor[position] = item[0]; } var del_pos = []; var near_pos = this.near_positions(position); for (var npn in near_pos) { if (this.posColor.hasOwnProperty(near_pos[npn])) { if (this.posColor[near_pos[npn]] != this.posColor[position]) { this.goString = { 'string': [], 'empty': [] }; this.go_string(near_pos[npn]); if (this.goString['empty'].length == 0) { for (var spn in this.goString['string']) { del_pos.includes(this.goString['string'][spn]) || del_pos.push(this.goString['string'][spn]); } } } } } if (del_pos.length == 0) { this.goString = { 'string': [], 'empty': [] }; this.go_string(position); if (this.goString['empty'].length == 0) { delete this.posColor[position]; } else { this.sgf.push(item); this.posColorList.push(JSON.parse(JSON.stringify(this.posColor))); return true; } } else { for (var d_p in del_pos) { delete this.posColor[del_pos[d_p]]; } this.sgf.push(item); this.posColorList.push(JSON.parse(JSON.stringify(this.posColor))); return true; } return false; } go_string(position) { this.goString['string'].push(position); var nPos = this.near_positions(position); for (var np in nPos) { if (this.posColor.hasOwnProperty(nPos[np])) { if (!this.goString['string'].includes(nPos[np]) && this.posColor[nPos[np]] == this.posColor[position]) { this.go_string(nPos[np]); } } else { this.goString['empty'].includes(nPos[np]) || this.goString['empty'].push(nPos[np]); } } } near_positions(position) { var near_pos = []; var row = this.near(position[0]); var col = this.near(position[1]); for (var r in row) { near_pos.push(row[r] + position[1]); } for (var c in col) { near_pos.push(position[0] + col[c]); } return near_pos; } near(char) { switch (char) { case "a": return ["b"]; case "s": return ["r"]; case "b": case "c": case "d": case "e": case "f": case "g": case "h": case "i": case "j": case "k": case "l": case "m": case "n": case "o": case "p": case "q": case "r": default: var pos = this.positions.indexOf(char); return [this.positions[pos - 1], this.positions[pos + 1]]; } } newWeiQi(sgf=[], posColor={}, posColorList=[]){ this.sgf = sgf; this.posColor = posColor; this.posColorList = posColorList; } } ``` #### 模拟围棋(Go)游戏的基本逻辑,Python 代码,分支“python3.tk” ``` class WeiQi: def __init__(self): self.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"] self.newWeiQi() self.__goString = { 'string': set(), 'empty': set() } def go_handler(self, item="B[pd]"): position = item[2:4] if position not in self.posColor: self.posColor[position] = item[0] delPositions = set() for nPos in self.near_positions(position): if nPos in self.posColor and self.posColor[nPos] != self.posColor[position]: self.__goString = { 'string': set(), 'empty': set() } self.go_string(nPos) if len(self.__goString['empty']) == 0: delPositions.update(self.__goString['string']) if len(delPositions) == 0: self.__goString = { 'string': set(), 'empty': set() } self.go_string(position) if len(self.__goString['empty']) == 0: del self.posColor[position] else: self.sgf.append(item) self.posColorList.append(copy.deepcopy(self.posColor)) return True else: for dPos in delPositions: del self.posColor[dPos] self.sgf.append(item) self.posColorList.append(copy.deepcopy(self.posColor)) return True return False def go_string(self, position): self.__goString['string'].add(position) for nPos in self.near_positions(position): if nPos in self.posColor: if nPos not in self.__goString['string'] and self.posColor[nPos] == self.posColor[position]: self.go_string(nPos) else: self.__goString['empty'].update(nPos) def near_positions(self, position): near_pos = set() for r in self.near(position[0]): near_pos.add(r + position[1]) for c in self.near(position[1]): near_pos.add(position[0] + c) return near_pos def near(self, char): match char: case 'a': return ['b'] case 's': return ['r'] case "b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"|"l"|"m"|"n"|"o"|"p"|"q"|"r": pos = self.positions.index(char) return [self.positions[pos - 1], self.positions[pos + 1]] return [] def newWeiQi(self, sgf=[], posColor={}, posColorList=[]): self.sgf = sgf self.posColor = posColor self.posColorList = posColorList ``` #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)