项目简述

五子棋对弈游戏(网站地址:http://120.25.190.60

  • 匹配对战:可能匹配不到真人(等待10s匹配到人机);

  • 邀请对战功能;

  • 观战功能;

匹配对战的流程

图片

1、客户端向服务器发起ws请求,建立链接;

2、前端点击【开始匹配】,将会向后端(backed)发送以下玩家信息

1
2
3
4
{
user_id: 1, // 玩家id
user_codeid: 7, // 使用的codeid[若为亲自出战,则不传该参数]
}

3、后端(backed)根据玩家id到数据库查到其战斗力,将玩家信息(如下)发送至匹配服务(matching_service)

1
2
3
4
5
{
user_id: 1, // 用户id
user_codeid: 7, // 使用的codeid
rating: 9999, // 战斗力
}

4、匹配服务根据玩家等待的时间和战斗力,完成对局匹配,将以下匹配信息返回后端(backed)

1
2
3
4
5
6
{
black_id: 1, //黑子玩家id
black_codeid: -1, //说明是亲自出马
white_id: 2, // 白子玩家id
white_codeid: 9, // 说明是派AI出战
}

5、后端(backed)收到匹配消息,执行startGame()函数开启本次对局(新建一个Game线程管理本次对局)。黑子先手,每个玩家每回合拥有30秒思考时间。
假设有当前有一个对局

  • 5.1 当收到落子消息(判断该名玩家是否具有落子权+忽略非法操作)之后,落子权转移至对手手中,然后通过websocket向前端两名玩家发送本次落子消息。
    • 5.1.1 注:若具备落子权的玩家选择的是AI出战,那么还会发送一份如下对局信息给5.2代码执行服务(code_running_service):
    • 5.1.2 注:若有一方连成5子则对局结束,发送对局结果给对战双方,并将本次对局记录存储至数据库。
1
2
3
4
5
6
{
user_id: 1, //玩家id
user_code: "public static int[] userFunction(int[][] g, Integer color ) {......}", //玩家编写的代码
map_message: "", //地图信息
opponent_id: 2 //对手id
}

然后,开始30秒倒计时,若拥有落子权力的玩家在该时间段内没有输入(不管是前端没有落子或AI执行异常导致没有返回x,y坐标),则会判这名玩家输,向对战双方发生结果,并保存记录到数据库中。

  • 5.2 代码执行服务(code_running_service)接收到对局信息,将其放入消费队列中等待消费者消费。
    消费的过程: 会新建一个线程,去尝试编译执行用户编写的代码user_code:
    • 如果失败/异常:忽略;
    • 如果成功:应该得到返回结果 int[2] (代表x坐标和y坐标),此时向后端(backed)返回落子消息,回到步骤5.1。
1
2
3
4
5
6
{
user_id: 1, //玩家id
x: 6, //落子的x坐标
y: 6, // 落子的y坐标
opponent_id: 2 //对手id
}