Skip to content

wangdongdongc/Gomoku

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Gomoku 五子棋游戏

使用 Typescript 编写的带有简单 AI 的五子棋小游戏 (无禁手)。

Typescript 是微软的一个开源项目,在 Javascript 现有语法的基础上提供了与 C++、Java 类似的正宗的面向对象与静态类型支持。使用 Visual Studio 或 Visual Studio Code 能够在编译期对代码进行检查,执行安全的重构操作(重命名)。

游戏实现了

  1. 基于 HTML Canvas 元素的界面
  2. 五子棋 AI
  3. 主题切换、查看步数

运行

  • 在线玩
  • 下载源代码,在浏览器中打开 index.html

编译

Typescript(.ts) 源文件需要编译成 Javascript(.js) 才能在浏览器中运行

  1. 安装 npm 包管理器
  2. 进入项目根目录执行 npm install 以安装 Typescript
  3. 安装完成后运行 npm run build 以启动编译 (或 ./node_modules/.bin/tsc --sourcemap, 编译选项见 tsconfig.json)

image

MVC 设计模式

游戏使用 MVC (model-view-controller) 的模式组织程序

对应的源码如下

Model

src/GomokuGame.ts 游戏规则实现
src/Models/GomokuDB.ts 历史记录存取

View

实现 UI

src/Views/ComokuView.ts 游戏视图
src/Views/MenuView.ts 菜单视图
src/Views/DialogView.ts 对话框视图

UI 基于 HTML5 Canvas 实现。Canvas 是 HTML5 的一个元素,它在页面上嵌入一个画布,并使用 Javascript 在上面绘制线条,形状,图像。

image

Controller

src/GomokuViewController.ts

这个控制器同时管理了游戏视图和菜单栏视图,两个视图上发生的事件都交给这一个控制器处理

View 接受用户的在 UI 上进行的操作(鼠标点击,鼠标滑动),将动作发送给 Controller,Controller 处理动作。

例如:View 发现用户点击了 Canvas 元素的xx位置,告诉 Controller ,Controller 告诉 Model 玩家在棋盘中xx处落子,Model 处理落子,发现玩家获胜,告诉 Controller 玩家已获胜,Controller 最后控制 View 显示 “已获胜” 的字样。

AI

游戏自带 AI,能够与玩家进行对战

src/AIs/AIScore.ts 棋型估分
src/AIs/TestAI_2.ts  AI

AI 如何决策

AI 能够看到当前棋盘的棋子分布,就像玩家一样

AI 的决策包含防守和进攻

  1. 防守:当玩家摆出能够危险的棋局时,在危险位置上落子防御。危险的棋局非常复杂,这里仅考虑一些基本的类型。例如:四连、两个三连同时出现。

  2. 进攻:若无危险棋局,一般选择进攻。正如 AI 能够判断玩家可能摆出危险的棋局,AI 也能判断是否可以下出这些攻击力强的棋局。

AI 如何判断棋局

AI 对不同的棋局进行估分,在不同的位置落子能够产生不同的棋局,选取分数最高的棋局落子。

AI 将尝试在棋盘的每一个空位置落子,然后检查上下左右与主对角线副对角线方向有多少个连子,连子的两边是否被堵住,连子中是否有间隔,这这些信息交给一个分值判断函数。 e.g.

//这是一个进行分值判断的函数,它根据连子的个数(line),两侧是否被堵住(block1, block2),给出分数
//note: 这里分数被表示成了一些很形象的变量(oooo)
scoreOfStyle(line: number, block1: boolean, block2: boolean) {
    if (line == 5) return AIScore.ooooo
    if (block1 && block2) return 0
    switch (line) {
        case 4: return (block1 || block2) ? AIScore.Ioooo : AIScore.oooo
        case 3: return (block1 || block2) ? AIScore.Iooo : AIScore.ooo
        case 2: return (block1 || block2) ? AIScore.Ioo : AIScore.oo
        case 1: return 0
    }
}

这种判断棋型的方法能够判断多个 ooo 交叉的情况。因为不同的方向的棋局所产生的分数是可以叠加的。例如:检查水平方向时,发现了一个 ooo,检查斜方向时,又发现了 |oooo,这样的棋局显然可以获胜,若没有更直接的获胜棋局,AI 应该立刻在这种位置落子。

一些抽象

src/Shapes/ 下存放用于在 Canvas 绘制特定形状的类(如:Circle、Rectangle),这些类包装了 Canvas 的 API,防止 View 中出现大量的 Canvas API。

src/Models/ 下存放供 Model 使用的一些数据结构,用于简化 Model 的代码。

src/Themes/ 下包含了几种棋盘棋子的样式类,用于主题切换