用 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 功能:引入搜索算法进行人机对战

总结

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

相关推荐
白露秋4829 分钟前
C——五子棋小游戏
c语言·游戏
wgc2k9 小时前
Java游戏服务器开发流水账(5)Spring 在游戏开发中的使用简介
java·服务器·游戏
passionSnail9 小时前
《用MATLAB玩转游戏开发》推箱子游戏的MATLAB趣味实现
开发语言·游戏·matlab
海拥✘1 天前
CodeBuddy终极测评:中国版Cursor的开发革命(含安装指南+HTML游戏实战)
前端·游戏·html
一丝晨光1 天前
数值溢出保护?数值溢出应该是多少?Swift如何让整数计算溢出不抛出异常?类型最大值和最小值?
java·javascript·c++·rust·go·c·swift
monstercl1 天前
游戏资源传输服务器
运维·服务器·游戏
狐凄1 天前
Python实例题:pygame开发打飞机游戏
python·游戏·pygame
陌尘(MoCheeen)2 天前
技术书籍推荐(002)
java·javascript·c++·python·go
Tech Synapse2 天前
Unity ML-Agents实战指南:构建多技能游戏AI训练系统
人工智能·游戏·unity
浮云中的神马-潘帅4 天前
一款独立于游戏外的键盘源按键辅助工具他来了
游戏·计算机外设