用 Go 写一个可以双人对弈的中国象棋游戏!附完整源码

你有没有想过用 Go 写一个 中国象棋 ?今天就带你一步步从零打造一个支持 双人对战的终端版中国象棋游戏,不仅有完整代码,还有运行效果,适合新手练手,也适合进阶开发者继续拓展为 AI 版或网页版!
文末附完整代码,复制即玩!


为什么选择 Go 实现中国象棋?

  • Go 的语法简单直观,比 Java/Python 更适合写 CLI 游戏
  • 协程天生适合拓展对战、AI 功能
  • 项目易部署、编译快、跨平台运行

功能设计概览

本项目属于入门级版本,核心功能如下:

支持双方轮流走棋

棋盘初始化 + 控制台打印棋盘

使用如 move a0 a1 的命令进行走子

棋子可覆盖吃掉对方(不含规则限制)


中国象棋棋盘和坐标系统

为简化控制台输入,我们把棋盘位置用 a0 ~ i9 表示。例如:

  • a0 是黑方左上角车
  • e9 是红方"帅"所在位置

这个直观坐标方式可以方便命令操作,非常适合终端交互。


完整代码(复制即用)

保存为 main.go,然后 go run main.go

go 复制代码
// main.go
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

type Piece struct {
    Name  string
    Color string // "red" or "black"
}

type Position struct {
    X int
    Y int
}

var board [10][9]*Piece

var posMap = map[string]Position{}

func initBoard() {
    // 初始化坐标映射
    letters := "abcdefghi"
    for i := 0; i < 10; i++ {
        for j := 0; j < 9; j++ {
            key := fmt.Sprintf("%c%d", letters[j], i)
            posMap[key] = Position{i, j}
        }
    }

    // Red side
    board[9][0] = &Piece{"车", "red"}
    board[9][1] = &Piece{"马", "red"}
    board[9][2] = &Piece{"相", "red"}
    board[9][3] = &Piece{"仕", "red"}
    board[9][4] = &Piece{"帅", "red"}
    board[9][5] = &Piece{"仕", "red"}
    board[9][6] = &Piece{"相", "red"}
    board[9][7] = &Piece{"马", "red"}
    board[9][8] = &Piece{"车", "red"}
    board[7][1] = &Piece{"炮", "red"}
    board[7][7] = &Piece{"炮", "red"}
    board[6][0] = &Piece{"兵", "red"}
    board[6][2] = &Piece{"兵", "red"}
    board[6][4] = &Piece{"兵", "red"}
    board[6][6] = &Piece{"兵", "red"}
    board[6][8] = &Piece{"兵", "red"}

    // Black side
    board[0][0] = &Piece{"车", "black"}
    board[0][1] = &Piece{"马", "black"}
    board[0][2] = &Piece{"象", "black"}
    board[0][3] = &Piece{"士", "black"}
    board[0][4] = &Piece{"将", "black"}
    board[0][5] = &Piece{"士", "black"}
    board[0][6] = &Piece{"象", "black"}
    board[0][7] = &Piece{"马", "black"}
    board[0][8] = &Piece{"车", "black"}
    board[2][1] = &Piece{"炮", "black"}
    board[2][7] = &Piece{"炮", "black"}
    board[3][0] = &Piece{"卒", "black"}
    board[3][2] = &Piece{"卒", "black"}
    board[3][4] = &Piece{"卒", "black"}
    board[3][6] = &Piece{"卒", "black"}
    board[3][8] = &Piece{"卒", "black"}
}

func printBoard() {
    fmt.Println("    a   b   c   d   e   f   g   h   i")
    fmt.Println("  +---+---+---+---+---+---+---+---+---+")
    for i, row := range board {
        fmt.Printf("%d |", i)
        for _, cell := range row {
            if cell != nil {
                color := "红"
                if cell.Color == "black" {
                    color = "黑"
                }
                fmt.Printf(" %s%s|", color, cell.Name)
            } else {
                fmt.Print("   |")
            }
        }
        fmt.Println()
        fmt.Println("  +---+---+---+---+---+---+---+---+---+")
    }
}

func movePiece(from, to string, turn string) bool {
    p1, ok1 := posMap[from]
    p2, ok2 := posMap[to]
    if !ok1 || !ok2 {
        fmt.Println("❌ 坐标格式错误,请使用如 a0, b3 格式")
        return false
    }

    piece := board[p1.X][p1.Y]
    if piece == nil {
        fmt.Println("❌ 起始位置没有棋子")
        return false
    }
    if piece.Color != turn {
        fmt.Println("❌ 不能动对方的棋子")
        return false
    }

    board[p2.X][p2.Y] = piece
    board[p1.X][p1.Y] = nil
    return true
}

func main() {
    initBoard()
    scanner := bufio.NewScanner(os.Stdin)
    turn := "red"

    for {
        printBoard()
        fmt.Printf("[%s方] 请输入移动命令,例如 move a0 a1:", turn)
        scanner.Scan()
        line := strings.TrimSpace(scanner.Text())
        tokens := strings.Split(line, " ")
        if len(tokens) != 3 || tokens[0] != "move" {
            fmt.Println("❗️命令格式错误,用法: move <from> <to>")
            continue
        }
        from := tokens[1]
        to := tokens[2]
        if movePiece(from, to, turn) {
            if turn == "red" {
                turn = "black"
            } else {
                turn = "red"
            }
        }
    }
}

运行效果

scss 复制代码
[red方] 请输入移动命令,例如 move a0 a1:
move a0 a1

终端将会展示棋盘更新后的状态,非常适合你和朋友一边敲命令,一边下棋!


进阶玩法(你可以继续做的)

  • • 加入棋子合法性规则(比如兵不能后退)
  • • 判定将死/胜负
  • • 网络版:用 WebSocket 实现远程对弈
  • • 图形界面:Go + Web (Vite/React) 实现在线对弈
  • • AI 功能:引入搜索算法进行人机对战

总结

这个项目虽然简单,却是入门游戏开发、控制台交互、坐标系统建模的好练手案例。如果你也觉得有趣,不妨动手试试!同时也欢迎你把它发给朋友,一起下盘终端象棋

相关推荐
Mgx1 小时前
从“CPU 烧开水“到优雅暂停:Go 里 sync.Cond 的正确打开方式
go
GM_82813 小时前
从0开始在Go当中使用Apache Thrift框架(万字讲解+图文教程+详细代码)
rpc·go·apache·thrift
上海云盾安全满满15 小时前
APP应用怎么选择游戏盾
网络·游戏
棉猴15 小时前
《pygame中Sprite类实现多帧动画》注-通过多张序列帧显示动画2-2
开发语言·python·游戏·游戏程序·pygame
AA陈超17 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P07-08 点击移动
c++·游戏·ue5·游戏引擎·虚幻
Kratos开源社区19 小时前
别卷 LangChain 了!Blades AI 框架让 Go 开发者轻松打造智能体
go·agent·ai编程
Kratos开源社区19 小时前
跟 Blades 学 Agent 设计 - 01 用“提示词链”让你的 AI 助手变身超级特工
llm·go·agent
csd79819 小时前
从原理到实操:ddraw.dll是什么?为何游戏启动时频繁提示“找不到ddraw.dll”?解决思路全解析
游戏·dll修复工具·dll修复·dll丢失·dll缺失
星释20 小时前
Rust 练习册 :Pig Latin与语言游戏
游戏·rust·c#
Nebula_g20 小时前
C语言应用实例:硕鼠游戏,田忌赛马,搬桌子,活动选择(贪心算法)
c语言·开发语言·学习·算法·游戏·贪心算法·初学者