refactor(game): add Map.closest and improve flag assignment logic

- Introduced `Map.closest` to encapsulate nearest‑position search and replaced duplicated distance loops in flag targeting.
- Updated flag assignment to consider enemy players carrying flags and to use the new helper for both ally and enemy flag selection.
- Cleaned up unused imports and renamed `mypolicy` to `mypolicy.py` for clarity.
- Adjusted frontend `game_config.json` to use new team identifiers, increase players to 3, raise flag count to 9, and enable random flag placement.
This commit is contained in:
2025-12-27 22:10:46 +08:00
parent 8ef3f65ce9
commit b038e5ac29
38 changed files with 28 additions and 255576 deletions
@@ -1,16 +1,15 @@
import asyncio
import random
from lib.game_engine import GameMap, run_game_server
import threading
import collections
# 1. Initialize the global world model
world = GameMap(show_gap_in_msec=10.0)
lock = threading.Lock()
last_updated_time = -1
update_threshold = 10
player_to_flag_assign = {}
my_side_is_left = None
class Map:
def __init__(self):
self.width = world.width
@@ -84,11 +83,8 @@ class Map:
dist[v] = dist[u] + 1
prev[v] = u
queue.append(v)
# ---- 若不可达,返回空字符串 ----
if dist[dst_idx] == float('inf'):
return ""
# ---- 重建路径(逆序) ----
path = []
cur = dst_idx
while cur is not None:
@@ -125,7 +121,15 @@ class Map:
if dist[dst_idx] == float('inf'):
return -1
return dist[dst_idx]
def closest(self, posx_start, posy_start, positions):
closest_pos = None
min_length = float('inf')
for pos in positions:
temp = self.length(posx_start, posy_start, pos[0], pos[1])
if temp != -1 and temp < min_length:
min_length = temp
closest_pos = pos
return closest_pos
myMap = Map()
def start_game(req):
global player_to_flag_assign,my_side_is_left
@@ -141,14 +145,16 @@ def plan_next_actions(req):
global player_to_flag_assign,myMap,my_side_is_left
my_players = world.list_players(mine=True, inPrison=False, hasFlag=None)
opponents = world.list_players(mine=False, inPrison=False, hasFlag=None)
enemy_players_flags = world.list_players(mine=False, inPrison=False, hasFlag=True)
enemy_flags = world.list_flags(mine=False, canPickup=True)
my_flags = world.list_flags(mine=True, canPickup=True)
my_targets = list(world.list_targets(mine=True))
active_player_names = {p["name"] for p in my_players if not p["hasFlag"]}
flags_list = []
for flags in my_flags:
regard_list = []
for flags in enemy_flags:
flags_list.append((flags["posX"],flags["posY"]))
for p in enemy_players_flags:
regard_list.append((p["posX"],p["posY"]))
player_to_flag_assign = {
name: pos for name, pos in player_to_flag_assign.items()
if name in active_player_names
@@ -160,14 +166,7 @@ def plan_next_actions(req):
if p["name"] in player_to_flag_assign and player_to_flag_assign[p["name"]] in flags_list:
flags_list.remove(player_to_flag_assign[p["name"]])
continue
closest_flag = None
min_length = float('inf')
for f in flags_list:
temp = myMap.length(p["posX"],p["posY"],f[0],f[1])
if temp != -1 and temp < min_length:
min_length = temp
closest_flag = f
f = closest_flag
f = myMap.closest(p["posX"],p["posY"],flags_list)
if f is not None:
player_to_flag_assign[p["name"]] = (f[0],f[1])
print(f[0], f[1])
@@ -177,16 +176,16 @@ def plan_next_actions(req):
player_moves = {}
for p in my_players:
curr_pos = (p["posX"], p["posY"])
# Determine Target: Either the assigned flag or the home target
if p["hasFlag"]:
dest = my_targets[0]
elif p["name"] in player_to_flag_assign:
dest = player_to_flag_assign[p["name"]]
else:
continue
f = myMap.closest(p["posX"],p["posY"],regard_list)
if f is not None:
dest = (f[0],f[1])
else:
continue
player_moves[p["name"]] = myMap.guideance(p["posX"],p["posY"],dest[0],dest[1])
return player_moves