diff --git a/config.ini b/config.ini index b155bfd..abada11 100644 --- a/config.ini +++ b/config.ini @@ -2,19 +2,19 @@ # wait until every AI has submitted its orders before performing the next game tick, only works for gRPC players [bool] wait-for-players=true # time until the game ends [int] -playtime=5000 +playtime=40000 # seed for the RNG [int] seed=42 # frames per second [int] -fps=60 +fps=40 # number of updates every frame [int] -speed=2 +speed=10 # number of players (see auto-play) [int] players=2 # number of seekers per player [int] -seekers=5 +seekers=4 # number of goals [int] -goals=5 +goals=16 # color threshold for avoidance of similar colors [float] color-threshold=0.1 @@ -25,8 +25,8 @@ height=768 [camp] # camp dimensions [int] -width=55 -height=55 +width=65 +height=65 [seeker] # length of the acceleration vector of a seeker [float] diff --git a/run_via_grpc.py b/run_via_grpc.py new file mode 100644 index 0000000..1303c6d --- /dev/null +++ b/run_via_grpc.py @@ -0,0 +1,27 @@ +import subprocess +import argparse +import time + +def main(): + parser = argparse.ArgumentParser(description="Run python seekers AIs.") + parser.add_argument("ai_files", type=str, nargs="*", help="Paths to the AIs.") + args = parser.parse_args() + server = subprocess.Popen(["python3", "seekers.py"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1) + for l in server.stdout: + if """[SeekersGame] INFO: Waiting for players to connect:""" in l: + break + + clients = [] + print(args.ai_files) + for script in args.ai_files: + clients.append(subprocess.Popen(["python3", "client.py", script])) + time.sleep(0.1) + server.wait() + + +if __name__ == "__main__": + main() diff --git a/seekers/net/client.py b/seekers/net/client.py index b56ad5d..4ecd56c 100644 --- a/seekers/net/client.py +++ b/seekers/net/client.py @@ -70,7 +70,7 @@ def join(self, name: str, color: seekers.Color = None) -> str: ) from e raise - def send_commands(self, commands: list[Command]) -> CommandResponse: + def send_commands(self, commands: list[CommandRequest.Command]) -> CommandResponse: if self.channel_connectivity_status != grpc.ChannelConnectivity.READY: raise ServerUnavailableError("Channel is not ready.") @@ -202,7 +202,7 @@ def tick(self): def send_commands_and_update_state(self, new_seekers: list[seekers.Seeker]) -> None: # self._logger.debug(f"Sending {len(new_seekers)} commands.") response = self.service_wrapper.send_commands([ - Command(seeker_id=seeker.id, target=vector_to_grpc(seeker.target), magnet=seeker.magnet.strength) + CommandRequest.Command(seeker_id=seeker.id, target=vector_to_grpc(seeker.target), magnet=seeker.magnet.strength) for seeker in new_seekers ]) self.update_state(response) @@ -226,14 +226,14 @@ def update_existing_state(self, response: CommandResponse): for new_seeker in response.seekers: try: - seeker = self.seekers[new_seeker.super.id] + seeker = self.seekers[new_seeker.physical.id] except KeyError as e: raise CouldNotUpdateExistingStateResponseInvalid( - f"Invalid Response: Seeker ({new_seeker.super.id!r}) not in State.seekers. ({list(self.seekers)!r})" + f"Invalid Response: Seeker ({new_seeker.physical.id!r}) not in State.seekers. ({list(self.seekers)!r})" ) from e else: - seeker.position = vector_to_seekers(new_seeker.super.position) - seeker.velocity = vector_to_seekers(new_seeker.super.velocity) + seeker.position = vector_to_seekers(new_seeker.physical.position) + seeker.velocity = vector_to_seekers(new_seeker.physical.velocity) seeker.target = vector_to_seekers(new_seeker.target) seeker.magnet.strength = new_seeker.magnet @@ -250,14 +250,14 @@ def update_existing_state(self, response: CommandResponse): for new_goal in response.goals: try: - goal = self.goals[new_goal.super.id] + goal = self.goals[new_goal.physical.id] except KeyError as e: raise CouldNotUpdateExistingStateResponseInvalid( - f"Invalid Response: Goal ({new_goal.super.id!r}) not in State.goals. ({list(self.goals)!r})" + f"Invalid Response: Goal ({new_goal.physical.id!r}) not in State.goals. ({list(self.goals)!r})" ) from e else: - goal.position = vector_to_seekers(new_goal.super.position) - goal.velocity = vector_to_seekers(new_goal.super.velocity) + goal.position = vector_to_seekers(new_goal.physical.position) + goal.velocity = vector_to_seekers(new_goal.physical.velocity) goal.time_owned = new_goal.time_owned goal.owner = self.camps[new_goal.camp_id].owner if new_goal.camp_id else None @@ -267,7 +267,7 @@ def create_new_state(self, response: CommandResponse): config = self.get_config() camp_replies = {camp.id: camp for camp in response.camps} - seeker_replies = {seeker.super.id: seeker for seeker in response.seekers} + seeker_replies = {seeker.physical.id: seeker for seeker in response.seekers} self.seekers = {} self.players = {} @@ -293,7 +293,7 @@ def create_new_state(self, response: CommandResponse): ) from e self.goals = { - goal.super.id: goal_to_seekers(goal, self.camps, config) + goal.physical.id: goal_to_seekers(goal, self.camps, config) for goal in response.goals } diff --git a/seekers/net/converters.py b/seekers/net/converters.py index 4e575b6..8df8607 100644 --- a/seekers/net/converters.py +++ b/seekers/net/converters.py @@ -15,10 +15,8 @@ from seekers.game.vector import Vector from seekers.game.seeker import Seeker -import seekers.game as game - def vector_to_seekers(vector: Vector2DAPI) -> Vector: - return game.Vector(vector.x, vector.y) + return Vector(vector.x, vector.y) def vector_to_grpc(vector: Vector) -> Vector2DAPI: @@ -26,11 +24,11 @@ def vector_to_grpc(vector: Vector) -> Vector2DAPI: def seeker_to_seekers(seeker: SeekerAPI, owner: Player, config: Config) -> SeekerAPI: - out = game.Seeker( + out = Seeker( id_=seeker.physical.id, owner=owner, - position=vector_to_seekers(seeker.super.position), - velocity=vector_to_seekers(seeker.super.velocity), + position=vector_to_seekers(seeker.physical.position), + velocity=vector_to_seekers(seeker.physical.velocity), mass=config.seeker_mass, radius=config.seeker_radius, friction=config.seeker_friction, @@ -57,7 +55,7 @@ def physical_to_grpc(physical: Physical) -> PhysicalAPI: def seeker_to_grpc(seeker: Seeker) -> SeekerAPI: return SeekerAPI( - super=physical_to_grpc(seeker), + physical=physical_to_grpc(seeker), player_id=seeker.owner.id, magnet=seeker.magnet.strength, target=vector_to_grpc(seeker.target), @@ -67,9 +65,9 @@ def seeker_to_grpc(seeker: Seeker) -> SeekerAPI: def goal_to_seekers(goal: GoalAPI, camps: dict[str, Camp], config: Config) -> Goal: out = Goal( - id_=goal.super.id, - position=vector_to_seekers(goal.super.position), - velocity=vector_to_seekers(goal.super.velocity), + id_=goal.physical.id, + position=vector_to_seekers(goal.physical.position), + velocity=vector_to_seekers(goal.physical.velocity), mass=config.goal_mass, radius=config.goal_radius, friction=config.seeker_friction, @@ -88,7 +86,7 @@ def goal_to_seekers(goal: GoalAPI, camps: dict[str, Camp], config: Config) -> Go def goal_to_grpc(goal: Goal) -> GoalAPI: return GoalAPI( - super=physical_to_grpc(goal), + physical=physical_to_grpc(goal), camp_id=goal.owner.camp.id if goal.owner else "", time_owned=goal.time_owned ) diff --git a/seekers/net/server.py b/seekers/net/server.py index 6c97056..38191d0 100644 --- a/seekers/net/server.py +++ b/seekers/net/server.py @@ -82,7 +82,7 @@ def Command(self, request: CommandRequest, context: grpc.ServicerContext) -> Com # self._logger.debug(f"Got event for next game tick. Sending status.") command_response = copy.copy(self.current_status) - command_response.seekers_changed = len(request.commands) + #command_response.seekers_changed = len(request.commands) return command_response else: # self._logger.debug(