Skip to content
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add type hint.
  • Loading branch information
gianlucadecola committed Apr 11, 2022
commit 48d5f07f21331bcf08cf7e8cf05e39cd6d577207
12 changes: 7 additions & 5 deletions gym/utils/play.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import argparse
from typing import Tuple

import pygame
from pygame.event import Event

import gym
from gym import logger
from gym import Env, logger

try:
import matplotlib
Expand All @@ -20,15 +22,15 @@


class PlayableGame:
def __init__(self, env, keys_to_action=None, zoom=None):
def __init__(self, env: Env, keys_to_action: dict = None, zoom: float = None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keys_to_action: Optional[dict]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better if we can specify the key/value types on the dict (I guess values are arbitrary actions, but keys should be keypresses? how are they represented?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's Dict[Tuple[int], int] where the key is (ord(key),)

def get_keys_to_action(self):
# Control with left and right arrow keys.
return {(): 1, (276,): 0, (275,): 2, (275, 276): 1}

reference of the actions:

| Num | Observation | Value | Unit |
|-----|-------------------------------------------------------------|---------|------|
| 0 | Accelerate to the left | Inf | position (m) |
| 1 | Don't accelerate | Inf | position (m) |
| 2 | Accelerate to the right | Inf | position (m) |

gym/gym/utils/play.py

Lines 125 to 135 in 9a1d4b6

keys_to_action: dict: tuple(int) -> int or None
Mapping from keys pressed to action performed.
For example if pressed 'w' and space at the same time is supposed
to trigger action number 2 then key_to_action dict would look like this:
{
# ...
sorted(ord('w'), ord(' ')) -> 2
# ...
}
If None, default key_to_action mapping for that env is used, if provided.

self.env = env
self.relevant_keys = self._get_relevant_keys(keys_to_action)
self.video_size = self._get_video_size(zoom)
self.screen = pygame.display.set_mode(self.video_size)
self.pressed_keys = []
self.running = True

def _get_relevant_keys(self, keys_to_action):
def _get_relevant_keys(self, keys_to_action: dict) -> set:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional[dict]

if keys_to_action is None:
if hasattr(self.env, "get_keys_to_action"):
keys_to_action = self.env.get_keys_to_action()
Expand All @@ -43,7 +45,7 @@ def _get_relevant_keys(self, keys_to_action):
relevant_keys = set(sum(map(list, keys_to_action.keys()), []))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map is nice (functional programming is great), but in Python it's typically more readable to use a comprehension, so it'd be something like
set(sum(list(key) for key in keys_to_action), []))

But is this actually what we want this to do? I'm not sure what each key is meant to be (see previous comment about types), so take another look at the logic here. Intuition tells me that you might have wanted to just do set(keys_to_actions.keys()) or something like that (which might be equivalent to just set(keys_to_actions))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to explore it more in depth, this logic was already there in the old play(), it seems also to me that set(keys_to_actions.keys()) may be fine

return relevant_keys

def _get_video_size(self, zoom=None):
def _get_video_size(self, zoom: float = None) -> Tuple[int, int]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional[float]

rendered = self.env.render(mode="rgb_array")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put like a TODO here so that we remember to update this when the render API change goes through?

video_size = [rendered.shape[1], rendered.shape[0]]

Expand All @@ -52,7 +54,7 @@ def _get_video_size(self, zoom=None):

return video_size

def process_event(self, event):
def process_event(self, event: Event) -> None:
if event.type == pygame.KEYDOWN:
if event.key in self.relevant_keys:
self.pressed_keys.append(event.key)
Expand Down