Download graphwar/match.py from Foxgrad/graphwar-arena: direct link, hf CLI and curl.
- Browser
- Download file 2.72 kB
-
https://huggingface.co/Foxgrad/graphwar-arena/resolve/main/graphwar/match.py
- Command line
-
hf download hf://Foxgrad/graphwar-arena/graphwar/match.py
-
curl -L -o match.py https://huggingface.co/Foxgrad/graphwar-arena/resolve/main/graphwar/match.py
2.72 kB
| """Une partie : deux équipes de soldats, chaque équipe pilotée par un bot, tour par tour.""" | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| import numpy as np | |
| from . import shot as S | |
| from .world import World | |
| class Turn: | |
| team: int | |
| shooter: int | |
| shot: object | |
| result: S.ShotResult | |
| outcome: str # "kill", "teamkill", "obstacle", "out" | |
| class Match: | |
| def __init__(self, bot_left, bot_right, rng: np.random.Generator, soldiers: int = 3, max_turns: int = 40): | |
| self.bots = [bot_left, bot_right] | |
| self.world = World.random(rng, (soldiers, soldiers)) | |
| self.team = int(rng.integers(2)) # qui commence | |
| self.cursor = [0, 0] | |
| self.turns: list[Turn] = [] | |
| self.max_turns = max_turns | |
| self.stats = [{"tirs": 0, "kills": 0, "teamkills": 0} for _ in range(2)] | |
| def next_shooter(self, team): | |
| alive = self.world.alive(team) | |
| idx = alive[self.cursor[team] % len(alive)] | |
| self.cursor[team] += 1 | |
| return idx | |
| def over(self) -> bool: | |
| return self.winner() is not None or len(self.turns) >= self.max_turns | |
| def winner(self): | |
| a, b = len(self.world.alive(0)), len(self.world.alive(1)) | |
| if a and not b: | |
| return 0 | |
| if b and not a: | |
| return 1 | |
| if not a and not b: | |
| return -1 | |
| if len(self.turns) >= self.max_turns: | |
| return 0 if a > b else 1 if b > a else -1 # au temps : plus de survivants | |
| return None | |
| def plan(self): | |
| """Le bot de l'équipe dont c'est le tour choisit son tir (sans encore l'appliquer).""" | |
| team = self.team | |
| shooter = self.next_shooter(team) | |
| sh = self.bots[team].act(self.world, shooter) | |
| res = S.simulate(self.world, shooter, sh.g, sh.z, sh.target) | |
| return team, shooter, sh, res | |
| def commit(self, team, shooter, sh, res) -> Turn: | |
| st = self.stats[team] | |
| st["tirs"] += 1 | |
| if res.event == "soldier": | |
| victim = self.world.soldiers[res.hit_index] | |
| outcome = "teamkill" if victim.team == team else "kill" | |
| st["kills" if outcome == "kill" else "teamkills"] += 1 | |
| else: | |
| outcome = res.event | |
| S.apply(self.world, res) | |
| t = Turn(team, shooter, sh, res, outcome) | |
| self.turns.append(t) | |
| self.team = 1 - team | |
| if not self.world.alive(self.team): # l'autre équipe n'a plus personne | |
| self.team = team | |
| return t | |
| def step(self) -> Turn: | |
| return self.commit(*self.plan()) | |
| def play(self): | |
| while not self.over(): | |
| self.step() | |
| return self.winner() | |