Skip to content
Snippets Groups Projects
Commit e08b8b22 authored by Fabian Heinrich's avatar Fabian Heinrich
Browse files

Formatting all files

parent 93f53b27
No related branches found
No related tags found
1 merge request!2Resolve "2D movement continuous"
......@@ -2,8 +2,8 @@ import numpy as np
class Counter:
"""Simple class for a counter at a specified position (center of counter). Can hold things on top.
"""
"""Simple class for a counter at a specified position (center of counter). Can hold things on top."""
def __init__(self, pos: np.array):
self.pos = pos
self.occupied_by = None
......
from overcooked_simulator.player import Player
import sys
from pathlib import Path
from overcooked_simulator.player import Player
from overcooked_simulator.pygame_gui import PyGameGUI
from overcooked_simulator.simulation_runner import Simulator
def main():
......
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
......@@ -10,12 +11,16 @@ from overcooked_simulator.counters import Counter
class Action:
"""Action class, specifies player, action type and action itself.
"""
"""Action class, specifies player, action type and action itself."""
def __init__(self, player, act_type, action):
self.player = player
self.act_type = act_type
assert self.act_type in ["movement", "pickup", "interact"], "Unknown action type"
assert self.act_type in [
"movement",
"pickup",
"interact",
], "Unknown action type"
self.action = action
......@@ -89,7 +94,9 @@ class Environment:
Returns: The closest counter for the given point.
"""
counter_distances = distance_matrix([point], [counter.pos for counter in self.counters])[0]
counter_distances = distance_matrix(
[point], [counter.pos for counter in self.counters]
)[0]
closest_counter_idx = np.argmin(counter_distances)
return self.counters[closest_counter_idx]
......@@ -177,8 +184,11 @@ class Environment:
Returns: True if the player is intersecting with any object in the environment.
"""
return (self.detect_player_collision(player) or self.detect_collision_counters(player) or
self.detect_collision_world_bounds(player))
return (
self.detect_player_collision(player)
or self.detect_collision_counters(player)
or self.detect_collision_world_bounds(player)
)
def detect_player_collision(self, player: Player):
"""Detects collisions between the queried player and other players.
......@@ -207,7 +217,12 @@ class Environment:
Returns: True if the player collides with any counter, False if not.
"""
return any(map(lambda counter: self.detect_collision_player_counter(player, counter), self.counters))
return any(
map(
lambda counter: self.detect_collision_player_counter(player, counter),
self.counters,
)
)
def detect_collision_player_counter(self, player: Player, counter: Counter):
"""Checks if the player and counter collide (overlap).
......@@ -239,12 +254,14 @@ class Environment:
Returns: True if the player touches the world bounds, False if not.
"""
collisions_lower = any((player.pos - player.radius) < 0)
collisions_upper = any((player.pos + player.radius) > [self.world_width, self.world_height])
collisions_upper = any(
(player.pos + player.radius) > [self.world_width, self.world_height]
)
return collisions_lower or collisions_upper
def step(self):
"""Performs a step of the environment. Affects time based events such as cooking or cutting things, orders
and timelimits.
and time limits.
"""
pass
......@@ -254,9 +271,7 @@ class Environment:
Returns: Dict of lists of the current relevant game objects.
"""
return {"players": self.players,
"counters": self.counters,
"score": self.score}
return {"players": self.players, "counters": self.counters, "score": self.score}
def get_state_json(self):
"""Get the current state of the game environment as a json-like nested dictionary.
......
import numpy as np
from overcooked_simulator.counters import Counter
......@@ -8,6 +9,7 @@ class Player:
This class handles interactions with counters and objects.
"""
def __init__(self, name, pos):
self.name = name
self.pos = np.array(pos, dtype=float)
......
import pygame
import numpy as np
import pygame
from overcooked_simulator.overcooked_environment import Action
from overcooked_simulator.simulation_runner import Simulator
WHITE = (255, 255, 255)
GREY = (190, 190, 190)
BLACK = (0, 0, 0)
......@@ -14,6 +14,7 @@ RED = (255, 0, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
BACKGROUND_COLOR = GREY
BACKGROUND_LINES = (200, 200, 200)
class PlayerKeyset:
......@@ -22,28 +23,44 @@ class PlayerKeyset:
5th key is for interacting with counters.
6th key ist for picking up things or dropping them.
"""
def __init__(self, keys: list[pygame.key]):
self.player_keys = keys
self.move_vectors = [[-1, 0], [1, 0], [0, -1], [0, 1]]
self.key_to_movement = {key: vec for (key, vec) in zip(self.player_keys[:-2], self.move_vectors)}
self.key_to_movement = {
key: vec for (key, vec) in zip(self.player_keys[:-2], self.move_vectors)
}
self.interact_key = self.player_keys[-2]
self.pickup_key = self.player_keys[-1]
class PyGameGUI:
"""Visualisation of the overcooked environmnent and reading keyboard inputs using pygame.
"""
"""Visualisation of the overcooked environmnent and reading keyboard inputs using pygame."""
def __init__(self, simulator: Simulator):
self.FPS = 60
self.simulator = simulator
self.counter_size = self.simulator.env.counter_side_length
self.window_width, self.window_height = simulator.env.world_width, simulator.env.world_height
self.window_width, self.window_height = (
simulator.env.world_width,
simulator.env.world_height,
)
self.GET_CONTINOUS_INTERACT_AND_PICKUP = False
keys1 = [pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN, pygame.K_SPACE, pygame.K_i]
keys1 = [
pygame.K_LEFT,
pygame.K_RIGHT,
pygame.K_UP,
pygame.K_DOWN,
pygame.K_SPACE,
pygame.K_i,
]
keys2 = [pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s, pygame.K_f, pygame.K_e]
self.player_keysets: list[PlayerKeyset] = [PlayerKeyset(keys1), PlayerKeyset(keys2)]
self.player_keysets: list[PlayerKeyset] = [
PlayerKeyset(keys1),
PlayerKeyset(keys2),
]
def send_action(self, action: Action):
"""Sends an action to the game environment.
......@@ -68,14 +85,14 @@ class PyGameGUI:
if np.linalg.norm(move_vec) != 0:
move_vec = move_vec / np.linalg.norm(move_vec)
action = Action(f"p{player_idx+1}", "movement", move_vec)
action = Action(f"p{player_idx + 1}", "movement", move_vec)
self.send_action(action)
if self.GET_CONTINOUS_INTERACT_AND_PICKUP:
if relevant_keys[-2]:
action = Action(f"p{player_idx+1}", "interact", "interact")
action = Action(f"p{player_idx + 1}", "interact", "interact")
self.send_action(action)
if relevant_keys[-1]:
action = Action(f"p{player_idx+1}", "pickup", "pickup")
action = Action(f"p{player_idx + 1}", "pickup", "pickup")
self.send_action(action)
def handle_interact_single_send(self, event):
......@@ -94,17 +111,15 @@ class PyGameGUI:
self.send_action(action)
def draw_background(self):
"""Visualizes a game background.
"""
BACKGROUND_LINES = (200, 200, 200)
block_size = self.counter_size//2 # Set the size of the grid block
"""Visualizes a game background."""
block_size = self.counter_size // 2 # Set the size of the grid block
for x in range(0, self.window_width, block_size):
for y in range(0, self.window_height, block_size):
rect = pygame.Rect(x, y, block_size, block_size)
pygame.draw.rect(self.screen, BACKGROUND_LINES, rect, 1)
def draw_players(self, state):
"""Visualizes the players as circles with an triangle for the facing diretion.
"""Visualizes the players as circles with a triangle for the facing diretion.
Args:
state: The game state returned by the environment.
......@@ -121,9 +136,15 @@ class PyGameGUI:
facing = player.facing_direction
pygame.draw.polygon(self.screen, BLUE,
((pos[0]+(facing[1]*5), pos[1]-(facing[0]*5)),
(pos[0]-(facing[1]*5), pos[1]+(facing[0]*5)), player.pos + (facing * 20)))
pygame.draw.polygon(
self.screen,
BLUE,
(
(pos[0] + (facing[1] * 5), pos[1] - (facing[0] * 5)),
(pos[0] - (facing[1] * 5), pos[1] + (facing[0] * 5)),
player.pos + (facing * 20),
),
)
def draw_counters(self, state):
"""Visualizes the counters in the environment.
......@@ -132,9 +153,12 @@ class PyGameGUI:
state: The game state returned by the environment.
"""
for idx, counter in enumerate(state["counters"]):
counter_rect_outline = pygame.Rect(counter.pos[0] - (self.counter_size / 2),
counter.pos[1] - (self.counter_size / 2), self.counter_size,
self.counter_size)
counter_rect_outline = pygame.Rect(
counter.pos[0] - (self.counter_size / 2),
counter.pos[1] - (self.counter_size / 2),
self.counter_size,
self.counter_size,
)
pygame.draw.rect(self.screen, COUNTERCOLOR, counter_rect_outline)
......@@ -153,8 +177,7 @@ class PyGameGUI:
pygame.display.flip()
def start_pygame(self):
"""Starts pygame and the gui loop. Each frame the gamestate is visualized and keyboard inputs are read.
"""
"""Starts pygame and the gui loop. Each frame the gamestate is visualized and keyboard inputs are read."""
pygame.init()
pygame.font.init()
......@@ -167,7 +190,6 @@ class PyGameGUI:
# Game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
......
from threading import Thread
import time
from threading import Thread
from overcooked_simulator.overcooked_environment import Environment, Action
from overcooked_simulator.player import Player
......@@ -27,68 +28,67 @@ class Simulator(Thread):
super().__init__()
def step(self):
"""One simulation step of the environment.
"""
"""One simulation step of the environment."""
self.env.step()
def enter_action(self, action: Action):
"""Takes an action and executes it in the environment.
Args:
action (Action): The action object to be executed.
"""
Args:
action (Action): The action object to be executed.
"""
self.env.perform_action(action)
def get_state(self):
"""Get the current gamestate as python objects.
Returns:
The current state of the game. Currently as dict with lists of environment objects.
"""
Returns:
The current state of the game. Currently as dict with lists of environment objects.
"""
return self.env.get_state()
def get_state_json(self):
"""Get the current gamestate in json-like dict.
Returns:
The gamestate encoded in a json style nested dict.
"""
Returns:
The gamestate encoded in a json style nested dict.
"""
return self.env.get_state_json()
def register_player(self, player: Player):
print(f"Added player {player.name} to the game.")
"""Adds a player to the environment.
Args:
player: The player to be added.
"""
Args:
player: The player to be added.
"""
print(f"Added player {player.name} to the game.")
self.env.players[player.name] = player
def register_players(self, players: list[Player]):
"""Registers multiple players from a list
Args:
players: List of players to be added.
"""
Args:
players: List of players to be added.
"""
for p in players:
self.register_player(p)
def run(self):
"""Starts the simulator thread. Runs in a loop until stopped.
"""
"""Starts the simulator thread. Runs in a loop until stopped."""
overslept_in_ns = 0
while not self.finished:
step_start = time.time_ns()
self.step()
step_duration = time.time_ns() - step_start
time_to_sleep_ns = self.prefered_sleeptime_ns - (step_duration + overslept_in_ns)
time_to_sleep_ns = self.prefered_sleeptime_ns - (
step_duration + overslept_in_ns
)
sleep_start = time.time_ns()
time.sleep(max(time_to_sleep_ns / 1e9, 0))
......@@ -96,7 +96,6 @@ class Simulator(Thread):
overslept_in_ns = sleep_function_duration - time_to_sleep_ns
def stop(self):
"""Stops the simulator
"""
"""Stops the simulator"""
print("Stopping the simulation.")
self.finished = True
from overcooked_simulator.simulation_runner import Simulator
from overcooked_simulator.player import Player
from overcooked_simulator.overcooked_environment import Environment, Action
import numpy as np
import time
from pathlib import Path
import numpy as np
from overcooked_simulator.counters import Counter
from overcooked_simulator.player import Player
from overcooked_simulator.simulation_runner import Simulator
def test_player_registration():
......@@ -51,8 +49,8 @@ def test_simulator_frequency():
print(sim.env.c)
accepted_tolerance = 0.02
lower = frequency * running_time_seconds * (1-accepted_tolerance)
upper = frequency * running_time_seconds * (1+accepted_tolerance)
lower = frequency * running_time_seconds * (1 - accepted_tolerance)
upper = frequency * running_time_seconds * (1 + accepted_tolerance)
assert lower < sim.env.c < upper, "Timing error in the environment at 1000hz"
......@@ -73,11 +71,16 @@ def test_collision_detection():
assert not sim.env.detect_collision(player1), "Does not collide yet."
player1.move_abs(counter_pos)
assert sim.env.detect_collision_counters(player1), "Player and counter at same pos. Not detected."
assert sim.env.detect_collision_counters(
player1
), "Player and counter at same pos. Not detected."
player2.move_abs(counter_pos)
assert sim.env.detect_player_collision(player1), "Players at same pos. Not detected."
assert sim.env.detect_player_collision(
player1
), "Players at same pos. Not detected."
player1.move_abs(np.array([0, 0]))
assert sim.env.detect_collision_world_bounds(player1), "Player collides with world bounds."
assert sim.env.detect_collision_world_bounds(
player1
), "Player collides with world bounds."
sim.stop()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment