Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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]
Expand Down
27 changes: 27 additions & 0 deletions run_via_grpc.py
Original file line number Diff line number Diff line change
@@ -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()
24 changes: 12 additions & 12 deletions seekers/net/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.")

Expand Down Expand Up @@ -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)
Expand All @@ -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

Expand All @@ -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

Expand All @@ -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 = {}
Expand All @@ -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
}

Expand Down
20 changes: 9 additions & 11 deletions seekers/net/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,20 @@
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:
return Vector2DAPI(x=vector.x, y=vector.y)


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,
Expand All @@ -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),
Expand All @@ -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,
Expand All @@ -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
)
Expand Down
2 changes: 1 addition & 1 deletion seekers/net/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading