Skip to content

Commit

Permalink
Project import generated by Copybara.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 260707578
  • Loading branch information
qstanczyk committed Jul 30, 2019
1 parent 9d89f79 commit 2238c15
Show file tree
Hide file tree
Showing 196 changed files with 1,548 additions and 7,577 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Numbering scheme:
Each environment release number is of the form vX.Y. X is the major version
number, Y is the minor version number. Experiment results within the same X
should not change, as modifications made to the environment are either
new features or backward compatible bug fixes. We will maintain vX branches
pointing at the most recent vX.Y

v1.1
- Add support for running multiple environment instances in a single process.
- Replaced left_players and right_players with a single players flag. This allows for controling players in both teams by a single agent (useful for self-play).
- Make ball_owned_player and ball_owned_team consistent (fix for https://github.com/google-research/football/issues/45).
- Removed paper.pdf and references to it. The paper is now at https://arxiv.org/abs/1907.11180.

v1.0 (released July 19th, 2019)
- added support for multi agent training with run_multiagent_rllib.py example.
- added enable_sides_swap parameter to create_environment, which enables random swapping of team sides for each episode. This is useful for self-play training.
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This is not an official Google product.

We'd like to thank Bastiaan Konings Schuiling, who authored and open-sourced the original version of this game.

For more information, please look at our [paper (github)](https://github.com/google-research/football/blob/master/paper.pdf).
For more information, please look at our [paper](https://arxiv.org/abs/1907.11180).

Mailing list: https://groups.google.com/forum/#!forum/google-research-football

Expand Down Expand Up @@ -213,13 +213,12 @@ directory. Have a look at existing scenarios for example.
## Multiagent support
Using play_game script (see 'Playing game yourself' section for details)
it is possible to set up a game played between multiple agents.
`left_players` and `right_players` command line parameters are
the comma-separated lists of players on the left and right teams, respectively.
`players` command line parameter is a comma-separated lists of players for both teams.
For example, to play yourself using a gamepad with two lazy bots on your team
against three bots you can run
`python3 -m gfootball.play_game --left_players=gamepad,lazy:players=2 --right_players=bot,bot,bot`.
`python3 -m gfootball.play_game --players=gamepad:left_players=1;lazy:left_players=2;bot:right_players=1;bot:right_players=1;bot:right_players=1`.

Notice the use of `players=2` for the lazy player, bot player does not support it.
Notice the use of `left_players=2` for the lazy player, bot player does not support it.

You can implement your own player controlling multiple players by adding its implementation
to the env/players directory (no other changes are needed).
Expand Down
2 changes: 1 addition & 1 deletion gfootball/build_game_engine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
set -e
# Delete pre-existing version of CMakeCache.txt to make 'pip3 install' work.
rm -f third_party/gfootball_engine/CMakeCache.txt
pushd third_party/gfootball_engine && cmake . && make -j10 && popd
pushd third_party/gfootball_engine && cmake . && make -j && popd
pushd third_party/gfootball_engine && ln -sf libgame.so _gameplayfootball.so && popd
53 changes: 25 additions & 28 deletions gfootball/env/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from __future__ import division
from __future__ import print_function


from gfootball.env import config
from gfootball.env import football_env
from gfootball.env import observation_preprocessing
Expand All @@ -28,17 +27,16 @@
def create_environment(env_name='',
stacked=False,
representation='extracted',
with_checkpoints=False,
rewards='scoring',
enable_goal_videos=False,
enable_full_episode_videos=False,
render=False,
write_video=False,
dump_frequency=1,
logdir='',
data_dir=None,
font_file=None,
right_players=None,
number_of_players_agent_controls=1,
extra_players=None,
number_of_left_players_agent_controls=1,
number_of_right_players_agent_controls=0,
enable_sides_swap=False,
channel_dimensions=(
observation_preprocessing.SMM_WIDTH,
Expand Down Expand Up @@ -91,9 +89,8 @@ def create_environment(env_name='',
CornerMode, ThrowInMode, PenaltyMode}.
Can only be used when the scenario is a flavor of normal game
(i.e. 11 versus 11 players).
with_checkpoints: True to add intermediate checkpoint rewards to guide
the agent to move to the opponent goal.
If False, only scoring provides a reward.
rewards: Comma separated list of rewards to be added.
Currently supported rewards are 'scoring' and 'checkpoints'.
enable_goal_videos: whether to dump traces up to 200 frames before goals.
enable_full_episode_videos: whether to dump traces for every episode.
render: whether to render game frames.
Expand All @@ -103,14 +100,13 @@ def create_environment(env_name='',
dump_frequency: how often to write dumps/videos (in terms of # of episodes)
Sub-sample the episodes for which we dump videos to save some disk space.
logdir: directory holding the logs.
data_dir: location of the game engine data
Safe to leave as the default value.
font_file: location of the game font file
Safe to leave as the default value.
right_players: A list of right players (adversary) to use in the environment.
Reserved for future usage to provide an opponent to train against.
(which could be used for self-play).
number_of_players_agent_controls: Number of players an agent controls.
extra_players: A list of extra players to use in the environment.
Each player is defined by a string like:
"$player_name:left_players=?,right_players=?,$param1=?,$param2=?...."
number_of_left_players_agent_controls: Number of left players an agent
controls.
number_of_right_players_agent_controls: Number of right players an agent
controls.
enable_sides_swap: Whether to randomly pick a field side at the beginning of
each episode for the team that the agent controls.
channel_dimensions: (width, height) tuple that represents the dimensions of
Expand All @@ -119,27 +115,26 @@ def create_environment(env_name='',
Google Research Football environment.
"""
assert env_name
if right_players is None:
right_players = []
players = [('agent:left_players=%d,right_players=%d' % (
number_of_left_players_agent_controls,
number_of_right_players_agent_controls))]
if extra_players is not None:
players.extend(extra_players)
c = config.Config({
'enable_sides_swap': enable_sides_swap,
'dump_full_episodes': enable_full_episode_videos,
'dump_scores': enable_goal_videos,
'left_players': [('agent:players=%d' % number_of_players_agent_controls)],
'players': players,
'level': env_name,
'render': render,
'tracesdir': logdir,
'write_video': write_video,
'right_players': right_players,
})
if data_dir:
c['data_dir'] = data_dir
if font_file:
c['font_file'] = font_file
env = football_env.FootballEnv(c)
if dump_frequency > 1:
env = wrappers.PeriodicDumpWriter(env, dump_frequency)
if with_checkpoints:
assert 'scoring' in rewards.split(',')
if 'checkpoints' in rewards.split(','):
env = wrappers.CheckpointRewardWrapper(env)
if representation.startswith('pixels'):
env = wrappers.PixelsStateWrapper(env, 'gray' in representation,
Expand All @@ -150,8 +145,10 @@ def create_environment(env_name='',
env = wrappers.SMMWrapper(env, channel_dimensions)
else:
raise ValueError('Unsupported representation: {}'.format(representation))
if number_of_players_agent_controls == 1:
env = wrappers.SingleAgentWrapper(env)
if (number_of_left_players_agent_controls +
number_of_right_players_agent_controls == 1):
env = wrappers.SingleAgentObservationWrapper(env)
env = wrappers.SingleAgentRewardWrapper(env)
if stacked:
# Import FrameStack here to avoid unconditional dependence on baselines.
from baselines.common.atari_wrappers import FrameStack
Expand Down
61 changes: 29 additions & 32 deletions gfootball/env/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import copy
import logging
import os
import sys
import traceback

Expand Down Expand Up @@ -62,30 +61,39 @@ def parse_player_definition(definition):
Returns:
A tuple (name, dict).
"""
if ':' not in definition:
return definition, {}

(name, params) = definition.split(':')
d = {}
for param in params.split(','):
(key, value) = param.split('=')
d[key] = value
name = definition
d = {'left_players': 0,
'right_players': 0}
if ':' in definition:
(name, params) = definition.split(':')
for param in params.split(','):
(key, value) = param.split('=')
d[key] = value
if d['left_players'] == 0 and d['right_players'] == 0:
d['left_players'] = 1
return name, d


def parse_number_of_players(definition):
def count_players(definition):
"""Returns a number of players given a definition."""
return int(parse_player_definition(definition)[1].get('players', 1))
_, player_definition = parse_player_definition(definition)
return (int(player_definition['left_players']) +
int(player_definition['right_players']))


def get_number_of_players(players):
"""Returns a total number of players controlled."""
return sum([parse_number_of_players(player) for player in players])
def count_left_players(definition):
"""Returns a number of left players given a definition."""
return int(parse_player_definition(definition)[1]['left_players'])


def count_right_players(definition):
"""Returns a number of players given a definition."""
return int(parse_player_definition(definition)[1]['right_players'])


def get_agent_number_of_players(players):
"""Returns a total number of players controlled by an agent."""
return sum([parse_number_of_players(player) for player in players
return sum([count_players(player) for player in players
if player.startswith('agent')])


Expand All @@ -94,42 +102,33 @@ class Config(object):
def __init__(self, values=None):
self._values = {
'action_set': 'default',
'right_players': [],
'data_dir':
os.path.abspath(os.path.join(os.path.dirname(libgame.__file__),
'data')),
'enable_sides_swap': False,
'font_file':
os.path.abspath(os.path.join(os.path.dirname(libgame.__file__),
'fonts', 'AlegreyaSansSC-ExtraBold.ttf')),
'display_game_stats': True,
'dump_full_episodes': False,
'dump_scores': False,
'game_difficulty': 0.6,
'left_players': ['agent:players=1'],
'players': ['agent:left_players=1'],
'level': '11_vs_11_stochastic',
'physics_steps_per_frame': 10,
'real_time': False,
'render': False,
'tracesdir': '/tmp/dumps',
'write_video': False
}
if 'GFOOTBALL_DATA_DIR' in os.environ:
self._values['data_dir'] = os.environ['GFOOTBALL_DATA_DIR']
if 'GFOOTBALL_FONT' in os.environ:
self._values['font_file'] = os.environ['GFOOTBALL_FONT']
if values:
self._values.update(values)
self.NewScenario()

def number_of_left_players(self):
return get_number_of_players(self._values['left_players'])
return sum([count_left_players(player)
for player in self._values['players']])

def number_of_right_players(self):
return get_number_of_players(self._values['right_players'])
return sum([count_right_players(player)
for player in self._values['players']])

def number_of_players_agent_controls(self):
return get_agent_number_of_players(self._values['left_players'])
return get_agent_number_of_players(self._values['players'])

def __eq__(self, other):
assert isinstance(other, self.__class__)
Expand Down Expand Up @@ -166,8 +165,6 @@ def GameConfig(self):
cfg.render_mode = libgame.e_RenderingMode.e_Onscreen if self[
'render'] else libgame.e_RenderingMode.e_Disabled
cfg.high_quality = self['render']
cfg.data_dir = self['data_dir']
cfg.font_file = self['font_file']
cfg.physics_steps_per_frame = self['physics_steps_per_frame']
return cfg

Expand Down
Loading

0 comments on commit 2238c15

Please sign in to comment.