README.md

    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/ 下包含了几种棋盘棋子的样式类,用于主题切换

    项目简介

    1024程序员开源挑战赛

    发行版本

    当前项目没有发行版本

    贡献者 2

    T tuzhaofeng @tuzhaofeng
    6 635677437d755007c09848d3 @635677437d755007c09848d3

    开发语言

    • TypeScript 94.6 %
    • HTML 5.4 %