From 99d702961f5f1e26da64dc57ca1496ed02db798b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=AE=B6=E6=9C=AA?= <752736341@qq.com> Date: Wed, 16 Oct 2019 17:31:26 +0800 Subject: [PATCH] update hw kp race with both simulated server and strategy --- 19-q3q4/huawei kunpen race/README.md | 16 + .../huawei kunpen race/brifuture/.gitignore | 1 + .../brifuture/client/ballclient/__init__.py | 0 .../client/ballclient/comunicate/__init__.py | 0 .../client/ballclient/comunicate/client.py | 176 ++++++++ .../brifuture/client/ballclient/main.py | 30 ++ .../client/ballclient/service/__init__.py | 0 .../client/ballclient/service/clientteam.py | 153 +++++++ .../client/ballclient/service/constants.py | 4 + .../client/ballclient/service/gameteam.py | 93 ++++ .../client/ballclient/service/mapelement.py | 104 +++++ .../client/ballclient/service/service.py | 122 +++++ .../client/ballclient/service/strategy.py | 422 ++++++++++++++++++ .../brifuture/client/ballclient/util.py | 42 ++ .../brifuture/client/start.bat | 6 + .../brifuture/client/start.sh | 2 + .../brifuture/client/test/__init__.py | 0 .../brifuture/client/test/server.py | 31 ++ .../brifuture/client/test/service.py | 22 + .../brifuture/client/test/test.py | 14 + .../brifuture/client/test/test2.py | 17 + .../brifuture/gameclient.bat | 6 + .../brifuture/gameclient.sh | 4 + .../brifuture/packclient.sh | 2 + .../brifuture/testclient.sh | 3 + .../huawei kunpen race/brifuture/wingame.bat | 4 + 19-q3q4/huawei kunpen race/server/game.csv | 1 + 19-q3q4/huawei kunpen race/server/main.py | 4 + .../huawei kunpen race/server/map_r2m1.txt | 36 ++ .../server/parse_map/compare.txt | 11 + .../server/parse_map/leg_start.txt | 28 ++ .../server/parse_map/mix_replay.txt | 269 +++++++++++ .../server/parse_map/my_parse_map1.txt | 78 ++++ .../server/parse_map/my_parse_map2.txt | 90 ++++ .../server/parse_map/my_replay.txt | 131 ++++++ .../server/parse_map/parse_map.txt | 271 +++++++++++ .../server/parse_map/parse_map1.txt | 77 ++++ .../server/parse_map/parse_map2.txt | 107 +++++ .../server/parse_map/parse_map3.txt | 8 + .../server/parse_map/parse_map4.txt | 78 ++++ .../server/parse_map/parse_replay.txt | 414 +++++++++++++++++ .../server/parse_map/parse_replay2.txt | 303 +++++++++++++ .../server/parse_map/round.txt | 12 + 19-q3q4/huawei kunpen race/server/replay.txt | 23 + .../server/simserver/__init__.py | 16 + .../server/simserver/gamemap.py | 278 ++++++++++++ .../server/simserver/gameteam.py | 113 +++++ .../server/simserver/interface.md | 145 ++++++ .../server/simserver/mapelement.py | 150 +++++++ .../server/simserver/params.py | 0 .../server/simserver/replay.txt | 33 ++ .../server/simserver/server.py | 297 ++++++++++++ .../server/simserver/sockserver.py | 71 +++ .../server/simserver/tracesaver.py | 130 ++++++ .../server/simserver/util.py | 46 ++ .../server/test/test_gamemap.py | 11 + ...241\243\350\257\264\346\230\216-0801.docx" | Bin 0 -> 182283 bytes 57 files changed, 4505 insertions(+) create mode 100644 19-q3q4/huawei kunpen race/README.md create mode 100644 19-q3q4/huawei kunpen race/brifuture/.gitignore create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/__init__.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/__init__.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/client.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/main.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/__init__.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/clientteam.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/constants.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/gameteam.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/mapelement.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/service.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/strategy.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/ballclient/util.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/start.bat create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/start.sh create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/test/__init__.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/test/server.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/test/service.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/test/test.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/client/test/test2.py create mode 100644 19-q3q4/huawei kunpen race/brifuture/gameclient.bat create mode 100644 19-q3q4/huawei kunpen race/brifuture/gameclient.sh create mode 100644 19-q3q4/huawei kunpen race/brifuture/packclient.sh create mode 100644 19-q3q4/huawei kunpen race/brifuture/testclient.sh create mode 100644 19-q3q4/huawei kunpen race/brifuture/wingame.bat create mode 100644 19-q3q4/huawei kunpen race/server/game.csv create mode 100644 19-q3q4/huawei kunpen race/server/main.py create mode 100644 19-q3q4/huawei kunpen race/server/map_r2m1.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/compare.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/leg_start.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/mix_replay.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/my_parse_map1.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/my_parse_map2.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/my_replay.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_map.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_map1.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_map2.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_map3.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_map4.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_replay.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/parse_replay2.txt create mode 100644 19-q3q4/huawei kunpen race/server/parse_map/round.txt create mode 100644 19-q3q4/huawei kunpen race/server/replay.txt create mode 100644 19-q3q4/huawei kunpen race/server/simserver/__init__.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/gamemap.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/gameteam.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/interface.md create mode 100644 19-q3q4/huawei kunpen race/server/simserver/mapelement.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/params.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/replay.txt create mode 100644 19-q3q4/huawei kunpen race/server/simserver/server.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/sockserver.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/tracesaver.py create mode 100644 19-q3q4/huawei kunpen race/server/simserver/util.py create mode 100644 19-q3q4/huawei kunpen race/server/test/test_gamemap.py create mode 100644 "19-q3q4/huawei kunpen race/\345\215\216\344\270\272\344\272\221\351\262\262\351\271\217\345\274\200\345\217\221\350\200\205\345\244\247\350\265\233\350\265\233\351\242\230\346\226\207\346\241\243\350\257\264\346\230\216-0801.docx" diff --git a/19-q3q4/huawei kunpen race/README.md b/19-q3q4/huawei kunpen race/README.md new file mode 100644 index 0000000..cae40f3 --- /dev/null +++ b/19-q3q4/huawei kunpen race/README.md @@ -0,0 +1,16 @@ +## 华为云鲲鹏开发者大赛 + +这是 2019 年参加 “华为云鲲鹏开发者大赛” 时编写的一些代码: + +`brifuture` 文件夹里面是我编写的策略。只编写了一天,效果并不好,还有很多策略没有实现,打不过 AI,最好的成绩只有 300 多分。 + +`server` 文件夹里面是模拟官方的服务器,根据官方的文档说明编写的自定义的服务器,大部分功能都实现了,但仍有小部分的 bug 未解决。 + +**Note:解题策略和服务器仅供参考。** + +----- +官方资源: + +[赛题说明文档](https://bbs.huaweicloud.com/forum/thread-21027-1-1.html) + +[试题工程](https://developer-res-cbc-cn.obs.cn-north-1.myhwclouds.com/competition/%E5%8D%8E%E4%B8%BA%E4%BA%91%E9%B2%B2%E9%B9%8F%E5%BC%80%E5%8F%91%E8%80%85%E5%A4%A7%E8%B5%9B-%E8%AF%95%E9%A2%98%E5%B7%A5%E7%A8%8B0801.zip) \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/.gitignore b/19-q3q4/huawei kunpen race/brifuture/.gitignore new file mode 100644 index 0000000..4c89497 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/.gitignore @@ -0,0 +1 @@ +brifuture.zip diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/__init__.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/__init__.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/client.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/client.py new file mode 100644 index 0000000..fa5e4c1 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/comunicate/client.py @@ -0,0 +1,176 @@ +# encoding:utf8 +''' +客户端对数据的接受和对已生成数据的发送,选手可以不关注此模块 + +''' + +import socket +import json + +from ballclient.service import service +import ballclient.service.constants as constants +import traceback +from ballclient.util import logger +from time import sleep + +_socket = None + +SOCKET_CACHE = 1024 * 20 + + +def try_again(func): + def wraper(*args, **kwargs): + connect_time = 1 + while connect_time <= 300: + try: + return func(*args, **kwargs) + except Exception: + if connect_time % 10 == 0: + logger.warning("connect server failed.....connect_time:%s" % connect_time) + connect_time += 1 + sleep(0.2) + logger.fatal("can not connect with server. %s,%s" % args) + exit(1) + return wraper + +@try_again +def connect_socket(ip=None, port=None): + global _socket + _socket.connect((ip, port)) + + +def start(ip=None, port=None): + global _socket + _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + data = None + try: + connect_socket(ip,port) + + logger.debug("Tri to register.") + register() + while 1: + data = _receive() + if data is None: + break + # logger.debug(data) + + if data['msg_name'] == "round": + message = service.round(data) + send_dict(message) + elif data['msg_name'] == "leg_start": + service.leg_start(data) + elif data['msg_name'] == "leg_end": + service.leg_end(data) + elif data['msg_name'] == "game_over": + service.game_over(data) + logger.info("Server Exit") + return + else: + print("invalid msg_name.") + except socket.error: + print("can not connect with server. %s,%s" % (ip, port)) + exit() + except Exception as e: + print("[start] some error happend: %s. the receive data: %s" % (e, data) ) + traceback.print_exc() + finally: + if _socket: + _socket.close() + logger.info("Client Closed") + + +def register(): + ''' + register logic + :return: + ''' + data = {"msg_name": "registration", + "msg_data": {"team_name": constants.team_name, + "team_id": constants.team_id}} + # print(f"[Register] {data}") + send_dict(data) + + +def send_dict(data): + data_str = json.dumps(data) + _socket.sendall(add_str_len(data_str).encode()) + + +class Receiver(object): + def __init__(self): + self._cache = "" + self.remainBytes = 0 + + def __call__(self, *args, **kwargs): + while 1: + d = None + try: + d = _socket.recv(SOCKET_CACHE).decode() + # logger.debug(f"Data: {d}, {len(d)}") + if len(d) == 0: + return None + if self.remainBytes == 0: + + if d[0:5].isdigit() and d[5] == "{": + need = int(d[0:5]) + self.remainBytes = need - (len(d) - 5) + if(self.remainBytes == 0): + self._cache = "" + data = remove_json_num(d) + return json.loads(data) + else: + self._cache = d + else: + self.remainBytes -= len(d) + if self.remainBytes == 0: + data = remove_json_num(self._cache + d) + # logger.debug(self._cache + d) + self._cache = "" + return json.loads(data) + else: + self._cache += d + except ConnectionResetError: + print("can not connect with server.") + exit() + except Exception as e: + print("[Receiver] receive data error. cach the data and wait for next.", e) + traceback.print_exc() + break + + +_receive = Receiver() + +def add_str_len(msg_data): + length = str(len(msg_data)) + index = 5 - len(length) + if index < 0: + raise Exception("the return msg data is too long. the length > 99999.") + return '0' * index + length + msg_data + + +def remove_json_num(msg): + return msg[5:] + + +""" +# def _receive(): +# d = _socket.recv(SOCKE_CACH) +# data = remove_json_num(d) +# return json.loads(data) + + +def receive_game_data(): + try: + data = _receive() + if data['msg_name'] == "game_over": + service.exec_game_over() + return 0 + else: + return_msg = service.exec_round(data) + send_msg = add_str_len(json.dumps(return_msg)) + _socket.sendall(send_msg) + except: + print('error receive data......') + + return 1 +""" diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/main.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/main.py new file mode 100644 index 0000000..26cbc9c --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/main.py @@ -0,0 +1,30 @@ +# encoding:utf8 +''' +入口方法,选手不关注 +''' + + +from ballclient import util +import sys + +if __name__ == "__main__": + print(sys.argv) + if len(sys.argv) != 4: + print("The parameters has error. (TeamID server_ip server_port)") + exit() + team_id = sys.argv[1] + server_ip = sys.argv[2] + port = sys.argv[3] + print("start client....................") + if team_id.isdigit() and port.isdigit(): + team_id = int(team_id) + port = int(port) + util.createShareLogger("brifuture_%s.log" % team_id, stream=True) + else: + print("team_id and port must be digit.") + exit() + + import ballclient.service.constants as constants + from ballclient.comunicate import client + constants.team_id = team_id + client.start( server_ip, port) diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/__init__.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/clientteam.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/clientteam.py new file mode 100644 index 0000000..838f09b --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/clientteam.py @@ -0,0 +1,153 @@ +from .gameteam import BasePlayer, BaseTeam, _ForceBeat, _ForceThink + +class ClientPlayer(BasePlayer): + PrivilegeForce = _ForceBeat + + def __init__(self, p): + BasePlayer.__init__(self, p["id"], p["team"]) + self.x = p["x"] + self.y = p["y"] + self.score = p["score"] + self.visible = True + self.lastAction = None + self.nextPos = (self.x, self.y) + self.posStack = [] # 保留最近 n 次的位置 + self.visualArea = [[0, 0], [0, 0]] + + def distance(self, x, y): + return abs(self.x - x) + abs(self.y - y) + + def isInvision(self, x, y): + if abs(self.x - x) <= ClientTeam.Vision and abs(self.y - y) <= ClientTeam.Vision: + return True + return False + + def update(self, p): + self.lastX = self.x + self.lastY = self.y + BasePlayer.__init__(self, p["id"], p["team"]) + self.x = p["x"] + self.y = p["y"] + self.score = p["score"] + + def __repr__(self): + return ' ' % (self.team, self.id, self.x, self.y) + +class ClientTeam(BaseTeam): + + Width = 20 + Height = 20 + Vision = 3 + + def __init__(self, id = 0): + BaseTeam.__init__(self) + self.meteor = None + self.tunnel = None + self.wormhole = None + self.id = id + + # key 是 player 的 id, value 是 ClientPlayer 对象 + self.players = {} + self.powers = [] # {'point': 1, 'x': 12, 'y': 2} + self.playerNum = 0 + self.privilege = False + + def addPlayer(self, playerInfo, replace=True): + player = ClientPlayer(playerInfo) + if not replace and player.id in self.players: + self.players[player.id].update(playerInfo) + else: + self.players[player.id] = player + self.playerNum = len(self.players) + + def nearmate(self, x, y, dis = 5): + count = 0 + for p in self.players.values(): + if abs(p.x - x) <= dis and abs(p.y - y) <= dis: + count += 1 + return count + + def isMeteor(self, x, y): + """Return True if meteor, + if x, y is out of boundary, return True + """ + for m in self.meteor: + if x == m["x"] and y == m["y"]: + return True + + if x < 0 or x >= ClientTeam.Width or y < 0 or y >= ClientTeam.Height: + return True + return False + + def isTunnel(self, x, y): + """Return Tunnel Dict if found, else None + {"x": 3, "y": 1, "direction": "down"} + """ + for t in self.tunnel: + if t["x"] == x and t["y"] == y: + return t + return None + + def isWormhole(self, x, y): + """Return wormhole if found, else None + {"name": "a","x": 4, "y": 1} + """ + for wh in self.wormhole: + if wh["x"] == x and wh["y"] == y: + return wh + return None + + def peerWormhole(self, wh): + """Return Peer wormhole + """ + name = wh["name"] + if name.isupper(): + exp = name.lower() + else: + exp = name.upper() + + for h in self.wormhole: + if h["name"] == exp: + return h + + def isPlayer(self, x, y, exceptPlayer=None): + for p in self.players.values(): + if p == exceptPlayer: + continue + if p.x == x and p.y == y: + return p + if p.nextPos[0] == x and p.nextPos[1] == y: + return p + return None + + def isPower(self, x, y): + """Return Power point if found + """ + for p in self.powers: + if p["x"] == x and p["y"] == y: + return p["point"] + return None + + def tunnelNext(self, tunnel): + """direct 是 tunnel 的方向, + x y 是 tunnel 的位置 + """ + direct = tunnel["direction"] + x = tunnel["x"] + y = tunnel["y"] + if direct == "right": + x += 1 + elif direct == "left": + x -= 1 + elif direct == "down": + y += 1 + elif direct == "up": + y -= 1 + # cascade tunnel + t = self.isTunnel(x, y) + if t is not None: + return self.tunnelNext(t) + return x, y + +class ClientMap(): + pass \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/constants.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/constants.py new file mode 100644 index 0000000..5141379 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/constants.py @@ -0,0 +1,4 @@ +#global variable here +team_id = 1125 + +team_name = "qqcy" # decided by yourself. \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/gameteam.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/gameteam.py new file mode 100644 index 0000000..d9d31fa --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/gameteam.py @@ -0,0 +1,93 @@ +_ForceBeat = "beat" +_ForceThink = "think" + +class BasePlayer(): + StatusAlive = "alive" + StatusDead = "Dead" + + ActionNone = "blank" + ActionNormal = ["up", "down", "left", "right"] + + def __init__(self, id, teamid): + self.score = 0 + self._sleep = 0 + self.x = 0 + self.y = 0 + self.action = BasePlayer.ActionNone + self.force = None + self.status = BasePlayer.StatusAlive + self.id = id + self.team = teamid + self.group = None + + @property + def sleep(self): + return 1 if self._sleep else 0 + + @staticmethod + def testMove(x, y, action): + if action == "up": + return x, y - 1 + elif action == "down": + return x, y + 1 + elif action == "left": + return x - 1, y + elif action == "right": + return x + 1, y + else: + return x, y + + def _beforeMove(self): + self.lastX = self.x + self.lastY = self.y + + def undoMove(self): + self.x = self.lastX + self.y = self.lastY + + def moveUp(self): + self._beforeMove() + self.y -= 1 + + def moveDown(self): + self._beforeMove() + self.y += 1 + + def moveLeft(self): + self._beforeMove() + self.x -= 1 + + def moveRight(self): + self._beforeMove() + self.x += 1 + +class BaseTeam(): + ForceBeat = _ForceBeat + ForceThink = _ForceThink + + def __init__(self): + self.id = 0 + self.conn = None + self.name = None + self.remain_life = 0 + self.registered = False + self.players = [] + self.playerId = [] + self.force = BaseTeam.ForceBeat + + @property + def point(self): + po = 0 + for p in self.players: + po += p.score + return po + +import random + +class BasePower(): + def __init__(self, id, x, y): + self.id = id + self.x = x + self.y = y + self.value = random.randint(1, 5) + self.exist = True \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/mapelement.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/mapelement.py new file mode 100644 index 0000000..a2d8250 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/mapelement.py @@ -0,0 +1,104 @@ +from .gameteam import BasePlayer, BaseTeam, _ForceBeat, _ForceThink, BasePower +from ballclient.util import logger + +class Player(BasePlayer): + PrivilegeForce = _ForceBeat + + """包含 id, teamid,位置(x y) + """ + def __init__(self, id, teamid): + BasePlayer.__init__(self, id, teamid) + + + def setAction(self, action): + if action in Player.ActionNormal: + self.action = action + else: + self.action = Player.ActionNone + + def triMove(self): + """According to action, change x, y + """ + return Player.testMove(self.x, self.y, self.action) + + @staticmethod + def playerKillAnother(killer, killed): + """Player killer killed Player killed + """ + killer.score += killed.score + killed.score = 0 + killed._sleep = 1 + killed.group.remain_life -= 1 + + + def meetPlayer(self, player): + if player.team == self.team: + return + + # TODO + if player.force == Player.PrivilegeForce: + Player.playerKillAnother(player, self) + else: + Player.playerKillAnother(self, player) + + + def __repr__(self): + return f' ' + +class Team(BaseTeam): + """Team + """ + # 视野 + Vision = 3 + + def __init__(self): + BaseTeam.__init__(self) + + def getPlayer(self, pid): + """Return player if found + """ + for p in self.players: + if p.id == pid: + return p + return None + + def setForce(self, force): + self.force = force + for p in self.players: + p.force = force + + def addPlayer(self, pid, x, y): + p = Player(pid, self.id) + p.x = x + p.y = y + p.force = self.force + p.group = self + self.players.append(p) + self.playerId.append(pid) + return p + + def round_player_pack(self, another): + pack = [] + for p in self.players: + pack.append(p.pack()) + for ap in another.players: + for p in self.players: + if abs(p.x - ap.x) <= Team.Vision and abs(p.y - ap.y) <= Team.Vision: + pack.append(ap.pack()) + break + return pack + + def __repr__(self): + return f'' + +class Power(BasePower): + def __init__(self, id, x, y): + BasePower.__init__(self, id, x, y) + + def isVisibleToPlayer(self, player): + if abs(player.x - self.x) <= Team.Vision and abs(player.y - self.y) <= Team.Vision: + return True + return False + + def __repr__(self): + return f'' diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/service.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/service.py new file mode 100644 index 0000000..6964dee --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/service.py @@ -0,0 +1,122 @@ +# encoding:utf8 +''' +业务方法模块,需要选手实现 + +选手也可以另外创造模块,在本模块定义的方法中填入调用逻辑。这由选手决定 + +所有方法的参数均已经被解析成json,直接使用即可 + +所有方法的返回值为dict对象。客户端会在dict前面增加字符个数。 +''' +import ballclient.service.constants as constants +from ballclient.util import logger +from ballclient.service.clientteam import ClientPlayer, ClientTeam +from ballclient.service.strategy import Strategy, Strategy2 + +myteam = ClientTeam(constants.team_id) +enemy = ClientTeam() +strategy = Strategy2(myteam, enemy) + +def leg_start(msg): + ''' + :param msg: + :return: None + ''' + msg_data = msg["msg_data"] + msg_map = msg_data['map'] + ClientTeam.Vision = msg_map['vision'] + ClientTeam.Width = msg_map['width'] + ClientTeam.Height = msg_map['height'] + + for t in msg_data['teams']: + if t["id"] == constants.team_id: + for pid in t['players']: + myteam.addPlayer({"score": 0, "x": 0, "y": 0, "id": pid, "team": myteam.id}) + ClientPlayer.PrivilegeForce = t["force"] + else: + enemy.id = t["id"] + + myteam.meteor = msg_map['meteor'] + myteam.tunnel = msg_map['tunnel'] + myteam.wormhole = msg_map['wormhole'] + + # logger.debug(f"Leg start: {msg_data}") + +def round(msg): + ''' + :param msg: dict + :return: + return type: dict + ''' + msg_data = msg['msg_data'] + round_id = msg_data['round_id'] + action = [] + + if 'players' in msg_data: + players = msg_data['players'] + # logger.debug("========Code Needs Update=======") + enemy.players = {} + if 'power' in msg_data: + myteam.powers = msg_data['power'] + else: + myteam.powers = [] + mode = msg_data["mode"] + myteam.privilege = (mode == ClientPlayer.PrivilegeForce) + for team in msg_data["teams"]: + if team['id'] == constants.team_id: + myteam.remain_life = team['remain_life'] + else: + enemy.remain_life = team['remain_life'] + # logger.info(f"[R{round_id}]Myteam is in privilege mode") + + for player in players: + if player['team'] == constants.team_id: + # my player + myteam.addPlayer(player, replace=False) + else: + enemy.addPlayer(player) + # logger.debug(f"------{myteam.players}------") + strategy.makeAction(action, round_id) + + + # logger.info(f"=====\nround data {msg_data}\n {myteam.powers}=======") + + result = { + "msg_name": "action", + "msg_data": { + "round_id": round_id, + 'actions': action + } + } + return result + + +legInfo = [] +def leg_end(msg): + ''' + :param msg: + { + "msg_name" : "leg_end", + "msg_data" : { + "teams" : [ + { + "id" : 1001, #队ID + "point" : 770 #本leg的各队所得点数 + }, + { + "id" : 1002, + "point" : 450 + } + ] + } + } + ''' + logger.info("leg end") + teams = msg["msg_data"]['teams'] + for team in teams: + legInfo.append("teams: %s, point: %d" % (team['id'], team['point'])) + + +def game_over(msg): + logger.info(legInfo) + logger.info("game over!") diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/strategy.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/strategy.py new file mode 100644 index 0000000..806c81b --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/service/strategy.py @@ -0,0 +1,422 @@ +from ballclient.service.clientteam import ClientPlayer, ClientTeam +from ballclient.util import logger +import random + +""" +TODO 追击敌人时,多只鲲一起协作 +2. 鲲原地打转问题 + +3. 增加一个可视区域,Privilege 尽量保证可视区域最大 +4. 己方不能重叠 + +- 计算权重时,不考虑方向了 +- 权重的计算公式 +weight funciton (x-1)^3-x+2 or y= 4.25-5.04 x + 1.75 x^2 +""" +class Strategy(): + Direction = ['right', 'left', 'down', 'up'] + WeightMeteor = 3 + WeightTunnel = 0.5 + WeightWormhole = 0.9 + WeightTunnelPeer = 1.2 + WeightWormholePeer = 2.0 + + WeightTunnelUnprivilege = 15 + WeightWormholeUnprivilege = 18 + WeightEnemyUnprivilege = 200 + WeightPower = 160 + WeightEnemy = 120 + + WeightEmpty = 0.5 + + RightHint = 0x800 + LeftHint = 0x400 + DownHint = 0x200 + UpHint = 0x100 + + RightDownHint = 0x80 + RightUpHint = 0x40 + LeftDownHint = 0x20 + LeftUpHint = 0x10 + + DownRightHint = 0x8 + DownLeftHint = 0x4 + UpRightHint = 0x2 + UpLeftHint = 0x1 + + def __init__(self, myteam, enemy): + self._direction = None + self.weight = 0 + self.myteam = myteam + self.enemy = enemy + self._weightDir = [0] * 4 + self.pos2 = [ + [1, 1], [2, 1], [1, 2], [2, 2] + ] + self.pos3 = [ + # fisrt vx, second vy + [1, 1], [2, 1], [1, 2], [2, 2], + [3, 1], [1, 3], [3, 2], [2, 3], [3, 3] + ] + + @property + def direction(self): + if self._direction is None: + return [] + return [self._direction] + + def ableToGo(self, x, y): + if self.myteam.isMeteor(x, y): + # logger.debug(f"[R{self.round} - abletogo ({x}, {y})] Meteor False") + return False + if self.enemy.isPlayer(x, y) is not None: + return self.myteam.privilege + return True + + def _calcTunnelWeight(self, player, tunnel, direct, **kwargs): + # TODO judge direction and next + + nx, ny = self.myteam.tunnelNext(tunnel) + if nx == player.x and ny == player.y: + # logger.debug(f"tunnel next is current loc") + return - 100000 + tdis = abs(nx - player.x - 1) + abs(ny - player.y - 1) + if tdis > ClientTeam.Vision: + tdis = abs(tdis - ClientTeam.Vision) + 1 + elif tdis == 0: + tdis += 1 + # tmp = self._calcWeight(player, nx, ny, dis=tdis, trans=False, direct=direct) + tmpList = [0, 0, 0, 0] + # if (direct & Strategy.RightHint) == Strategy.RightHint: # 右 + # direct = 0x8c0 + # if (direct & Strategy.LeftHint) == Strategy.LeftHint: # 左 + # direct = 0x430 + # if (direct & Strategy.DownHint) == Strategy.DownHint: # 下 + # direct = 0x20c + # if (direct & Strategy.UpHint) == Strategy.UpHint: # 上 + # direct = 0x103 + self.weightDirection(player, {"x": nx, "y": ny, "vx": 1, "vy": 1}, weightDir=tmpList, direct=direct, trans = False) + # logger.debug(tmpList) + tmp = sum(tmpList) + if self.myteam.privilege == False: + res = (tmp * Strategy.WeightTunnelPeer + random.randint(6, 8) * Strategy.WeightTunnelUnprivilege) + else: + res = (tmp * Strategy.WeightTunnelPeer + random.randint(2, 3) * Strategy.WeightTunnel) + return res + + def _calcWormholeWeight(self, player, wormhole, direct): + # TODO weight change + pwh = self.myteam.peerWormhole(wormhole) + nx = pwh["x"] + ny = pwh["y"] + + tmpList = [0, 0, 0, 0] + self.weightDirection(player, {"x": nx, "y": ny, "vx": 1, "vy": 1}, weightDir=tmpList, direct=0xfff) + tmp = sum(tmpList) + if self.myteam.privilege == False: + return random.randint(10, 15) * Strategy.WeightWormholeUnprivilege + tmp * Strategy.WeightWormholePeer + return random.randint(1, 2) * Strategy.WeightWormhole + tmp * Strategy.WeightWormholePeer + + def _calcWeightIgnoreDis(self, player, x, y, trans = True, direct = 0xfff): + """x, y tried pos(next) + @return weight + 不需要计算距离 + """ + tunnel = self.myteam.isTunnel(x, y) + if tunnel is not None: + if not trans: + return Strategy.WeightEmpty + # logger.debug(f"[R{self.round}] Tunnel ({x}, {y})") + return self._calcTunnelWeight(player, tunnel, direct) + + wormhole = self.myteam.isWormhole(x, y) + if wormhole is not None: + # logger.debug(f"[R{self.round}] Wormhole ({x}, {y})") + return self._calcWormholeWeight(player, wormhole, direct) + + # dis = pow(dis, 2) + if self.myteam.isMeteor(x, y): + # logger.debug(f"[R{self.round}] Meteor ({x}, {y})") + return -0.5 * Strategy.WeightMeteor + + power = self.myteam.isPower(x, y) + if power is not None: + # logger.debug(f"[R{self.round}] Pos({x}, {y}) Power {power}") + return power * Strategy.WeightPower + + ene = self.enemy.isPlayer(x, y) + if ene is not None: + if self.myteam.privilege == False: + score = (- ene.score - player.score) * Strategy.WeightEnemyUnprivilege - 80 * self.enemy.nearmate(x, y, dis=3) + else: + nearMate = self.myteam.nearmate(x, y, dis=ClientTeam.Vision) * self.myteam.remain_life + score = (ene.score + 10) * Strategy.WeightEnemy * (0.5 + nearMate) + # logger.debug(f"Tri to catch enemy({x}, {y}), near: {nearMate}") + + # logger.debug(f"[R{self.round}] Enemy ({x}, {y}) score: {score}") + return score + + teammate = self.myteam.isPlayer(x, y, player) + if teammate is not None: + # TODO A -> X <- B + return - 100 + + return Strategy.WeightEmpty * random.randint(0, 3) # empty + + def _calcWeight(self, player, x, y, dis = 1, trans = True, direct = 0xfff): + return self._calcWeightIgnoreDis(player, x, y, trans, direct=direct) / dis + + def weightDirection(self, player, coord, weightDir, specdis = None, direct = 0xfff, **kwargs): + """vx vy 都是距离,正值 + 从目标点 (x, y) 开始,计算附近的位置的权值 + coord {"x": x, "y": y, "vx": vx, "vy": vy} + weightDir array of 4 elements: weightDir 中的值会被累加 + """ + x = coord["x"] + y = coord["y"] + vx = coord["vx"] + vy = coord["vy"] + + txr = x + vx # 往右 + txl = x - vx # 往左 + tyd = y + vy # 往下 + tyu = y - vy # 往上 + # 直线距离 4.25-5.04 x + 1.75 x^2 + otherDis = 1.75 * vx * vx - 5.04 * vx + 4.25 + if (direct & Strategy.RightHint) == Strategy.RightHint: # 右 + weightDir[0] += self._calcWeight(player, txr, y, dis=otherDis, direct=Strategy.RightHint, **kwargs) + if (direct & Strategy.LeftHint) == Strategy.LeftHint: # 左 + weightDir[1] += self._calcWeight(player, txl, y, dis=otherDis, direct=Strategy.LeftHint, **kwargs) + + otherDis = 1.75 * vy * vy - 5.04 * vy + 4.25 + if (direct & Strategy.DownHint) == Strategy.DownHint: # 下 + weightDir[2] += self._calcWeight(player, x, tyd, dis=otherDis, direct=Strategy.DownHint, **kwargs) + if (direct & Strategy.UpHint) == Strategy.UpHint: # 上 + weightDir[3] += self._calcWeight(player, x, tyu, dis=otherDis, direct=Strategy.UpHint, **kwargs) + # otherDis = ((vx + vy - 0.5) * (vx + vy - 0.5) + abs(vx - vy) + 1) + otherDis = 1.75 * (vx+vy) * (vx+vy) - 5.04 * (vx+vy) + 4.25 + if vy < vx or (vx < 2 and vy < 2): + # 以横向为主 + if (direct & Strategy.RightDownHint) == Strategy.RightDownHint: + weightDir[0] += self._calcWeight(player, txr, tyd, otherDis, **kwargs) # 右下 + if (direct & Strategy.RightUpHint) == Strategy.RightUpHint: + weightDir[0] += self._calcWeight(player, txr, tyu, otherDis, **kwargs) # 右上 + + if (direct & Strategy.LeftDownHint) == Strategy.LeftDownHint: + weightDir[1] += self._calcWeight(player, txl, tyd, otherDis, **kwargs) # 左下 + if (direct & Strategy.LeftUpHint) == Strategy.LeftUpHint: + weightDir[1] += self._calcWeight(player, txl, tyu, otherDis, **kwargs) # 左上 + elif vy > vx or (vx < 2 and vy < 2): + # 以纵向为主 + if (direct & Strategy.DownRightHint) == Strategy.DownRightHint: + weightDir[2] += self._calcWeight(player, txr, tyd, otherDis, **kwargs) # 下右 + if (direct & Strategy.DownLeftHint) == Strategy.DownLeftHint: + weightDir[2] += self._calcWeight(player, txl, tyd, otherDis, **kwargs) # 下左 + + if (direct & Strategy.UpRightHint) == Strategy.UpRightHint: + weightDir[3] += self._calcWeight(player, txr, tyu, otherDis, **kwargs) # 上右 + if (direct & Strategy.UpLeftHint) == Strategy.UpLeftHint: + weightDir[3] += self._calcWeight(player, txl, tyu, otherDis, **kwargs) # 上左 + else: + pass + + + def compare(self, player): + """ + """ + mweight = -1000000 + d = -1 + + if player.lastAction is not None and self._weightDir[0] == self._weightDir[1] and self._weightDir[1] == self._weightDir[2] \ + and self._weightDir[2] == self._weightDir[3]: + self._weightDir[Strategy.Direction.index(player.lastAction)] += 30 + + for i in range(4): + if mweight < self._weightDir[i]: + mweight = self._weightDir[i] + d = i + + logger.debug("[R%d %s - %s] <===> %s" + % (self.round, player, Strategy.Direction[d], self._weightDir)) + return Strategy.Direction[d] + + def makeAction(self, action, round): + self.round = round + + for player in self.myteam.players.values(): + # logger.debug(f"[R{self.round}] {player}") + x = player.x + y = player.y + # iterate + # 四种组合,先右后左,先下后上 + for i in range(4): + self._weightDir[i] = 0 + + if not self.ableToGo(x+1, y): + self._weightDir[0] = -100000 + if not self.ableToGo(x-1, y): + self._weightDir[1] = -100000 + + if not self.ableToGo(x, y+1): + self._weightDir[2] = -100000 + if not self.ableToGo(x, y-1): + self._weightDir[3] = -100000 + + for p in self.pos3: + self.weightDirection(player, + coord = {"x": player.x, "y":player.y, "vx": p[0], "vy": p[1]}, + weightDir=self._weightDir, + direct=0xfff) + player.lastAction = self.compare(player) + player.nextPos = self.playerNextPos(player) + # if len(player.posStack) < 5: + + for player in self.myteam.players.values(): + # logger.debug(f"[R{self.round} {self.myteam.privilege}]{player}: {res}") + action.append({"team": player.team, "player_id": player.id, + "move": [player.lastAction]}) + + def playerNextPos(self, player): + if player.lastAction == 'right': + return (player.x + 1, player.y) + elif player.lastAction == 'left': + return (player.x - 1, player.y) + elif player.lastAction == 'up': + return (player.x, player.y - 1) + elif player.lastAction == 'down': + return (player.x, player.y + 1) + + +class Strategy2(Strategy): + + def __init__(self, myteam, enemy): + Strategy.__init__(self, myteam, enemy) + self.pos3 = [ + # fisrt vx, second vy + [1, 0], [0, 1], [1, 1], + [2, 0], [0, 2], [2, 1], [1, 2], [2, 2], + [3, 0], [0, 3], [3, 1], [1, 3], [3, 2], [2, 3], [3, 3] + ] + + def makeAction(self, action, round): + self.round = round + + for player in self.myteam.players.values(): + # logger.debug(f"[R{self.round}] {player}") + x = player.x + y = player.y + # iterate + # 四种组合,先右后左,先下后上 + for i in range(4): + self._weightDir[i] = 0 + + if not self.ableToGo(x+1, y): + self._weightDir[0] = -100000 + if not self.ableToGo(x-1, y): + self._weightDir[1] = -100000 + + if not self.ableToGo(x, y+1): + self._weightDir[2] = -100000 + if not self.ableToGo(x, y-1): + self._weightDir[3] = -100000 + + for p in self.pos3: + coord = {"x": player.x, "y":player.y, "vx": p[0], "vy": p[1]} + coord["tx"] = player.x + p[0] + coord["ty"] = player.y + p[1] + self.weightPos(player, coord = coord, weightDir=self._weightDir, direct=0xfff) + coord["tx"] = player.x + p[0] + coord["ty"] = player.y - p[1] + self.weightPos(player, coord = coord, weightDir=self._weightDir, direct=0xfff) + coord["tx"] = player.x - p[0] + coord["ty"] = player.y + p[1] + self.weightPos(player, coord = coord, weightDir=self._weightDir, direct=0xfff) + coord["tx"] = player.x - p[0] + coord["ty"] = player.y - p[1] + self.weightPos(player, coord = coord, weightDir=self._weightDir, direct=0xfff) + + player.lastAction = self.compare(player) + player.nextPos = self.playerNextPos(player) + # if len(player.posStack) < 5: + # TODO make a controller to control all actions + + for player in self.myteam.players.values(): + # logger.debug(f"[R{self.round} {self.myteam.privilege}]{player}: {res}") + action.append({"team": player.team, "player_id": player.id, + "move": [player.lastAction]}) + + def _calcWeightPos(self, player, x, y, dis=1, dir=-1, trans=True): + tunnel = self.myteam.isTunnel(x, y) + if tunnel is not None: + if not trans: + return Strategy.WeightEmpty + # logger.debug(f"[R{self.round}] Tunnel ({x}, {y})") + return self._calcTunnelWeight(player, tunnel, 0xfff) + + wormhole = self.myteam.isWormhole(x, y) + if wormhole is not None: + # logger.debug(f"[R{self.round}] Wormhole ({x}, {y})") + return self._calcWormholeWeight(player, wormhole, 0xfff) + + # dis = pow(dis, 2) + if self.myteam.isMeteor(x, y): + # logger.debug(f"[R{self.round}] Meteor ({x}, {y})") + return -0.5 * Strategy.WeightMeteor + + power = self.myteam.isPower(x, y) + if power is not None: + # logger.debug(f"[R{self.round}] Pos({x}, {y}) Power {power}") + return power * Strategy.WeightPower + + ene = self.enemy.isPlayer(x, y) + if ene is not None: + if self.myteam.privilege == False: + score = (- ene.score - player.score) * Strategy.WeightEnemyUnprivilege - 80 * self.enemy.nearmate(x, y, dis=3) + else: + nearMate = self.myteam.nearmate(x, y, dis=ClientTeam.Vision) * self.myteam.remain_life + score = (ene.score + 10) * Strategy.WeightEnemy * (0.5 + nearMate) + # logger.debug(f"Tri to catch enemy({x}, {y}), near: {nearMate}") + + # logger.debug(f"[R{self.round}] Enemy ({x}, {y}) score: {score}") + return score + + return Strategy.WeightEmpty * random.randint(0, 3) # empty + + def weightPos(self, player, coord, weightDir, **kwargs): + """ + coord x, y 起始点坐标, vx vy 距离,可以为 0,tx ty 目标点坐标 + """ + x = coord["x"] + y = coord["y"] + vx = coord["vx"] + vy = coord["vy"] + tx = coord["tx"] + ty = coord["ty"] + distance = 1.75 * (vx+vy) * (vx+vy) - 5.04 * (vx+vy) + 4.25 + dir = self.judegDir(x, y, vx, vy, tx, ty) + if dir[0] > -1: + weightDir[dir[0]] += self._calcWeightIgnoreDis(player, tx, ty) / distance + if dir[1] > -1: + weightDir[dir[1]] += self._calcWeightIgnoreDis(player, tx, ty) / distance + + def judegDir(self, x, y, vx, vy, tx, ty): + dirX = -1 + dirY = -1 + # warning: vy == vx 出现了两次 + if vy <= vx: + if tx > x: + # right + dirX = 0 + elif tx < x: + # left + dirX = 1 + # return dirX + if vx <= vy: + if ty > y: + # down + dirY = 2 + elif ty < y: + # up + dirY = 3 + # return dirY + return dirX, dirY \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/client/ballclient/util.py b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/util.py new file mode 100644 index 0000000..2455aaf --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/ballclient/util.py @@ -0,0 +1,42 @@ +import logging + + +from pathlib import Path + +_BASE_DIR = Path("/var") +_LOG_DIR = _BASE_DIR / "log" + +_LOG_DIR.mkdir(parents=True, exist_ok=True) + +## For Translating + +import logging +def createLogger(name: str, stream = False, level = logging.DEBUG): + """create logger, specify name, for example: test.log + suffix is not necessary but helpful + """ + + # log_file = (_LOG_DIR / name) + + logger = logging.getLogger() + # fh = logging.FileHandler(log_file.absolute()) + fh = logging.FileHandler("%s/%s" % (_LOG_DIR, name)) + fh.setFormatter(logging.Formatter("%(asctime)s %(levelname)s: %(message)s")) + fh.setLevel(level) + logger.setLevel(level) + logger.addHandler(fh) + + if stream: + sh = logging.StreamHandler() + sh.setLevel(level) + sh.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(filename)s %(lineno)s: %(message)s")) + logger.addHandler(sh) + + return logger + +logger = None + +def createShareLogger(name: str, stream = False, level = logging.DEBUG): + # print(name) + global logger + logger = createLogger(name, stream=stream, level=level) \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/client/start.bat b/19-q3q4/huawei kunpen race/brifuture/client/start.bat new file mode 100644 index 0000000..5e4a1f1 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/start.bat @@ -0,0 +1,6 @@ +@echo off +set PATHONPATH=%cd% +python -m ballclient.main %1 %2 %3 +@echo on + +EXIT \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/client/start.sh b/19-q3q4/huawei kunpen race/brifuture/client/start.sh new file mode 100644 index 0000000..3956e96 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/start.sh @@ -0,0 +1,2 @@ +#!/bin/bash +python3 -m ballclient.main $1 $2 $3 diff --git a/19-q3q4/huawei kunpen race/brifuture/client/test/__init__.py b/19-q3q4/huawei kunpen race/brifuture/client/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/19-q3q4/huawei kunpen race/brifuture/client/test/server.py b/19-q3q4/huawei kunpen race/brifuture/client/test/server.py new file mode 100644 index 0000000..e0ecef0 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/test/server.py @@ -0,0 +1,31 @@ +# encoding:utf8 +import socket +import threading + +HOST = "127.0.0.1" +PORT = 3000 + +if __name__ == "__main__": + _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + _socket.bind((HOST, PORT)) + _socket.listen(5) + while 1: + conn, addr = _socket.accept() # 接受TCP连接,并返回新的套接字与IP地址 + print('Connected by', addr) # 输出客户端的IP地址 + data = conn.recv(1024) # 把接收的数据实例化 + conn.sendall('00000{"msg_name":"leg_start","b":2}') + threading._sleep(0.2) + while 1: + conn.sendall('''12345{"msg_name":"round","msg_data":{"round_id":2,"players":[{"id":0,"team":1,"x":0,"y":1, "sleep":1,"score":20}]}}'''); + threading._sleep(0.2) + print "start receive" + data = conn.recv(1024) + print "receive:%s" % data + data = data[5:] + import json + + m = json.loads(data) + print "*****************************" + print m + print "*****************************" +conn.close() # 关闭连接 diff --git a/19-q3q4/huawei kunpen race/brifuture/client/test/service.py b/19-q3q4/huawei kunpen race/brifuture/client/test/service.py new file mode 100644 index 0000000..8309821 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/test/service.py @@ -0,0 +1,22 @@ +#encoding:utf8 +''' +测试 +''' +import random + +current_direction = "" + + +def exec_round(msg): + self_balls = msg['msg_data']["self_balls"] + current_round = msg['msg_data']['round_id'] + result = [] + + for current in self_balls: + result.append( + {"ball_id": current['ball_id'], "force_x": random.randint(1, 10), + "force_y": random.randint(1, 10)}) + + result = {"msg_name": "action", + "msg_data": {"round_id": current_round, "actions": result}} + return result diff --git a/19-q3q4/huawei kunpen race/brifuture/client/test/test.py b/19-q3q4/huawei kunpen race/brifuture/client/test/test.py new file mode 100644 index 0000000..9fd9819 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/test/test.py @@ -0,0 +1,14 @@ +a = '{"msg_name": "action", "msg_data": {"round_id": 2, "action": [{"player_id": 0, "move": ["up"], "team": 1}]}}' + +import json + +import ballclient.comunicate.client as client + +print client.add_str_len(a) + +a = '''{"msg_name": "action", "msg_data": {"round_id": 2, "action": [ + {"player_id": 0, "move": ["up"], "team": 1}]}}''' + + +print type(json.loads(a)) + diff --git a/19-q3q4/huawei kunpen race/brifuture/client/test/test2.py b/19-q3q4/huawei kunpen race/brifuture/client/test/test2.py new file mode 100644 index 0000000..56ef6dc --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/client/test/test2.py @@ -0,0 +1,17 @@ +import ballclient.comunicate.client as client +import json + +a = '{"msg_name": "action", "msg_data": {"round_id": 659, "actions": [{"force_y": 8, "force_x": 10, "ball_id": 0}, {"force_y": 10, "force_x": 9, "ball_id": 1}, {"force_y": 5, "force_x": 1, "ball_id": 2}, {"force_y": 2, "force_x": 5, "ball_id": 3}]}}' +a ='''{"msg_name": "round", + "msg_data": { + "round_id": 2, + "players": [ + { + "id": 0, "team": 1, "x": 0, "y": 1, sleep: 1, score: 20 + } + } +}''' + +b = json.dumps(a) + +print client.add_str_len(b) diff --git a/19-q3q4/huawei kunpen race/brifuture/gameclient.bat b/19-q3q4/huawei kunpen race/brifuture/gameclient.bat new file mode 100644 index 0000000..93398b9 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/gameclient.bat @@ -0,0 +1,6 @@ +pushd %CD% +cd /d client +start.bat %1 %2 %3 +popd + +EXIT \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/brifuture/gameclient.sh b/19-q3q4/huawei kunpen race/brifuture/gameclient.sh new file mode 100644 index 0000000..b3b13c2 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/gameclient.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cd "$(dirname "$0")" +cd client +sh start.sh $1 $2 $3 diff --git a/19-q3q4/huawei kunpen race/brifuture/packclient.sh b/19-q3q4/huawei kunpen race/brifuture/packclient.sh new file mode 100644 index 0000000..9b1541e --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/packclient.sh @@ -0,0 +1,2 @@ +#!/bin/sh +zip -r brifuture.zip gameclient.sh client diff --git a/19-q3q4/huawei kunpen race/brifuture/testclient.sh b/19-q3q4/huawei kunpen race/brifuture/testclient.sh new file mode 100644 index 0000000..931f0d8 --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/testclient.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd client +python -m ballclient.main $1 $2 $3 diff --git a/19-q3q4/huawei kunpen race/brifuture/wingame.bat b/19-q3q4/huawei kunpen race/brifuture/wingame.bat new file mode 100644 index 0000000..ca07a2b --- /dev/null +++ b/19-q3q4/huawei kunpen race/brifuture/wingame.bat @@ -0,0 +1,4 @@ +pushd %CD% +cd /d bin +client.exe %1 %2 %3 +popd \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/game.csv b/19-q3q4/huawei kunpen race/server/game.csv new file mode 100644 index 0000000..add9133 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/game.csv @@ -0,0 +1 @@ +map_r2m1.txt,qqcy,1163,0,AI 1.1,1123,0 \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/main.py b/19-q3q4/huawei kunpen race/server/main.py new file mode 100644 index 0000000..678e8ed --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/main.py @@ -0,0 +1,4 @@ +from simserver import startServer +import sys +print("=======", sys.argv) +startServer() \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/map_r2m1.txt b/19-q3q4/huawei kunpen race/server/map_r2m1.txt new file mode 100644 index 0000000..3c1f984 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/map_r2m1.txt @@ -0,0 +1,36 @@ +{ + "game":{ + "revive_player_pos":false, + "revive_times":4, + "vision":3, + "power_create_num":10, + "timeout":800 + }, + "map": + { + "height":20, + "width":20, + "map_str":" + .X........X........A + ..................## + ...1...1....1...1... + ..1..............1.. + .......##..##....... + .....^>>>>>>>>>..... + .....^.......bv..... + O.1.#^........v#.1.O + ....#^..2112..v#.... + .....^..1551..v..... + .....^..1551..v..... + ....#^..2112..v#.... + O.1.#^........v#.1.O + .....^a.......v..... + .....<<<<<<<< 0.8: + found = False + for po in self._powers: + if po.x == i and po.y == j: + found = True + if found: continue + + self.addPower(i, j) + pc += 1 + logger.debug(f"generate Power at ({i}, {j})") + + def isPower(self, x: int, y: int) -> Power: + """Return Power action if True or None will return + """ + for p in self._powers: + if x == p.x and y == p.y and p.exist: + return p + return None + + @property + def powers(self): + return [x.pack() for x in self._powers] + + @property + def powerLen(self): + return len(self._powers) + + + def tunnelType(self, x: int, y: int): + t = self._map_str_list[y][x] + if t == GameMap.PosTunnelUp: + return "up" + elif t == GameMap.PosTunnelDown: + return "down" + elif t == GameMap.PosTunnelLeft: + return "left" + elif t == GameMap.PosTunnelRight: + return "right" + + def addPower(self, i, j, value = None): + p = Power(self.powerId, i, j) + self.powerId += 1 + self._powers.append(p) + if value is not None: + p.value = value + + def _parse(self, map_str_list: list, width: int): + self.width = width + self.height = width + + for j, map_str in enumerate(map_str_list): + for i in range(width): + if map_str[i] == GameMap.PosMeteor: + self._pushMeteor(i, j) + elif map_str[i] in GameMap.PosTunnels: + self._pushTunnel(i, j, map_str[i]) + elif map_str[i] in GameMap.PosWormhole: + self._pushWormhole(i, j, map_str[i]) + elif map_str[i] in GameMap.PosTeam: + self._pushTeam(i, j, map_str[i]) + elif map_str[i] == BaseGameMap.PosEmpty: + continue + else: + try: + value = int(map_str[i]) + self.addPower(i, j, value) + except Exception as e: + logger.warning(e) + + +class GameMap(BaseGameMap): + """ + Property: meteor, tunnel, wormhole, + teamInitPos(teamA, teamB), vision, height + """ + + PosTunnelDesc = ["up", "down", "left", "right"] + + def __init__(self, mapFile: str): + BaseGameMap.__init__(self) + self.map = {} + self._players = {} + with open(mapFile) as f: + f.readline() + content = "" + while True: + text = f.readline().strip() + content += text + # logger.debug(text) + if text.find("},") > -1: + break + # logger.debug(content[7:-1]) + self.map["game"] = json.loads(content[7:-1]) + Team.Vision = self.map["game"]["vision"] + BaseGameMap.PowerCreateNum =self.map["game"]["power_create_num"] + self.map["map"] = {} + for text in f: + text = text.strip() + if text.find("height") > -1: + i = text.index("height") + self.map["map"]["height"] = int(text[i + 2 +len("length"):-1]) + if text.find("width") > -1: + i = text.index("width") + self.map["map"]["width"] = int(text[i + 1 +len("length"):-1]) + if text.find("map_str") > -1: + break + # map_str_list 每一行存放的是 该行的 map 信息 + map_str_list = [] + + for i, text in enumerate(f): + text = text.strip() + if text.find("\"") > -1: break + map_str_list.append(text) + i += 1 + # logger.debug(map_str_list) + self._parse(map_str_list, self.map["map"]["width"]) + self._map_str_list = map_str_list + + def isPlayer(self, x: int, y: int): + """Return Player Instance if there is, or None will be returned + """ + for p in self._players.values(): + if x == p.x and y == p.y: + return p + return None + + + def addPlayer(self, pid, player: Player): + self._players[pid] = player + + + def getPowers(self, team: Team): + power = [] + for po in self._powers: + see = False + for pe in team.players: + # pe = Player() + if pe.status == Player.StatusDead: + continue + if po.isVisibleToPlayer(pe): + see = True + break + if see: + power.append(po.pack()) + return power + + @property + def mines(self): + return [x.save_pack() for x in self._powers if x.exist] + + @property + def playerList(self): + return self._players.values() + + def eatPower(self, player: Player): + """dep + """ + dp = None + for power in self._powers: + if power["x"] == player.x and power["y"] == player.y: + player.score += power.value + dp = power + break + if dp is not None: + self._powers.remove(dp) + \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/simserver/gameteam.py b/19-q3q4/huawei kunpen race/server/simserver/gameteam.py new file mode 100644 index 0000000..901da70 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/gameteam.py @@ -0,0 +1,113 @@ +_ForceBeat = "beat" +_ForceThink = "think" + +class BasePlayer(): + StatusAlive = "alive" + StatusDead = "Dead" + + ActionNone = "blank" + ActionNormal = ["up", "down", "left", "right"] + + def __init__(self, id: int, teamid: int): + self.score = 0 + self._sleep = 0 + self.x = 0 + self.y = 0 + self.action = BasePlayer.ActionNone + self.force = None + self.status = BasePlayer.StatusAlive + self.id = id + self.team = teamid + self.group = None + + @property + def sleep(self): + return 1 if self._sleep else 0 + + @staticmethod + def testMove(x, y, action): + if action == "up": + return x, y - 1 + elif action == "down": + return x, y + 1 + elif action == "left": + return x - 1, y + elif action == "right": + return x + 1, y + else: + return x, y + + def _beforeMove(self): + self.lastX = self.x + self.lastY = self.y + + def undoMove(self): + self.x = self.lastX + self.y = self.lastY + + def moveUp(self): + self._beforeMove() + self.y -= 1 + + def moveDown(self): + self._beforeMove() + self.y += 1 + + def moveLeft(self): + self._beforeMove() + self.x -= 1 + + def moveRight(self): + self._beforeMove() + self.x += 1 + +class BaseTeam(): + ForceBeat = _ForceBeat + ForceThink = _ForceThink + + def __init__(self): + self.id = 0 + self.conn = None + self.name = None + self.remain_life = 0 + self.registered = False + self.players = [] + self.playerId = [] + self.force = BaseTeam.ForceBeat + + @property + def point(self): + po = 0 + for p in self.players: + po += p.score + return po + + + def save_pack_round(self): + return { + "point": self.point, + "remain_life": self.remain_life, + "team_id": self.id + } + + def leg_start_pack(self, force): + self.setForce(force) + p = { + "id": self.id, + "players": self.playerId, + "force": self.force + } + return p + + def setForce(self, force): + self.force = force + +import random + +class BasePower(): + def __init__(self, id, x, y): + self.id = id + self.x = x + self.y = y + self.value = random.randint(1, 5) + self.exist = True \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/simserver/interface.md b/19-q3q4/huawei kunpen race/server/simserver/interface.md new file mode 100644 index 0000000..5883753 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/interface.md @@ -0,0 +1,145 @@ +## Interface SD Communicate Protocol + +1. registration() --> 客户端发送注册消息 + +>> Loop Race Leg + +2. leg_start() <---- 独立子场(leg)开始消息。 + +>> Loop Round 裁判程序给各参赛选手广播的当前会和的游戏相关的全部信息 + +3. round() <---- + +4. action() ----> + +<< Loop Round end + +5. leg_end() + +<< Loop Race Leg end + +6. game_over() + +> 注:服务器和客户端启动顺序不确定 + +### Message + +小写字符串。格式:消息长度+消息体 + +#### registration : 客户端发送的注册消息 + +```json +00158{"msg_name": "registration", "msg_data": {"team_id": 1000, "team_name": "test_demo"}} +``` + +#### leg_start: leg 开始消息 + +裁判程序给各参赛选手广播地图相关信息,以及选手的分组信息。 + +vision : 默认视野4,即视野范围9*9的方形空间 + +```json +{ + "msg_name": "leg_start", + "msg_data": { + "map": { + "width": 15, + "height": 15, + "vision": 3, + "meteor": [ + {"x": 1, "y": 1}, + {"x": 1, "y": 4} + ], + "tunnel": [ + {"x": 3, "y": 1, "direction": "down"}, + {"x": 3, "y": 4, "direction": "down"} + ], + "wormhole": [ + {"name": "a","x": 4, "y": 1}, + {"name": "A", "x": 4, "y": 4 } + ] + + }, + "teams" : [ + {"id": 1001, "players": [0, 1, 2, 3], "force": "beat"}, + {"id": 1002, "players": [4, 5, 6, 7], "force": "think"}, + + ] + } +} +``` + + +#### round + +裁判程序给各参赛选手广播的当前会和的游戏相关的全部信息。 + +```json +{ + "msg_name": "round", + "msg_data": { + "round_id": 2, + "mode": "beat", + "power": [ + {"x":5,"y":2, "point":1}, + {"x":5,"y":5, "point":2} + ], + "players": [ + { + "id":0,"score":0,"sleep":0,"team":1001,"x":0,"y":1 + } + ], + "teams": [ + {"id":1001,"point":0, "remain_life":2}, + {"id":1002,"point":0, "remain_life":3} + + ] + } +} +``` + + +#### action + +参赛选手反馈在本回合准备执行的动作。每个参赛选手每回合只反馈一条消息,包含所有player的动作请求。 + +```json +{ + "msg_name": "action", + "msg_data": { + "round_id": 2, + "actions": [ + {"team": 1002, "player_id": 5, "move": ["up"]} + ] + } +} +``` + +#### leg_end + +```json +{ + "msg_name" : "leg_end", + "msg_data" : { + "teams" : [ + { + "id" : 1001, + "point" : 770 + }, + { + "id" : 1002, + "point" : 450 + } + ] + } + +} +``` + +#### game_over + +```json +{ + "msg_name" : "game_over" +} +``` \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/simserver/mapelement.py b/19-q3q4/huawei kunpen race/server/simserver/mapelement.py new file mode 100644 index 0000000..40f9879 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/mapelement.py @@ -0,0 +1,150 @@ +from .gameteam import BasePlayer, BaseTeam, _ForceBeat, _ForceThink, BasePower +from .util import logger + +class Player(BasePlayer): + PrivilegeForce = _ForceBeat + + """包含 id, teamid,位置(x y) + """ + def __init__(self, id: int, teamid: int): + BasePlayer.__init__(self, id, teamid) + + + def setAction(self, action): + if action in Player.ActionNormal: + self.action = action + else: + self.action = Player.ActionNone + + def triMove(self): + """According to action, change x, y + """ + return Player.testMove(self.x, self.y, self.action) + + @staticmethod + def playerKillAnother(killer: BasePlayer, killed: BasePlayer): + """Player killer killed Player killed + """ + killer.score += killed.score + killed.score = 0 + killed._sleep = 1 + killed.group.remain_life -= 1 + + + + def eatPower(self, power: BasePower): + self.score += power.value + logger.debug(f"===> {self} eat {power}") + power.exist = False + + def meetPlayer(self, player: BasePlayer): + if player.team == self.team: + return + + # TODO + if player.force == Player.PrivilegeForce: + Player.playerKillAnother(player, self) + else: + Player.playerKillAnother(self, player) + + def pack(self): + return { + "id": self.id, + "score": self.score, + "sleep": self._sleep, + "team": self.team, + "x": self.x, + "y": self.y, + # "status": self.status + } + + def save_pack_round(self): + return { + # "moveOn": self.action, + "moveOn": "blank", + "player_id": self.id, + "team_id": self.team, + "point": self.score, + "sleep": self._sleep, + "status": self.status, + "x": self.x, + "y": self.y + } + + def __repr__(self): + return f' ' + +class Team(BaseTeam): + """Team + """ + # 视野 + Vision = 3 + def __init__(self): + BaseTeam.__init__(self) + + def getPlayer(self, pid): + """Return player if found + """ + for p in self.players: + if p.id == pid: + return p + return None + + def setForce(self, force): + self.force = force + for p in self.players: + p.force = force + + def addPlayer(self, pid: int, x: int, y: int): + p = Player(pid, self.id) + p.x = x + p.y = y + p.force = self.force + p.group = self + self.players.append(p) + self.playerId.append(pid) + return p + + def round_player_pack(self, another: BaseTeam): + """返回当前队伍的 Player 及能够看到的对方队伍的 Player + """ + pack = [] + for p in self.players: + pack.append(p.pack()) + for ap in another.players: + for p in self.players: + if abs(p.x - ap.x) <= Team.Vision and abs(p.y - ap.y) <= Team.Vision: + pack.append(ap.pack()) + break + return pack + + def __repr__(self): + return f'' + +class Power(BasePower): + def __init__(self, id, x, y): + BasePower.__init__(self, id, x, y) + + def isVisibleToPlayer(self, player: Player) -> bool: + if abs(player.x - self.x) <= Team.Vision and abs(player.y - self.y) <= Team.Vision: + return True + return False + + def pack(self): + return { + "point": self.value, + "x": self.x, + "y": self.y + } + + def save_pack(self): + m = { + "id": self.id, + "value": self.value, + "x": self.x, + "y": self.y + } + return m + + def __repr__(self): + return f'' diff --git a/19-q3q4/huawei kunpen race/server/simserver/params.py b/19-q3q4/huawei kunpen race/server/simserver/params.py new file mode 100644 index 0000000..e69de29 diff --git a/19-q3q4/huawei kunpen race/server/simserver/replay.txt b/19-q3q4/huawei kunpen race/server/simserver/replay.txt new file mode 100644 index 0000000..80b8208 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/replay.txt @@ -0,0 +1,33 @@ +01692{"belts":[{"dir":"up","x":5,"y":5},{"dir":"right","x":6,"y":5},{"dir":"right","x":7,"y":5},{"dir":"right","x":8,"y":5},{"dir":"right","x":9,"y":5},{"dir":"right","x":10,"y":5},{"dir":"right","x":11,"y":5},{"dir":"right","x":12,"y":5},{"dir":"right","x":13,"y":5},{"dir":"right","x":14,"y":5},{"dir":"up","x":5,"y":6},{"dir":"down","x":14,"y":6},{"dir":"up","x":5,"y":7},{"dir":"down","x":14,"y":7},{"dir":"up","x":5,"y":8},{"dir":"down","x":14,"y":8},{"dir":"up","x":5,"y":9},{"dir":"down","x":14,"y":9},{"dir":"up","x":5,"y":10},{"dir":"down","x":14,"y":10},{"dir":"up","x":5,"y":11},{"dir":"down","x":14,"y":11},{"dir":"up","x":5,"y":12},{"dir":"down","x":14,"y":12},{"dir":"up","x":5,"y":13},{"dir":"down","x":14,"y":13},{"dir":"left","x":5,"y":14},{"dir":"left","x":6,"y":14},{"dir":"left","x":7,"y":14},{"dir":"left","x":8,"y":14},{"dir":"left","x":9,"y":14},{"dir":"left","x":10,"y":14},{"dir":"left","x":11,"y":14},{"dir":"left","x":12,"y":14},{"dir":"left","x":13,"y":14},{"dir":"down","x":14,"y":14}],"block_name":"leg_start","gates":[{"name":"A","x":19,"y":0},{"name":"b","x":13,"y":6},{"name":"a","x":6,"y":13},{"name":"B","x":0,"y":19}],"map_size":{"height":20,"width":20},"max_round":30,"mode":"light","switch_round":15,"teams":[{"team_id":1152,"team_name":"qqcy","team_player_id_list":[0,1,2,3,4,5,6,7]},{"team_id":1123,"team_name":"AI 1.1","team_player_id_list":[]}],"walls":[{"x":18,"y":1},{"x":19,"y":1},{"x":7,"y":4},{"x":8,"y":4},{"x":11,"y":4},{"x":12,"y":4},{"x":4,"y":7},{"x":15,"y":7},{"x":4,"y":8},{"x":15,"y":8},{"x":4,"y":11},{"x":15,"y":11},{"x":4,"y":12},{"x":15,"y":12},{"x":7,"y":15},{"x":8,"y":15},{"x":11,"y":15},{"x":12,"y":15},{"x":0,"y":18},{"x":1,"y":18}]} +01427{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":38,"value":3,"x":18,"y":18},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":7},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":7},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":12},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":12},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":9,"y":19},{"moveOn":"up","player_id":7,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":18,"y":19}],"round_id":0,"teams":[{"point":0,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01393{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":6},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":6},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":11},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":11},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":9,"y":18},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":18}],"round_id":1,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01393{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":5},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":5},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":10},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":10},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":9,"y":17},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":17}],"round_id":2,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":4},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":4},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":9},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":9},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":9,"y":16},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":16}],"round_id":3,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":3},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":3},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":8},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":8},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":9,"y":15},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":15}],"round_id":4,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":2},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":7},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":7},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":14},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":14}],"round_id":5,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":1},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":6},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":6},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":13}],"round_id":6,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":5},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":5},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":12}],"round_id":7,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":4},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":4},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":11}],"round_id":8,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":3},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":3},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":10}],"round_id":9,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01391{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":41,"value":2,"x":18,"y":8},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":2},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":3,"sleep":0,"status":"alive","x":18,"y":9}],"round_id":10,"teams":[{"point":3,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01358{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":1},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":8}],"round_id":11,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01358{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":7}],"round_id":12,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01358{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":6}],"round_id":13,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01358{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"light","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":5}],"round_id":14,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01357{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":4}],"round_id":15,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01357{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":3}],"round_id":16,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01357{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":17,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01357{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":18,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01357{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":19,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":20,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":21,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":22,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":23,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":24,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":25,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":26,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":27,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":28,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01854{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"up","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"up","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"up","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"up","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"up","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"up","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":29,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +01878{"block_name":"round","mines":[{"id":30,"value":5,"x":16,"y":5},{"id":31,"value":3,"x":1,"y":5},{"id":32,"value":3,"x":11,"y":3},{"id":33,"value":2,"x":8,"y":12},{"id":34,"value":2,"x":4,"y":10},{"id":35,"value":4,"x":7,"y":12},{"id":36,"value":4,"x":10,"y":11},{"id":37,"value":2,"x":15,"y":10},{"id":39,"value":1,"x":12,"y":3},{"id":40,"value":5,"x":15,"y":15},{"id":42,"value":3,"x":19,"y":15},{"id":43,"value":5,"x":16,"y":17},{"id":44,"value":2,"x":1,"y":4},{"id":45,"value":1,"x":3,"y":7},{"id":46,"value":3,"x":8,"y":17},{"id":47,"value":3,"x":12,"y":2},{"id":48,"value":2,"x":10,"y":12},{"id":49,"value":2,"x":9,"y":11},{"id":50,"value":1,"x":19,"y":18},{"id":51,"value":4,"x":12,"y":9},{"id":52,"value":5,"x":14,"y":4},{"id":53,"value":5,"x":11,"y":2},{"id":54,"value":5,"x":11,"y":6},{"id":55,"value":2,"x":17,"y":12},{"id":56,"value":1,"x":7,"y":13},{"id":57,"value":1,"x":6,"y":11},{"id":58,"value":3,"x":8,"y":7},{"id":59,"value":4,"x":10,"y":18}],"mode":"dark","players":[{"moveOn":"blank","player_id":0,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"blank","player_id":1,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"blank","player_id":2,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":0,"y":0},{"moveOn":"blank","player_id":3,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":19,"y":2},{"moveOn":"blank","player_id":4,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":1,"y":0},{"moveOn":"blank","player_id":5,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":10,"y":0},{"moveOn":"blank","player_id":6,"team_id":1152,"point":0,"sleep":0,"status":"alive","x":4,"y":13},{"moveOn":"blank","player_id":7,"team_id":1152,"point":5,"sleep":0,"status":"alive","x":18,"y":2}],"round_id":30,"teams":[{"point":5,"remain_life":4,"team_id":1152},{"point":0,"remain_life":4,"team_id":1123}]} +00078{"block_name":"leg_end","teams":[{"id":1152,"point":5},{"id":1123,"point":0}]} diff --git a/19-q3q4/huawei kunpen race/server/simserver/server.py b/19-q3q4/huawei kunpen race/server/simserver/server.py new file mode 100644 index 0000000..ba75c06 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/server.py @@ -0,0 +1,297 @@ +""" +""" + +import json +from .util import logger +import traceback +from .gamemap import GameMap, Player, Team +from .sockserver import SockServer, sendMsg +import time + +class BaseSimServer(): + ModeExchangRound = 10 + LegMaxRound = 20 + # ModeExchangRound = 150 + # LegMaxRound = 300 + TotalLife = 4 + + DebugMode = True + + PlayerAIdStart = 0 + PlayerBIdStart = 4 + + def __init__(self, port: int, mapFile: str): + self._ss = SockServer(port) + self.teamA = Team() + self.teamB = Team() + self.mapFile = mapFile + self.mapObj = GameMap(mapFile) + BaseSimServer.TotalLife = self.mapObj.map["game"]["revive_times"] + self.round = 0 + self.teamCount = 0 + + from .tracesaver import TraceSaver + self.traceSaver = TraceSaver(self) + + def save_gamecsvFile(self): + content = [self.mapFile, self.teamA.name, self.teamA.id, self.teamA.point, + self.teamB.name, self.teamB.id, self.teamB.point] + with open("game.csv", "w") as f: + logger.debug(f"content write: {content}") + f.write(",".join(map(str, content))) + + def start(self): + data = None + try: + # start of registration + # wait Team A + while self.teamCount < 2: + if not self.teamA.registered: + self._register(self.teamA, self.mapObj.teamA, BaseSimServer.PlayerAIdStart) + + # wait Team B + if not self.teamB.registered: + self._register(self.teamB, self.mapObj.teamB, BaseSimServer.PlayerBIdStart) + + logger.info(f"===========Registration finished=========") + + self.save_gamecsvFile() + + # end of registration + + self._loop_leg() + + # send game over + self._broadcast({"msg_name": "game_over"}) + logger.info(f"Game Over, A: {self.teamA}, B: {self.teamB}") + except Exception as e: + logger.warning(f"[Start] Error: {e}, data: {data}") + traceback.print_exc() + finally: + self.traceSaver.close() + self._ss.sock.close() + + # if SimServer.DebugMode: + # self.start() + + def _register(self, team: Team, initPos: dict, offset: int): + conn, _ = self._ss.accept() + team.conn = conn + data = self._ss.recv(conn) + # logger.debug(data) + if data["msg_name"] != "registration": + logger.info(f"Expect Registration, not recved: {data}") + return + team.id = data["msg_data"]["team_id"] + team.name = data["msg_data"]["team_name"] + team.remain_life = SimServer.TotalLife + team.registered = True + + for i, xy in enumerate(initPos): + p = team.addPlayer(i + offset, xy["x"], xy["y"]) + self.mapObj.addPlayer(i + offset, p) + logger.info(f"Player created: {p}") + + logger.info(f"Registered: {team.id}, pos inited") + self.teamCount += 1 + + def _leg_start(self, aForce, bForce): + teams = [ + self.teamA.leg_start_pack(aForce), + self.teamB.leg_start_pack(bForce) + ] + logger.debug(f"leg_start: {teams}") + map = { + "width": self.mapObj.width, + "height": self.mapObj.height, + "vision": Team.Vision, + "meteor": self.mapObj.meteor, + "tunnel": self.mapObj.tunnel, + "wormhole": self.mapObj.wormhole + } + msg = { + "msg_name": "leg_start", + "msg_data": { + "map": map, + "teams": teams + } + } + self._sendA(msg) + self._sendB(msg) + self.traceSaver.leg_start() + + def _loop_leg(self): + pass + + + def _leg_end(self): + msg = { + "msg_name": "leg_end", + "msg_data": { + "teams": [ + { "id": self.teamA.id, "point": self.teamA.point }, + { "id": self.teamB.id, "point": self.teamB.point }, + ] + } + } + self._broadcast(msg) + self.traceSaver.leg_end() + + def _sendA(self, msg): + return sendMsg(self.teamA.conn, msg) + + def _sendB(self, msg): + return sendMsg(self.teamB.conn, msg) + + def _broadcast(self, msg): + self._sendA(msg) + self._sendB(msg) + + + +class SimServer(BaseSimServer): + + def __init__(self, port : int, mapFile: str): + BaseSimServer.__init__(self, port, mapFile) + self.running = False + self.leg = 0 + Player.PrivilegeForce = Team.ForceBeat + # self.mapObj.addPowers(20) + + def _loop_leg(self, whole = False): + # start of leg start + self._leg_start(Team.ForceBeat, Team.ForceThink) + # 上半场, 先火后水 + self._half_leg_mode(Team.ForceBeat) # mode A + self._half_leg_mode(Team.ForceThink, SimServer.ModeExchangRound) # mode B + for p in self.mapObj.playerList: + p.setAction("") + self.traceSaver.round() + self._leg_end() # send leg end + logger.info(f"End Start Leg 1") + + if not whole: + return + # start of leg start + self._leg_start(Team.ForceThink, Team.ForceBeat) + # 下半场 先水后火 + self._half_leg_mode(Team.ForceThink) # mode A + self._half_leg_mode(Team.ForceBeat, SimServer.ModeExchangRound) # mode B + self._leg_end() # send leg end + logger.info(f"End Start Leg 2") + + def _half_leg_mode(self, privilegeForce, roundOff = 0): + # loop round + self.round = roundOff + Player.PrivilegeForce = privilegeForce + logger.info(f"PrivilegeForce is {privilegeForce}") + # privilegeForce == Team.ForceBeat and teamA.force is Team.ForceBeat, A 是优势 + firstTeam = self.teamA + secondTeam = self.teamB + if self.teamA.force == Player.PrivilegeForce: + firstTeam = self.teamB + secondTeam = self.teamA + while self.round < SimServer.ModeExchangRound + roundOff: + logger.debug(f"-----Round: {self.round}----") + + self.traceSaver.round() + + self._teamRound(firstTeam, secondTeam) + aData = self._ss.recv(firstTeam.conn) + aData["team"] = firstTeam # for debug + self._recv_actions(aData) + self._move_team(firstTeam) + + self._teamRound(secondTeam, firstTeam) + bData = self._ss.recv(secondTeam.conn) + bData["team"] = secondTeam # for debug + self._recv_actions(bData) + self._move_team(secondTeam) + + logger.debug(f"------actionA - {aData}------\n----actionB - {bData}-----") + + # TODO uncomment following + if self.round % 8 == 0 and self.mapObj.powerLen < 15: + self.mapObj.addPowers(self.mapObj.map["game"]["power_create_num"]) + + # input("wait") + # if aData["round_id"]: # check round id + + self.round += 1 + time.sleep(0.01) + # end of half_leg, mode needs exchange + + def _teamRound(self, team: Team, another: Team): + """Send msg to team, another for reference + """ + players = team.round_player_pack(another) + + teams = [ + { "id": team.id, "point": team.point, "remain_life": team.remain_life}, + { "id": another.id, "point": another.point, "remain_life": another.remain_life} + ] + msg = { + "msg_name": "round", + "msg_data": { + "round_id": self.round , + "mode": Player.PrivilegeForce, + "power": self.mapObj.getPowers(team), + "players": players, + "teams": teams + } + } + logger.debug(f"---Round---: {team} Recv [{msg}]") + sendMsg(team.conn, msg) + + def _recv_actions(self, action: dict): + if action["msg_name"] != "action": + logger.warning(f"Round: {self.round}, Recved msg not action, msg: {action}") + return + for act in action["msg_data"]["actions"]: + if act["team"] != action["team"].id: continue + + pid = act["player_id"] + player = action["team"].getPlayer(pid) + player_actname = "" + if len(act["move"]) == 1: + player_actname = act["move"][0] + + player.setAction(player_actname) + + def _move_team(self, team: Team): + for p in team.players: + self._move_player(p) + + def _move_player(self, player: Player): + if player.action == Player.ActionNone: return + + # 获取下一个位置 + x, y = player.triMove() + if x < 0 or x >= self.mapObj.height \ + or y < 0 or y >= self.mapObj.width \ + or self.mapObj.isMeteor(x, y): + return + player.x = x + player.y = y + if self.mapObj.isTunnel(x, y): + t = self.mapObj.tunnelType(x, y) + player.setAction(t) + # tunnel + self._move_player(player) + return + + if self.mapObj.isWormhole(x, y) and player.action is not Player.ActionNone: + whpeer = self.mapObj.wormholePeer(x, y) + player.x = whpeer["x"] + player.y = whpeer["y"] + return + + power = self.mapObj.isPower(x, y) + if power is not None: + player.eatPower(power) + return + + another = self.mapObj.isPlayer(x, y) + if another is not None: + player.meetPlayer(another) + return diff --git a/19-q3q4/huawei kunpen race/server/simserver/sockserver.py b/19-q3q4/huawei kunpen race/server/simserver/sockserver.py new file mode 100644 index 0000000..204f7b0 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/sockserver.py @@ -0,0 +1,71 @@ +import socket +from .util import logger +import traceback +import json + +SOCKET_CACHE = 1024 * 10 + +def add_str_len(msg_data, offset = 0): + length = str(len(msg_data) + offset) + index = 5 - len(length) + if index < 0: + raise Exception("the return msg data is too long. the length > 99999.") + return '0' * index + length + msg_data + + +def remove_json_num(msg): + return msg[5:] + +class SockServer: + + def __init__(self, port: int): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.bind(("0.0.0.0", port)) + self.sock.listen(2) + self.remainBytes = 0 + + def accept(self): + conn, addr = self.sock.accept() + logger.debug(f"{addr} Connect") + return conn, addr + + def recv(self, conn: socket.socket): + """传入 Connection 对象,返回其接受到的内容 (dict) + @note为了获得完整的数据,在此处添加一个循环 + """ + while 1: + d = None + try: + d = conn.recv(SOCKET_CACHE) + if d[-1] == 0: + d = d[:-1] + d = d.decode() + if self.remainBytes == 0: + if d[0:5].isdigit() and d[5] == "{": + need = int(d[0:5]) + self.remainBytes = need - (len(d) - 5) + # logger.debug(f"remain: {self.remainBytes}, len: {len(d)}") + if(self.remainBytes <= 0): + self._cache = "" + data = remove_json_num(d) + return json.loads(data) + else: + self._cache = d + else: + self.remainBytes -= len(d) + if self.remainBytes == 0: + data = remove_json_num(self._cache + d) + logger.debug(self._cache + d) + self._cache = "" + return json.loads(data) + else: + self._cache += d + except ConnectionResetError as e: + pass + except Exception as e: + logger.warning(f"[Receiver] receive data error. cach the data and wait for next. {e}") + # logger.debug(d) + traceback.print_exc() + +def sendMsg(conn: socket.socket, msg: dict): + return conn.send(add_str_len(json.dumps(msg)).encode()) \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/simserver/tracesaver.py b/19-q3q4/huawei kunpen race/server/simserver/tracesaver.py new file mode 100644 index 0000000..64ddc43 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/tracesaver.py @@ -0,0 +1,130 @@ +import json +from .sockserver import add_str_len +from .server import SimServer +from .mapelement import Team, Player +# add_str_len(json.dumps(msg) + +RoundModeMap = {} +RoundModeMap[Team.ForceBeat] = "light" ## 火 +RoundModeMap[Team.ForceThink] = "dark" + +import os + +WormholeNameMap = { + "A": 65, + "a": 65, + "B": 66, + "b": 66, + "C": 67, + "c": 67, + "D": 68, + "d": 68, +} + +class TraceSaver(): + RoundModeThink = "light" + RoundModeBeat = "dark" + # TODO save trace necessary + def __init__(self, simserver: SimServer): + self.ss = simserver + try: + # os.remove("replay.txt") + self._file = open("replay.txt", "w") + except: + raise ValueError("File Error") + + def close(self): + self._file.close() + + def leg_start(self): + belts = [] + for t in self.ss.mapObj.tunnel: + belts.append({"dir": t["direction"],"x": t["x"],"y": t["y"]}) + + gates = [] + for wh in self.ss.mapObj.wormhole: + # name to char 65 == a + n = WormholeNameMap[wh["name"]] + gates.append({"name": n,"x": wh["x"], "y": wh["y"]}) + + teams = [ + { + "team_id": self.ss.teamA.id, + "team_name": self.ss.teamA.name, + "team_player_id_list": self.ss.teamA.playerId + }, + { + "team_id": self.ss.teamB.id, + "team_name": self.ss.teamB.name, + "team_player_id_list": self.ss.teamB.playerId + } + ] + + walls = self.ss.mapObj.meteor + + block = { + "belts": belts, + "block_name": "leg_start", + "gates": gates, + "map_size": { + "height": self.ss.mapObj.height, + "width": self.ss.mapObj.width + }, + "max_round": SimServer.LegMaxRound, + "mode": RoundModeMap[Player.PrivilegeForce], + "switch_round": SimServer.ModeExchangRound, + "teams": teams, + "walls": walls + } + self._write(block) + + def round(self): + mines = self.ss.mapObj.mines + players = [] + for p in self.ss.mapObj.playerList: + players.append(p.save_pack_round()) + + teams = [ + self.ss.teamA.save_pack_round(), + self.ss.teamB.save_pack_round() + ] + effects = { + "belts": [], + "create_mines": [], + "distroy_mines": [], + "kills": [] + } + toRemove = [] + for k, v in effects.items(): + if len(v) == 0: + toRemove.append(k) + + for k in toRemove: + effects.pop(k) + + block = { + "block_name": "round", + "mines": mines, + "mode": RoundModeMap[Player.PrivilegeForce], + "players": players, + "round_id": self.ss.round, + "teams": teams, + # "effects": effects + } + if len(effects) > 0: + block["effects"] = effects + self._write(block) + + def leg_end(self): + block = { + "block_name": "leg_end", + "teams": [ + { "id": self.ss.teamA.id, "point": self.ss.teamA.point }, + { "id": self.ss.teamB.id, "point": self.ss.teamB.point }, + ] + } + self._write(block) + + def _write(self, msg, offset = 2): + # offset 为 2,匹配原 server + self._file.write(add_str_len(json.dumps(msg, separators=(',', ':')), offset = offset)+"\n") diff --git a/19-q3q4/huawei kunpen race/server/simserver/util.py b/19-q3q4/huawei kunpen race/server/simserver/util.py new file mode 100644 index 0000000..bc1311b --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/simserver/util.py @@ -0,0 +1,46 @@ +import logging + + +from pathlib import Path + +_BASE_DIR = Path("./tmp/clients") +_LOG_DIR = _BASE_DIR / "logs" +_CONFIG_DIR = _BASE_DIR / "configs" + +_LOG_DIR.mkdir(parents=True, exist_ok=True) +_CONFIG_DIR.mkdir(parents=True, exist_ok=True) + +## For Translating + +LANGUAGE_DIR = (Path(__file__).parent / "locale").resolve() +import gettext +def initGetText(domain="myfacilities") -> gettext.gettext: + gettext.bindtextdomain(domain, LANGUAGE_DIR) + gettext.textdomain(domain) + gettext.find(domain, "locale", languages=["zh_CN", "en_US"]) + return gettext.gettext + +import logging +def createLogger(name: str, stream = False, level = logging.DEBUG): + """create logger, specify name, for example: test.log + suffix is not necessary but helpful + """ + + log_file = _LOG_DIR / name + + logger = logging.getLogger() + fh = logging.FileHandler(log_file) + fh.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(filename)s %(lineno)s: %(message)s")) + fh.setLevel(level) + logger.setLevel(level) + logger.addHandler(fh) + + if stream: + sh = logging.StreamHandler() + sh.setLevel(level) + sh.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(filename)s %(lineno)s: %(message)s")) + logger.addHandler(sh) + + return logger + +logger = createLogger("server.log", stream=True) \ No newline at end of file diff --git a/19-q3q4/huawei kunpen race/server/test/test_gamemap.py b/19-q3q4/huawei kunpen race/server/test/test_gamemap.py new file mode 100644 index 0000000..1838385 --- /dev/null +++ b/19-q3q4/huawei kunpen race/server/test/test_gamemap.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +pdir = Path(".") +sys.path.insert(0, str(pdir.absolute())) +from simserver.gamemap import GameMap + +gm = GameMap("map_r2m1.txt") + +print(gm.teamA) +print(gm.teamB) \ No newline at end of file diff --git "a/19-q3q4/huawei kunpen race/\345\215\216\344\270\272\344\272\221\351\262\262\351\271\217\345\274\200\345\217\221\350\200\205\345\244\247\350\265\233\350\265\233\351\242\230\346\226\207\346\241\243\350\257\264\346\230\216-0801.docx" "b/19-q3q4/huawei kunpen race/\345\215\216\344\270\272\344\272\221\351\262\262\351\271\217\345\274\200\345\217\221\350\200\205\345\244\247\350\265\233\350\265\233\351\242\230\346\226\207\346\241\243\350\257\264\346\230\216-0801.docx" new file mode 100644 index 0000000000000000000000000000000000000000..49ea6a86628ea4a6fda2be9d31a744b90a9f7b08 GIT binary patch literal 182283 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ñ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 F{|By-J;VS2 literal 0 HcmV?d00001