用Go语言写一个简单的扫雷后端实现(第一部分) | 青训营

277 阅读4分钟

在学习了一段时间Go语言后,我在b站上搜到了一些有趣的小实战项目,以下是一个经典游戏扫雷的简单后端代码实现

  • 首先我们要思考扫雷游戏的规则和逻辑,扫雷游戏是一个格子矩阵,其中有些格子被地雷覆盖,玩家需要点击格子来揭开它们。如果玩家揭开的格子是地雷,游戏结束;否则,将显示该格子周围的地雷数量。此外,玩家还可以对疑似地雷的格子插上旗帜。
  • 基于游戏规则和逻辑,需要设计代码结构。我可以创建两个结构体:Game用于表示游戏状态和逻辑,Cell用于表示每个格子的状态和信息,并添加了一些常量来表示游戏状态和格子状态。
// 游戏状态常量
const (
       StatePlaying = "playing"
       StateWin     = "win"
       StateLost    = "lost"
)

// 格子状态常量
const (
       CellCovered  = "covered"
       CellClicked  = "clicked"
       CellFlagged  = "flagged"
       CellQuestion = "question"
)

// 游戏结构体
type Game struct {
       Rows         int        `json:"rows"`
       Cols         int        `json:"cols"`
       NumMines     int        `json:"numMines"`
       MineLocations [][]bool  `json:"-"`
       Board        [][]*Cell `json:"board"`
       State        string     `json:"state"`
}

// 格子结构体
type Cell struct {
       IsMine     bool   `json:"isMine"`
       State      string `json:"state"`
       NumMines   int    `json:"numMines,omitempty"`
       NumFlagged int    `json:"numFlagged,omitempty"`
}
  • 接下来,我们需要编写函数,首先需要实现的是创建游戏和游戏板的函数,创建函数负责根据输入的行数、列数和地雷数量生成一个新的游戏实例,游戏板函数负责初始化游戏板和地雷位置。
// 创建游戏
func createGame(rows, cols, numMines int) *Game {
       mineLocations := make([][]bool, rows)
       for i := range mineLocations {
              mineLocations[i] = make([]bool, cols)
       }

       return &Game{
              Rows:         rows,
              Cols:         cols,
              NumMines:     numMines,
              MineLocations: mineLocations,
              Board:        createBoard(rows, cols),
              State:        StatePlaying,
       }
}

// 创建游戏板
func createBoard(rows, cols int) [][]*Cell {
       board := make([][]*Cell, rows)
       for i := range board {
              board[i] = make([]*Cell, cols)
       }
       
       return board
}
  • 我发现笔记要求是代码文字比不能超过70%,所以只能分成多个部分发布笔记,后面从头写一些课程内容,首先是Go语言的依赖管理。

GoPath

GOPATH是Go语言中使用的一个环境变量,它使用绝对路径提供项目的工作目录。工作目录是一个工程开发的相对参考目录,好比当你要在公司编写一套服务器代码,你的工位所包含的桌面、计算机及椅子就是你的工作区。如果不使用工作目录的概念,在多人开发时,每个人有一套自己的目录结构,读取配置文件的位置不统一,输出的二进制运行文件也不统一,这样会导致开发的标准不统一,影响开发效率。GOPATH适合处理大量Go语言源码、多个包组合而成的复杂工程 。

GOPATH在Go 1.5之前是用于存放Go代码的目录。在Go 1.5之前,Go语言使用GOPATH来管理依赖包,但是这种方式有很多缺点,比如:不同项目之间的依赖包版本不一致、路径不统一等等。为了解决这些问题,Go语言引入了Go Vendor机制,它是一种将依赖包放在项目内部的机制。而在Go 1.5之后引入了Go Module机制,它是一种官方推荐的依赖管理工具。

Go Vendor

Go Vendor是Go语言中使用的一种依赖管理机制,它的原理是将依赖的包,特指外部包,复制到当前工程下的vendor目录下,这样go build的时候,go会优先从vendor目录寻找依赖包。这种方式适合处理大量Go语言源码、多个包组合而成的复杂工程。

Go Module

  • Go Module是Go语言中的一种包管理机制,可以帮助开发者有效地管理项目的依赖库和版本,提高开发效率。使用Go Module进行包管理,需要在项目根目录下创建一个go.mod文件,该文件用于定义项目的模块路径和依赖项要求。Go Module支持多个模块,每个模块对应一个代码库,模块之间的依赖关系可以通过Go Module管理。相比于Go Vendor,Go Module更加现代化、易用、安全、可靠。
  • golang 提供了go mod命令来管理包,go.mod文件一旦创建后,它的内容将会被go toolchain掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。

go.mod 提供了module, require、replace和exclude 四个命令

  1. module 语句指定包的名字(路径)
  2. require 语句指定的依赖项模块
  3. replace 语句可以替换依赖项模块
  4. exclude 语句可以忽略依赖项模块
  • 在项目根目录下创建一个go.mod文件,该文件用于定义项目的模块路径和依赖项要求。可以使用以下命令创建一个新的go.mod文件:go mod init <module-name>。要将项目托管在GitHub上,可以在GitHub上创建一个新的仓库,然后将项目上传到该仓库中。之后就可以在代码中导入依赖项来使用Go Module了。