In [1]:
import sys
sys.path.append("..")
import cave_dweller
import cave_dweller.libtcodpy as libtcod
import cave_dweller.colors as colors

In [2]:
import yaml
from collections import namedtuple

In [3]:
tiles_meta = """
# ------ META INFORMATION about tiles ------
# Defaults for all tiles - required
DEFAULTS:
  char: SPACE
  readable_name: null
  is_obstacle: false
  fg: BLACK
  bg: null
  adjacent_hidden: false
  diggable: false
  dig_to: null
  buildable: false
  build_to: null
  tile_class: default
  tag: ""
  name: None
  
# Blocks to be used in world generation - required
GENERATION:
 ground_blocks:
  - use_tag: GROUND
 wall_blocks:
  - use_class: WALL

# Required
TRANSITIONS:
 BUILD:
    - char: 176
    - char: 177
    - char: 178
 DIG:
    - char: 178
    - char: 177
    - char: 176     
"""

In [4]:
tiles = """
ground:
 tile_class: GROUND
 tag: reg_ground
 readable_name: Ground
 # This will generate three similar instances of this block
 char: ['-', '.', '`']
 fg: GRAY
 bg: DARKEST_GRAY
 buildable: true
 build_to: wall
 
wall:
 tile_class: WALL
 readable_name: Limestone
 diggable: true
 buildable: false
 char: 'x'
 dig_to: ground
 
muddy_ground:
 inherits: ground
 bg: LIGHT_BROWN
 # XXX biomes are not actually implemented yet
 biome: muddy
"""

In [5]:
color_lookup = {}

color_lookup['black'] = colors.black
color_lookup['gray'] = colors.gray
color_lookup['darkest_gray'] = colors.darkest_gray
color_lookup['light_brown'] = colors.sepia

def translate_color(color_str_raw):
    if color_str_raw is None:
        return None
    color_str = color_str_raw.lower()
    return color_lookup[color_str]

In [6]:
def translate_char(char_str):
    if char_str is None:
        return
    if isinstance(char_str, int):
        return char_str
    if char_str == "SPACE":
        return ord(' ')
    elif len(char_str) == 1:
        return ord(char_str)
    else:
        raise RuntimeError("{char} cannot be translated".format(char=char_str))

In [7]:
tile_meta_dict = yaml.load(tiles_meta)

In [8]:
tile_meta_dict['DEFAULTS'].keys()


Out[8]:
['bg',
 'name',
 'fg',
 'diggable',
 'adjacent_hidden',
 'readable_name',
 'build_to',
 'char',
 'buildable',
 'tile_class',
 'is_obstacle',
 'tag',
 'dig_to']

In [9]:
tile_meta_dict['DEFAULTS'].values()


Out[9]:
[None,
 'None',
 'BLACK',
 False,
 False,
 None,
 None,
 'SPACE',
 False,
 'default',
 False,
 '',
 None]

In [10]:
tile_namedtuple_defaults = tile_meta_dict['DEFAULTS'].copy()
tile_namedtuple_defaults['fg'] = translate_color(tile_meta_dict['DEFAULTS']['fg'])
tile_namedtuple_defaults['bg'] = translate_color(tile_meta_dict['DEFAULTS']['bg'])
tile_namedtuple_defaults['char'] = translate_char(tile_meta_dict['DEFAULTS']['char'])

In [11]:
tile_namedtuple_defaults.keys()


Out[11]:
['bg',
 'name',
 'diggable',
 'adjacent_hidden',
 'readable_name',
 'build_to',
 'char',
 'buildable',
 'is_obstacle',
 'tile_class',
 'fg',
 'tag',
 'dig_to']

In [12]:
len(tile_meta_dict['TRANSITIONS']['BUILD'])


Out[12]:
3

In [74]:
class ConfigurationError(Exception):
    pass

def load_tiles(tiles_dict, tile_meta_dict, tile_builder):
    tile_lookup = {}
    for tile_name_base in tiles_dict:
        for tile_name, translated_tile in translate_tile(tile_name_base,
                                                         tiles_dict,
                                                         tile_meta_dict,
                                                         tile_builder):
            tile_lookup[tile_name] = translated_tile
    return tile_lookup
        
