Skip to content

Commit

Permalink
Merge pull request #825 from otizonaizit/use_dead_ends
Browse files Browse the repository at this point in the history
  • Loading branch information
Debilski authored Oct 3, 2024
2 parents 2f03fb4 + 46efdd8 commit 7aa1985
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 16 deletions.
3 changes: 3 additions & 0 deletions pelita/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#: Food pellet shadow distance
SHADOW_DISTANCE = 1

#: Proportion of layouts with dead ends
DEAD_ENDS = 0.25

class TkViewer:
def __init__(self, *, address, controller, geometry=None, delay=None, stop_after=None, fullscreen=False):
self.proc = self._run_external_viewer(address, controller, geometry=geometry, delay=delay, stop_after=stop_after, fullscreen=fullscreen)
Expand Down
28 changes: 16 additions & 12 deletions pelita/layout.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import importlib.resources as importlib_resources
import io
import os
import random

# bot to index conversion
Expand All @@ -9,7 +10,7 @@

RNG = random.Random()

def get_random_layout(size='normal', seed=None, dead_ends=False):
def get_random_layout(size='normal', seed=None, dead_ends=0):
""" Return a random layout string from the available ones.
Parameters
Expand All @@ -23,9 +24,9 @@ def get_random_layout(size='normal', seed=None, dead_ends=False):
'big' -> width=64, height=32, food=60
'all' -> all of the above
dead_ends: bool
if set, return a layout from the collection with dead_ends, otherwise
return a layout without dead_ends
dead_ends: float
Return a layout from the collection with dead ends with probabilty dead_ends.
By default never return a layout with dead_ends.
Returns
-------
Expand All @@ -35,7 +36,10 @@ def get_random_layout(size='normal', seed=None, dead_ends=False):
"""
if seed is not None:
RNG.seed(seed)
layouts_names = get_available_layouts(size=size, dead_ends=dead_ends)
if dead_ends and RNG.random() < dead_ends:
layouts_names = get_available_layouts(size=size, dead_ends=True)
else:
layouts_names = get_available_layouts(size=size, dead_ends=False)
layout_choice = RNG.choice(layouts_names)
return layout_choice, get_layout_by_name(layout_choice)

Expand Down Expand Up @@ -71,13 +75,13 @@ def get_available_layouts(size='normal', dead_ends=False):
size = ''

av_layouts = []
for resource in importlib_resources.files('pelita._layouts').iterdir():
if resource.is_file() and resource.name.endswith('.layout') and size in resource.name:
layout_name = resource.name.removesuffix('.layout')
if dead_ends and 'dead_ends' in resource.name:
av_layouts.append(layout_name)
if not dead_ends and 'dead_ends' not in resource.name:
av_layouts.append(layout_name)
for file in os.listdir(importlib_resources.files('pelita._layouts')):
if dead_ends:
cond = file.endswith('.layout') and size in file and 'dead_ends' in file
else:
cond = file.endswith('.layout') and size in file and 'dead_ends' not in file
if cond:
av_layouts.append(file.removesuffix('.layout'))

return sorted(av_layouts)

Expand Down
6 changes: 4 additions & 2 deletions pelita/scripts/pelita_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import zmq

import pelita
from pelita.game import DEAD_ENDS
from .script_utils import start_logging

from pelita.network import PELITA_PORT
Expand Down Expand Up @@ -324,7 +325,8 @@ def main():
sys.exit(0)

if args.list_layouts:
layouts = pelita.layout.get_available_layouts(size='all')
layouts = pelita.layout.get_available_layouts(size='all', dead_ends=False)
layouts += pelita.layout.get_available_layouts(size='all', dead_ends=True)
layouts.sort()
print('\n'.join(layouts))
sys.exit(0)
Expand Down Expand Up @@ -447,7 +449,7 @@ def main():
layout_name = args.layout
layout_string = pelita.layout.get_layout_by_name(args.layout)
else:
layout_name, layout_string = pelita.layout.get_random_layout(args.size, seed=seed)
layout_name, layout_string = pelita.layout.get_random_layout(args.size, seed=seed, dead_ends=DEAD_ENDS)

print("Using layout '%s'" % layout_name)

Expand Down
4 changes: 2 additions & 2 deletions pelita/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


from .team import make_bots, create_homezones
from .game import split_food, SHADOW_DISTANCE
from .game import split_food, SHADOW_DISTANCE, DEAD_ENDS
from .layout import (get_random_layout, get_layout_by_name, get_available_layouts,
parse_layout, BOT_N2I, initial_positions)
from .gamestate_filters import manhattan_dist
Expand All @@ -20,7 +20,7 @@ def _parse_layout_arg(*, layout=None, food=None, bots=None, seed=None):

# prepare layout argument to be passed to pelita.game.run_game
if layout is None:
layout_name, layout_str = get_random_layout(size='normal', seed=seed)
layout_name, layout_str = get_random_layout(size='normal', seed=seed, dead_ends=DEAD_ENDS)
layout_dict = parse_layout(layout_str)
elif layout in get_available_layouts(size='all'):
# check if this is a built-in layout
Expand Down
17 changes: 17 additions & 0 deletions test/test_layout.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest

import itertools
import math
import random
from pathlib import Path
from textwrap import dedent

Expand Down Expand Up @@ -69,6 +71,21 @@ def test_get_random_layout_random_seed():
name, layout = get_random_layout(size='small', seed=1)
assert name == 'small_017'

def test_get_random_layout_proportion_dead_ends():
N = 1000
prop = 0.25
expected = int(prop*N)
# get a fix sequence of seeds, so that the test is reproducible
RNG = random.Random()
RNG.seed(176399)
seeds = [RNG.random() for i in range(N)]
# check that we don't get any layout with dead ends if we don't ask for it
assert not any('dead_ends' in get_random_layout(seed=s)[0] for s in seeds)
# check that we get more or less the right proportion of layouts with dead ends
dead_ends = sum('dead_ends' in get_random_layout(seed=s, dead_ends=prop)[0] for s in seeds)
assert math.isclose(dead_ends, expected, rel_tol=0.1)


def test_legal_layout():
layout = """
######
Expand Down

0 comments on commit 7aa1985

Please sign in to comment.