Skip to content

userpro/CodeFight

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 

Repository files navigation

CodeFight

注意

因文档更新并不十分及时, 若文档与代码有出入, 以代码为准. (咕咕咕咕...

游戏介绍

简单的代码对战游戏, 受到 generals.io 以及知乎上 Color Fight 启发 . Go fight!

游戏中兵力即 Cell 中的数值, 两个不同阵营的兵力交战时, 结果为相减 .

游戏中有 兵营(barback)、据点(portal)、障碍物(barrier)、基地(base) 四种建筑物

兵营: 间隔较小轮数增加在其中的兵力

据点: 提升据点内兵力的实力 (即在其中的兵力相当于乘以一个因子, 出了据点即失效)

障碍物: 无法通过与摧毁之地

基地: 每个玩家仅一个, 被摧毁即失败. (被占领方所拥有的Cell会归占领方所有)

如何测试/运行

依赖
都为最新版
go:(可能需要翻墙)
	go get github.com/labstack/echo
	go get github.com/go-sql-driver/mysql
	go get golang.org/x/net/websocket
python:
	pip3 install requests
 	(如果想用Chrome打开前端展示页面, Windows可能需要设置代码里 gamePlayer1.py:11 chromepath变量的值)
数据库

go/src 目录下新建文件 config.txt 内容格式为 dbuser;dbpass;dbtablename;web_server_port (⚠️: 第四项是 web 服务器的监听端口)

数据库结构:
	表名 userinfo
	id	 		    int(11) 		AUTO_INCREMENT
	username		text	 		utf8mb4_unicode_ci
	password		text	 		utf8mb4_unicode_ci
	email			text	 		utf8mb4_unicode_ci
	status			int(11)  		0->未审核 1->审核通过
	CreateAt		datetime 		CURRENT_TIMESTAMP
	UpdateAt		datetime		CURRENT_TIMESTAMP		on update CURRENT_TIMESTAMP
命令
git clone https://github.com/userpro/CodeFight.git
cd CodeFight/go/src
go run main.go
cd example
python3 cleaner.py
# 如果需要启动多个 player 测试, 修改 cleaner.py:6 的 playernum 数量和 cleaner2.py:14 的roomtoken(需要先启动 cleaner.py 获得)

如何编写自己的Bot

参考 go/src/example/CodeWar/Utils.py 简单将API封装了一个 class , 简单的主体框架可参考 go/src/example/template.py , 也可以参考本人写的一个智障障bot go/src/example/cleaner.py (cleaner2.py是为了演示对战)

更多游戏环境参数的设置在 go/src/fight/config.go

一些建议

如果基于 go/src/example/CodeWar/Utils.py 开发bot, 请多留意源码中的注释, 欢迎对其进行二次开发.

维护一个自己的map, 定期query来更新自己的map. 在对战过程中, 你可能会丢失当前Cell, 这时候需要map来寻找下一个可move的Cell.

Query 策略和 Move 策略可以分开, 以免出现激烈对战的时候, bot因为丢失Cell而策略失效. (由于query只能查询自己拥有的Cell周围的情况)

当出现bot策略失效时, 可以直接重启bot程序, 支持断线重连.

Map

地图分两层 m1, m2 每个格子就叫Cell吧. (坐标均从左上角开始 包括返回值)

m1存放Cell数值

m2 存放Cell类型 (低8位有效)

对于m2:

/* 
地形 Cell Type
每个Cell Type唯一 不会重叠
*/
_space_   = 0x00 // 000- ----  空地
_base_    = 0x20 // 001- ----  基地(一个玩家仅一个, 即初始位置)  
_barback_ = 0x40 // 010- ----  军营(一个地图有随机个, 需要抢占, 每回合可加一个单位兵力)
_portal_  = 0x60 // 011- ----  据点(一个地图有随机个, 需要抢占, 兵力在里面可提高防御力)
_barrier_ = 0x80 // 100- ----  障碍(不可经过, 不可占领)

/* 阵营 User Id */
_system_  = 0x00 // ---0 0000  地图默认id
_visitor_ = 0x01 // ---0 0001  玩家默认id(加入游戏后, 玩家id会从此开始往后递增分配, 每个玩家id唯一)

_user_mask_ = 0x1f // 0001 1111
_type_mask_ = 0xe0 // 1110 0000

HTTP 接口

保证每个返回值都一定会有 message 和 status 两项

无特殊说明 status 返回 1 是成功, 0 是失败. (失败原因在 message 里)

注意: 优先判断 status , 在 status 为 0 时, 其他 json key 不一定存在 ( message 一定存在)

API 一览
e.POST(  "/user", register)
e.GET(   "/user", login   )
e.DELETE("/user", logout  )

e.GET(   "/room", query   )
e.POST(  "/room", join    )
e.PUT(   "/room", move    )
e.DELETE("/room", leave   )
e.GET("/room/start",      isStart)
e.GET("/room/scoreboard", getScoreBoard)
玩家相关
register
名称 说明
功能 注册( register )
请求方法 POST
URL /user
参数 username=XXX&password=XXX&email=XXX
示例 /user?username=hi&password=pro&email=abc@d.com
返回值 {
"message": "XXX",
"status": 1
}
返回值说明 status 为 1 仅表示信息注册成功, 需要审核通过才可以登录.
login
名称 说明
功能 登录 ( login )
请求方法 GET
URL /user
参数 username=XXX&password=XXX
示例 /user?username=hi&password=pro
返回值 {
"usertoken": "XXXX",
"message": "XXX",
"status": 1
}
返回值说明 仅 status 为 1 时, 才会有 usertoken 项, 表示登录成功
当 status 为 2 时, 表示已经登录过, 为在线状态
logout
名称 说明
功能 登出 (logout)
请求方法 DELETE
URL /user
参数 usertoken=XXX
示例 /user?usertoken=XXX
返回值 无 ( HTTP状态码为 NoContent 204 )
房间相关
join
名称 说明
功能 加入或者创建房间 ( join )
请求方法 POST
URL /room
参数 加入房间:
roomtoken=XXX
创建房间:
playernum=X&row=X&col=X
示例 加入房间:
/room?roomtoken=XXXX
创建房间:
/room?playernum=X&row=X&col=X
返回值 {
"id": X,
"usertoken": "XXX",
"roomtoken": "XXX",
"playernum": "XXX",
"row": XX,
"col":XX,
"barback": XX,
"portal": XX,
"barrier":XX,
"message": "XXX",
"status": X
}
返回值说明 返回所加入房间的信息,
id为本局游戏你的id,
barback 兵营数量, portal 据点数量, barrier 障碍物数量
leave
名称 说明
功能 离开房间 (leave)
请求方法 DELETE
URL /room
参数 usertoken=XXX
示例 /room?usertoken=XXX
返回值 {
"message": "XXX",
"status": 1
}
query
名称 说明
功能 查询游戏中对应 Cell 周围的信息 (query)
请求方法 GET
URL /room
参数 {
"usertoken": "XXX",
"roomtoken": "XXX",
"loc": {
"x": 1,
"y": 3
}
}
返回值 {
"eyeshot": {
"m1": [n][n],
"m2": [n][n]
},
"status": 1
}
返回值说明 m1 m2 分别指代地图的两个图层, size 一致,
标示了以 (x, y) 为中心的一个矩阵的视野,
具体矩阵的大小以实际返回为准, 可能会有调整,
对于超出地图的部分的值在m1中以 -1 填充
(⚠️ (x, y)必须为你拥有的Cell)
move
名称 说明
功能 移动地图上指定 Cell 的兵力 (move)
请求方法 PUT
URL /room
参数 {
"usertoken": "XXX",
"roomtoken": "XXX",
"radio": 1,
"direction": 1,
"loc": {
"x": 1,
"y": 2
}
}
参数说明 radio:
1 -> all 调动 (x, y) 所有兵力
2 -> half 调动 (x, y) 1/2的兵力
3 -> quarter 调动 (x, y) 1/4的兵力
direction:
1 -> (x, y) => (x - 1, y)
2 -> (x, y) => (x, y + 1)
3 -> (x, y) => (x + 1, y)
4 -> (x, y) => (x, y - 1)
注意: loc的 (x, y) 必须是属于你的 Cell 才能查询
返回值 {
"length": 1,
"status": 1
}
返回值说明 length 是目前操作序列的长度
isStart
名称 说明
功能 查询游戏是否开始 (isStart)
请求方法 GET
URL /room/start
参数 usertoken=XXX&roomtoken=XXX
示例 /room/start?usertoken=XXX&roomtoken=XXX
返回值 {
"x": 1,
"y": 2,
"row": 30,
"col": 30,
"status": 1
}
返回值说明 x, y 为你初始坐标, 也是你的Base坐标
row, col 即 map 尺寸
getScoreBoard
名称 说明
功能 获取当前房间内所有玩家的得分详情
(getScoreBoard)
请求方法 GET
URL /room/scoreboard
参数 roomtoken=XXX
示例 /room/scoreboard?roomtoken=XXX
返回值 {
"scoreboard": {
"username1": score1,
"username2": score2,
....
},
"status": 1
}
返回值说明 scoreboard 是一个用户名和其得分的键值对
(注意: 请不要频繁调用, 会拖慢游戏进程)

Webscoket

路径: go/src/public/view.html

仅前端展示页面的数据接口, 可定制自己的前端展示页面 (直接替换view.html, 不要改动文件名).

流程如下:

  1. 客户端 send => roomtoken到服务器 (注意 token 是通过模版标签{{.}}嵌入到页面的)
  2. 客户端 receive <=游戏基本信息A( json格式数据)
  3. 客户端 receive <= 每次操作B( json格式数据)
JSON格式

A:

{
    type: 1, // 拉取地图信息 只在最开始出现一次
    value: {
        time: 100, // 游戏总时长 (秒)
        col: 30,
        row: 30,
        m1: [default_row][default_col], // default_row default_col是地图总共大小
        m2: [default_row][default_col], // 但每个游戏实际使用地图的尺寸是之前row col所指定的
        roomtoken: "7ac45ec7b7046c529ac650366700ec50", // roomtoken emmmm 顺便发的
        userinfo: [ // 一个obj数组
            {
                id: 2, // userid 对应地图m2
                name: "hipy", // username
                score: 2, // 每个user占有的格子数量 前端维护接下来的变化
                status: 1 // -1: 离线 0: 等待  1: 游戏中
            }
        ]
    }
}

B: (有三种)

{
    type: 0 // 游戏结束
}
or
{
    type: 2, // 指定点改变
    value: {
        loc: [ // 一个obj数组
            {
                x: 1,
                y: 2,
                m1: 23, // m1[x][y]=23
                m2: 34  // m2[x][y]=34
            },
            {
                x: 2,
                y: 6,
                m1: 3,
                m2: 42
            },
        ]
    }
}
or
{
    type: 3 // 全图m1不为0的Cell加1 (除了barrier)
}
or
{
    type: 4 // 全图特殊cell加1 (军营, 基地)
}

About

Go fight! 一个简单的编写bot对战的游戏

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published