Skip to content
Draft
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
6 changes: 6 additions & 0 deletions pelita/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import subprocess
import sys
import time
import uuid
from warnings import warn

import zmq
Expand Down Expand Up @@ -343,6 +344,9 @@ def setup_game(team_specs, *, layout_dict, max_rounds=300, rng=None,
# Initialize the game state.

game_state = dict(
#: UUID
game_uuid=str(uuid.uuid4()),

### The layout attributes
#: Walls. Set of (int, int)
walls=set(layout_dict['walls']),
Expand Down Expand Up @@ -458,6 +462,8 @@ def setup_game(team_specs, *, layout_dict, max_rounds=300, rng=None,
controller=viewer_state['controller']
)

_logger.info("Creating game %s", game_state['game_uuid'])


# Wait until the controller tells us that it is ready
# We then can send the initial maze
Expand Down
7 changes: 7 additions & 0 deletions pelita/scripts/pelita_tournament.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ def setup():
del config["bonusmatch"]
break

res = input_choice("Should the web-viewer be activated? (publishes to tcp://127.0.0.1:5559) (y/n)", [], "yn")
if res == "y":
config['publish'] = "tcp://127.0.0.1:5559"
elif res == "n":
config['publish'] = None

print("Specify the folder where we should look for teams (or none)")
folder = input().strip()
if folder:
Expand Down Expand Up @@ -294,6 +300,7 @@ def escape(s):
winner = tournament.play_round2(config, rr_ranking, state, rng)

config.print('The winner of the %s Pelita tournament is...' % config.location, wait=2, end=" ")
config.print()
config.print('{team_group}: {team_name}. Congratulations'.format(
team_group=config.team_group(winner),
team_name=config.team_name(winner)), wait=2)
Expand Down
63 changes: 59 additions & 4 deletions pelita/tournament/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ def run_and_terminate_process(args, **kwargs):
p.kill()


def call_pelita(team_specs, *, rounds, size, viewer, seed, team_infos=None, write_replay=False, store_output=False):
def call_pelita(team_specs, *, rounds, size, viewer, seed, publish=None,
team_infos=None, write_replay=False, store_output=False):
""" Starts a new process with the given command line arguments and waits until finished.

Returns
Expand Down Expand Up @@ -134,6 +135,7 @@ def call_pelita(team_specs, *, rounds, size, viewer, seed, team_infos=None, writ
size = ['--size', size] if size else []
viewer = ['--' + viewer] if viewer else []
seed = ['--seed', seed] if seed else []
publish = ['--publish', publish] if publish else []
write_replay = ['--write-replay', write_replay] if write_replay else []
store_output = ['--store-output', store_output] if store_output else []
append_blue = ['--append-blue', team_infos[0]] if team_infos[0] else []
Expand All @@ -142,6 +144,8 @@ def call_pelita(team_specs, *, rounds, size, viewer, seed, team_infos=None, writ
cmd = [sys.executable, '-m', 'pelita.scripts.pelita_main',
team1, team2,
'--reply-to', reply_addr,
'--stop-at', '0',
*publish,
*append_blue,
*append_red,
*rounds,
Expand Down Expand Up @@ -270,6 +274,7 @@ def __init__(self, config):
self.size = config.get("size")

self.viewer = config.get("viewer")
self.publish = config.get("publish")
self.interactive = config.get("interactive")
self.statefile = config.get("statefile")

Expand All @@ -290,6 +295,13 @@ def __init__(self, config):
self.tournament_log_folder = None
self.tournament_log_file = None

if self.publish:
ctx = zmq.Context()
self.socket = ctx.socket(zmq.PUB)
self.socket.connect(self.publish)
else:
self.socket = None

@property
def team_ids(self):
return self.teams.keys()
Expand All @@ -306,6 +318,15 @@ def team_name_group(self, team):
def team_spec(self, team):
return self.teams[team]["spec"]

def send_remote(self, action, data=None):
if not self.socket:
return
if data is None:
publish_string = {"__action__": action}
else:
publish_string = {"__action__": action, "__data__": data}
self.socket.send_json(publish_string)

def _print(self, *args, **kwargs):
print(*args, **kwargs)
if self.tournament_log_file:
Expand All @@ -317,12 +338,15 @@ def print(self, *args, **kwargs):
"""Speak while you print. To disable set speak=False.
You need the program %s to be able to speak.
Set wait=X to wait X seconds after speaking."""

if len(args) == 0:
self.send_remote("SPEAK", " ".join(args))
self._print()
return
stream = io.StringIO()
wait = kwargs.pop('wait', 0.5)
want_speak = kwargs.pop('speak', None)
self.send_remote("SPEAK", " ".join(args))
if (want_speak is False) or not self.speak:
self._print(*args, **kwargs)
else:
Expand Down Expand Up @@ -382,6 +406,26 @@ def input(self, str, values=None):
except IndexError:
pass

def metadata(self):
return {
'teams': self.teams,
'location': self.location,
'date': self.date,
'rounds': self.rounds,
'size': self.size,
'greeting': self.greeting,
'farewell': self.farewell,
'host': self.host,
'seed': self.seed,
'bonusmatch': self.bonusmatch
}

def init_tournament(self):
metadata = self.metadata()
self.send_remote("INIT", metadata)

def clear_page(self):
self.send_remote("CLEAR")

def wait_for_keypress(self):
if self.interactive:
Expand Down Expand Up @@ -424,7 +468,9 @@ def load(cls, config, filename):


def present_teams(config):
config.init_tournament()
config.wait_for_keypress()
config.clear_page()
print("\33[H\33[2J") # clear the screen

greeting = config.greeting
Expand Down Expand Up @@ -453,8 +499,9 @@ def set_name(team):
print(sys.stderr)
raise


def play_game_with_config(config, teams, rng, *, match_id=None):
# TODO: Log tournament match cmdline
def play_game_with_config(config: Config, teams, rng, *, match_id=None):
config.clear_page()
team1, team2 = teams

if config.tournament_log_folder:
Expand All @@ -479,6 +526,7 @@ def play_game_with_config(config, teams, rng, *, match_id=None):
rounds=config.rounds,
size=config.size,
viewer=config.viewer,
publish=config.publish,
team_infos=team_infos,
seed=seed,
**log_kwargs)
Expand Down Expand Up @@ -508,6 +556,7 @@ def start_match(config, teams, rng, *, shuffle=False, match_id=None):
config.print('Starting match: '+ config.team_name_group(team1)+' vs ' + config.team_name_group(team2))
config.print()
config.wait_for_keypress()
config.clear_page()

(final_state, stdout, stderr) = play_game_with_config(config, teams, rng=rng, match_id=match_id)
try:
Expand Down Expand Up @@ -626,6 +675,7 @@ def play_round1(config, state, rng):
rr_played = state.round1["played"]

config.wait_for_keypress()
config.clear_page()
config.print()
config.print("ROUND 1 (Everybody vs Everybody)")
config.print('================================', speak=False)
Expand Down Expand Up @@ -655,6 +705,7 @@ def play_round1(config, state, rng):
winner = start_match_with_replay(config, match, rng=rng, match_id=match_id)
match_id.next_match()
config.wait_for_keypress()
config.clear_page()

if winner is False or winner is None:
rr_played.append({ "match": match, "winner": False })
Expand Down Expand Up @@ -697,9 +748,11 @@ def recur_match_winner(match):
def play_round2(config, teams, state, rng):
"""Run the second round and return the name of the winning team.

teams is the list [group0, group1, ...] not the names of the agens, sorted
teams is the list [group0, group1, ...] not the names of the agents, sorted
by the result of the first round.
"""
config.wait_for_keypress()
config.clear_page()
config.print()
config.print('ROUND 2 (K.O.)')
config.print('==============', speak=False)
Expand Down Expand Up @@ -729,6 +782,7 @@ def play_round2(config, teams, state, rng):
winner = start_deathmatch(config, t1_id, t2_id, rng=rng, match_id=match_id)
match.winner = winner

config.clear_page()
config.print(knockout_mode.print_knockout(last_match, config.team_name, highlight=[match]), speak=False)

state.round2["tournament"] = tournament
Expand All @@ -741,5 +795,6 @@ def play_round2(config, teams, state, rng):
match_id.next_match()

config.wait_for_keypress()
config.clear_page()

return last_match.winner
21 changes: 21 additions & 0 deletions test/test_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -1370,3 +1370,24 @@ def move(bot, state):
state = play_turn(state)
assert state['requested_moves'][1:] == [None, None, None]
assert state['requested_moves'][0] == {'previous_position': (1, 1), 'requested_position': expected_req, 'success': expected_success}

def test_games_have_different_uuid():
state1 = setup_game([dummy_bot, dummy_bot], layout_dict=parse_layout(small_layout), max_rounds=2)
state2 = setup_game([dummy_bot, dummy_bot], layout_dict=parse_layout(small_layout), max_rounds=2)

# removing internal objects
del state1['teams']
del state2['teams']
del state1['viewers']
del state2['viewers']
del state1['rng']
del state2['rng']
del state1['noisy_positions']
del state2['noisy_positions']

assert state1['game_uuid'] != state2['game_uuid']
del state1['game_uuid']
del state2['game_uuid']

# remainder of the game state is equal
assert state1 == state2
3 changes: 3 additions & 0 deletions test/test_tournament.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ def test_play_game_with_config(self):
config.viewer = 'ascii'
config.size = 'small'
config.tournament_log_folder = None
config.publish = None

teams = ["pelita/player/StoppingPlayer", "pelita/player/StoppingPlayer"]
(state, stdout, stderr) = tournament.play_game_with_config(config, teams, rng=RNG)
Expand Down Expand Up @@ -338,6 +339,7 @@ def mock_print(str="", *args, **kwargs):
config.size = 'small'
config.print = mock_print
config.tournament_log_folder = None
config.publish = None

team_ids = ["first_id", "first_id"]
result = tournament.start_match(config, team_ids, rng=RNG)
Expand Down Expand Up @@ -376,6 +378,7 @@ def mock_print(str="", *args, **kwargs):
config.size = 'small'
config.print = mock_print
config.tournament_log_folder = None
config.publish = None

result = tournament.start_deathmatch(config, *teams.keys(), rng=RNG)
assert result is not None
Expand Down
Loading