def translate_tile(tile_name_base, tiles_dict, tiles_meta, tile_builder):
        
        cur_tile = tiles_dict[tile_name_base]
        if 'inherits' in cur_tile:
            cur_tile = tiles_dict[cur_tile['inherits']].copy()
            if 'tag' in cur_tile:
                del cur_tile['tag'] 
            cur_tile.update(tiles_dict[tile_name_base])
        char = cur_tile.get('char')
        namedtuple_args = {}
        if 'fg' in cur_tile:
            namedtuple_args['fg'] = translate_color(cur_tile['fg'])
        if 'bg' in cur_tile:
            namedtuple_args['bg'] = translate_color(cur_tile['bg'])
        copy_args = ['diggable', 'adjacent_hidden', 'readable_name', 'buildable', 'is_obstacle', 'tile_class', 'tag']
        if 'build_to' in cur_tile:
            if cur_tile.get('buildable') != True:
                raise ConfigurationError("buildable must be true to specify build_to")
        if 'dig_to' in cur_tile:
            if cur_tile.get('diggable') != True:
                raise ConfigurationError("diggable must be true to specify dig_to")
                
        build_to = cur_tile.get('build_to')
        dig_to = cur_tile.get('dig_to')
                
        for arg in copy_args:
            if arg in cur_tile:
                namedtuple_args[arg] = cur_tile[arg]

        input_blueprints = []
        # One codepath for character variation tiles
        if not isinstance(char, list):
            char = [char]
        for variation_index, char_variation in enumerate(char):
            tile_b = namedtuple_args.copy()
            tile_b['char'] = translate_char(char_variation)
            if tile_b['char'] is None:
                del tile_b['char']
            if tile_b.get('buildable') == True:
                tile_b['build_to'] = name_build(tile_name_base, variation_index, 0)
            if tile_b.get('diggable') == True:
                tile_b['dig_to'] = name_dig(tile_name_base, variation_index, 0)
            input_blueprints.append(tile_b)                     
                    
        for index, tile in enumerate(input_blueprints):
            tile['name'] = get_name(tile_name_base, index)
            yield tile['name'], tile_builder(**tile)
            
        for blueprint_index, blueprint in enumerate(input_blueprints):
            if 'tag' in blueprint:
                del blueprint['tag']
            if blueprint.get('buildable') == True:
                next_index = range(1, len(tiles_meta['TRANSITIONS']['BUILD']))
                for index, transition in enumerate(tiles_meta['TRANSITIONS']['BUILD']):                    
                    prev = blueprint['name'] if index == 0 else name
                    name = name_build(tile_name_base, blueprint_index, index)
                    tile_b = blueprint.copy()
                    tile_b['char'] = translate_char(transition['char'])
                    try:
                        tile_b['build_to'] = name_build(tile_name_base, blueprint_index, next_index[index])
                    except IndexError:
                        tile_b['build_to'] = build_to
                    tile_b['dig_to'] = prev
                    tile_b['name'] = name
                    yield name, tile_builder(**tile_b)
            if blueprint.get('diggable') == True:
                next_index = range(1, len(tiles_meta['TRANSITIONS']['DIG']))
                for index, transition in enumerate(tiles_meta['TRANSITIONS']['DIG']):                    
                    prev = blueprint['name'] if index == 0 else name
                    name = name_dig(tile_name_base, blueprint_index, index)
                    try:
                        tile_b['dig_to'] = name_dig(tile_name_base, blueprint_index, next_index[index])
                    except IndexError:
                        tile_b['dig_to'] = dig_to
                    tile_b['build_to'] = prev
                    tile_b['name'] = name
                    yield name, tile_builder(**tile_b)
                    
def get_name(base_name, variation_index):   
    return base_name + str(variation_index) if variation_index>0 else base_name

def name_build(base_name, variation_index, index):
    return ''.join([get_name(base_name, variation_index), '_build', str(index)])

def name_dig(base_name, variation_index, index):
    return ''.join([get_name(base_name, variation_index), '_dig', str(index)])

In [75]:
Tile = namedtuple('Tile', tile_namedtuple_defaults.keys())
Tile.__new__.__defaults__ = tuple(tile_namedtuple_defaults.values())

In [76]:
tiles_dict = yaml.load(tiles)

In [77]:
tile_lookup = load_tiles(tiles_dict, tile_meta_dict, Tile)

In [78]:
any_ground = [tile for tile in tile_lookup.values() if tile.tag.lower()=='reg_ground']

In [79]:
tile_lookup


Out[79]:
{'ground': Tile(bg=Color(31,31,31), name='ground', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground_build0', char=45, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='reg_ground', dig_to=None),
 'ground1': Tile(bg=Color(31,31,31), name='ground1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground1_build0', char=46, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='reg_ground', dig_to=None),
 'ground1_build0': Tile(bg=Color(31,31,31), name='ground1_build0', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground1_build1', char=176, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground1'),
 'ground1_build1': Tile(bg=Color(31,31,31), name='ground1_build1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground1_build2', char=177, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground1_build0'),
 'ground1_build2': Tile(bg=Color(31,31,31), name='ground1_build2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='wall', char=178, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground1_build1'),
 'ground2': Tile(bg=Color(31,31,31), name='ground2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground2_build0', char=96, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='reg_ground', dig_to=None),
 'ground2_build0': Tile(bg=Color(31,31,31), name='ground2_build0', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground2_build1', char=176, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground2'),
 'ground2_build1': Tile(bg=Color(31,31,31), name='ground2_build1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground2_build2', char=177, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground2_build0'),
 'ground2_build2': Tile(bg=Color(31,31,31), name='ground2_build2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='wall', char=178, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground2_build1'),
 'ground_build0': Tile(bg=Color(31,31,31), name='ground_build0', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground_build1', char=176, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground'),
 'ground_build1': Tile(bg=Color(31,31,31), name='ground_build1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground_build2', char=177, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground_build0'),
 'ground_build2': Tile(bg=Color(31,31,31), name='ground_build2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='wall', char=178, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='ground_build1'),
 'muddy_ground': Tile(bg=Color(127,101,63), name='muddy_ground', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground_build0', char=45, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to=None),
 'muddy_ground1': Tile(bg=Color(127,101,63), name='muddy_ground1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground1_build0', char=46, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to=None),
 'muddy_ground1_build0': Tile(bg=Color(127,101,63), name='muddy_ground1_build0', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground1_build1', char=176, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground1'),
 'muddy_ground1_build1': Tile(bg=Color(127,101,63), name='muddy_ground1_build1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground1_build2', char=177, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground1_build0'),
 'muddy_ground1_build2': Tile(bg=Color(127,101,63), name='muddy_ground1_build2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='wall', char=178, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground1_build1'),
 'muddy_ground2': Tile(bg=Color(127,101,63), name='muddy_ground2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground2_build0', char=96, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to=None),
 'muddy_ground2_build0': Tile(bg=Color(127,101,63), name='muddy_ground2_build0', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground2_build1', char=176, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground2'),
 'muddy_ground2_build1': Tile(bg=Color(127,101,63), name='muddy_ground2_build1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground2_build2', char=177, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground2_build0'),
 'muddy_ground2_build2': Tile(bg=Color(127,101,63), name='muddy_ground2_build2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='wall', char=178, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground2_build1'),
 'muddy_ground_build0': Tile(bg=Color(127,101,63), name='muddy_ground_build0', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground_build1', char=176, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground'),
 'muddy_ground_build1': Tile(bg=Color(127,101,63), name='muddy_ground_build1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='muddy_ground_build2', char=177, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground_build0'),
 'muddy_ground_build2': Tile(bg=Color(127,101,63), name='muddy_ground_build2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='wall', char=178, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='', dig_to='muddy_ground_build1'),
 'wall': Tile(bg=None, name='wall', diggable=True, adjacent_hidden=False, readable_name='Limestone', build_to=None, char=120, buildable=False, is_obstacle=False, tile_class='WALL', fg=Color(0,0,0), tag='', dig_to='wall_dig0'),
 'wall_dig0': Tile(bg=None, name='wall_dig0', diggable=True, adjacent_hidden=False, readable_name='Limestone', build_to='wall', char=120, buildable=False, is_obstacle=False, tile_class='WALL', fg=Color(0,0,0), tag='', dig_to='wall_dig1'),
 'wall_dig1': Tile(bg=None, name='wall_dig1', diggable=True, adjacent_hidden=False, readable_name='Limestone', build_to='wall_dig0', char=120, buildable=False, is_obstacle=False, tile_class='WALL', fg=Color(0,0,0), tag='', dig_to='wall_dig2'),
 'wall_dig2': Tile(bg=None, name='wall_dig2', diggable=True, adjacent_hidden=False, readable_name='Limestone', build_to='wall_dig1', char=120, buildable=False, is_obstacle=False, tile_class='WALL', fg=Color(0,0,0), tag='', dig_to='ground')}

In [20]:
any_ground


Out[20]:
[Tile(bg=Color(31,31,31), name='ground1', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground1_build0', char=46, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='reg_ground', dig_to=None),
 Tile(bg=Color(31,31,31), name='ground2', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground2_build0', char=96, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='reg_ground', dig_to=None),
 Tile(bg=Color(31,31,31), name='ground', diggable=False, adjacent_hidden=False, readable_name='Ground', build_to='ground_build0', char=45, buildable=True, is_obstacle=False, tile_class='GROUND', fg=Color(127,127,127), tag='reg_ground', dig_to=None)]

In [ ]: