From 8ab3ccec813423b3b200d42b26347508691abfff Mon Sep 17 00:00:00 2001 From: GreenVars Date: Sat, 23 Aug 2014 17:01:25 -0400 Subject: [PATCH 1/8] New Previewer in some_bot system This is my attempt at putting the new previewer in some_bot. I don't know anything about sys.args and some python 2 things but its a start. I commented anything I'm not sure on. --- previewer.py | 437 +++++++++++++++------------------------------------ 1 file changed, 129 insertions(+), 308 deletions(-) diff --git a/previewer.py b/previewer.py index edaa191..e04fe87 100755 --- a/previewer.py +++ b/previewer.py @@ -1,328 +1,149 @@ -#!/usr/bin/env python -"""A preview generator for tagpro.""" - -from __future__ import division -import functools - import sys -import json import urllib import cStringIO -import fractions -import itertools - -from PIL import Image, ImageDraw - - +from os import listdir +from json import load +from PIL import Image +map = {} +sprites = {} +WALLS = ["45", "135", "225", "315", "wall"] +fails = 0 TILE_SIZE = 40 SIZE_LIMIT = 100*100 - - def usage(): print >> sys.stderr, 'Usage: {} PNG JSON [SPLATS] > PREVIEW'.format( sys.argv[0]) - - -class Splat(): - def __init__(self, color, radius): - width = height = radius * 2 + 1 - splat = Image.new("RGBA", (width, height)) - c = ImageDraw.ImageDraw(splat, "RGBA") - (x, y) = (radius,) * 2 - c.ellipse((x - radius, y - radius, x + radius, y + radius), fill=color) - r, g, b, a = splat.split() - self.splat = Image.merge("RGB", (r, g, b)) - self.mask = Image.merge("L", (a,)) - - def paste_onto(self, im, coords): - im.paste(self.splat, coords, self.mask) - - +rgbs = { + (0, 0, 0): "black", + (120, 120, 120): "wall", + (55, 55, 55): "spike", + (255, 0, 0): "redflag", + (0, 0, 255): "blueflag", + (128, 128, 0): "yellowflag", + (212, 212, 212): "floor", + (0, 117, 0): "gate", + (185, 122, 87): "button", + (0, 255, 0): "topspeed", + (255, 255, 0): "boost", + (255, 128, 0): "bomb", + (220, 186, 186): "red_speed_tile", + (187, 184, 221): "blue_speed_tile", + (202, 192, 0): "portaloff", + (155, 0, 0): "redball", + (0, 0, 155): "blueball", + (255, 115, 115): "red_boost", + (115, 115, 255): "blue_boost", + (185, 0, 0): "red_endzone", + (25, 0, 148): "blue_endzone", + (128, 112, 64): "45", + (64, 128, 80): "135", + (64, 80, 128): "225", + (128, 64, 112): "315" +} +# Er good class use? class Map(): - tiles = Image.open('resources/tiles.png') - speedpad = Image.open('resources/speedpad.png') - speedpad_blue = Image.open('resources/speedpadblue.png') - speedpad_red = Image.open('resources/speedpadred.png') - portal = Image.open('resources/portal.png') - colormap = { - 'black': (0, 0, 0), - 'wall': (120, 120, 120), - 'tile': (212, 212, 212), - 'spike': (55, 55, 55), - 'button': (185, 122, 87), - 'powerup': (0, 255, 0), - 'gate': (0, 117, 0), - 'blueflag': (0, 0, 255), - 'redflag': (255, 0, 0), - 'yellowflag': (128, 128, 0), - 'blueendzone': (25, 0, 148), - 'redendzone': (185, 0, 0), - 'speedpad': (255, 255, 0), - 'bomb': (255, 128, 0), - 'bluetile': (187, 184, 221), - 'redtile': (220, 186, 186), - 'speedpadred': (255, 115, 115), - 'speedpadblue': (115, 115, 255), - 'portal': (202, 192, 0), - 'bluespawn': (0, 0, 155), - 'redspawn': (155, 0, 0) - } - coord_map = {colormap['speedpad']: (0, 0, speedpad), - colormap['speedpadred']: (0, 0, speedpad_red), - colormap['speedpadblue']: (0, 0, speedpad_blue), - colormap['bomb']: (6, 5, None), - colormap['redtile']: (3, 1, None), - colormap['bluetile']: (3, 2, None), - colormap['spike']: (2, 3, None), - colormap['button']: (2, 5, None), - colormap['powerup']: (7, 8, None), - colormap['blueflag']: (9, 0, None), - colormap['redflag']: (8, 0, None), - colormap['yellowflag']: (7, 0, None), - colormap['blueendzone']: (5, 2, None), - colormap['redendzone']: (5, 1, None), - colormap['redspawn']: (6, 2, None), - colormap['bluespawn']: (6, 3, None), - colormap['tile']: (2, 2, None)} - - # Directions are N,S,E,W - wall_dirs = {(True, True, True, True): (4, 4), - (True, True, True, False): (0, 4), - (True, True, False, True): (7, 4), - (True, True, False, False): (4, 2), - (True, False, True, True): (4, 8), - (True, False, True, False): (2, 8), - (True, False, False, True): (6, 8), - (True, False, False, False): (0, 6), - (False, True, True, True): (4, 0), - (False, True, True, False): (2, 0), - (False, True, False, True): (6, 0), - (False, True, False, False): (0, 2), - (False, False, True, True): (2, 4), - (False, False, True, False): (8, 6), - (False, False, False, True): (9, 6), - (False, False, False, False): (0, 0)} - - def __init__(self, pngpath, jsonpath): - if 'http' in pngpath: - png_handle = cStringIO.StringIO(urllib.urlopen(pngpath).read()) - png = Image.open(png_handle) - else: - png = Image.open(pngpath) - - if png.mode != 'RGBA': - png = png.convert('RGBA') - self.png = png - self.max_x, self.max_y = self.png.size - if self.max_x * self.max_y > SIZE_LIMIT: - error_msg = "Image '{}' is too large. Limit is {} px, but it is {}x{}.".format( - pngpath, SIZE_LIMIT, self.max_x, self.max_y - ) - raise ValueError(error_msg) - self.pixels = png.load() - self._preview = None - self.portal_entrances = [] - - if 'http' in jsonpath: - json_file = urllib.urlopen(jsonpath) - self.json = json.load(json_file) - else: - with open(jsonpath) as fp: - self.json = json.load(fp) - - def draw(self, (x, y), (i, j), tiles, preview, draw_background=False, - source=None, draw_num_tiles=1): - """Draws a square square size (x, y) from the source source - onto preview at coordinates (i, j)""" - - if draw_background: - im = tiles.crop((2 * TILE_SIZE, 2 * TILE_SIZE, - 2 * TILE_SIZE + TILE_SIZE, - 2 * TILE_SIZE + TILE_SIZE)) - - # itertools.product simply returns all combinations from a - # combination of iterables. - # For a further usage look at self.all_coords, which eliminates - # a double `for` loop and just gives us the x, y pairs we want. - for c, d in itertools.product(xrange(i, i + draw_num_tiles), - xrange(j, j + draw_num_tiles)): - preview.paste(im, (int(c * TILE_SIZE), int(d * TILE_SIZE))) - - if not source: - source = tiles - - x, y = x * TILE_SIZE, y * TILE_SIZE - im = source.crop(( - x, y, x + draw_num_tiles * TILE_SIZE, - y + draw_num_tiles * TILE_SIZE)) - preview.paste(im, (int(i * TILE_SIZE), int(j * TILE_SIZE)), im) - - @property - def all_coords(self): - return itertools.product(range(self.max_x), range(self.max_y)) - - def _draw_under(self): - green = [] - blue = [] - red = [] - draw = functools.partial(self.draw, tiles=self.tiles, - preview=self._preview, draw_background=True) - try: - for point, state in self.json['fields'].iteritems(): - x, y = point.split(',') - if state['defaultState'] == 'on': - l = green - elif state['defaultState'] == 'red': - l = red - elif state['defaultState'] == 'blue': - l = blue - else: - continue - l.append((int(x), int(y))) - except KeyError: - pass - if 'portals' in self.json: - portals = [z.split(",") for z in self.json['portals']] - self.portal_entrances.extend((int(x), int(y)) for x, y in portals) - - for i, j in self.all_coords: - try: - source = None - color = self.get_color(i, j) - if color in self.coord_map: - a, b, source = self.coord_map[color] - draw((a, b), (i, j), source=source) - elif color == self.colormap['portal']: - if (i, j) in self.portal_entrances: - a, b = 0, 0 - else: - a, b = 4, 0 - source = self.portal - elif color == self.colormap['gate']: - if (i, j) in green: - a, b = 10, 2 - elif (i, j) in red: - a, b = 10, 3 - elif (i, j) in blue: - a, b = 10, 4 - else: - a, b = 10, 1 - elif color == self.colormap['black']: - continue - elif color == self.colormap['wall']: - continue - else: - raise KeyError("Unknown RGB value {}".format(color)) - draw((a, b), (i, j), source=source) - except KeyError as e: - print >> sys.stderr, e - - def _draw_splats(self, splatfile): - im = self._preview - with open(splatfile) as f: - splats = json.load(f) - radius = 10 - opacity = 64 - color = {2: (0, 0, 255, opacity), 1: (255, 0, 0, opacity)} - shift = 10 - - red_splat = Splat(color[1], radius) - blue_splat = Splat(color[2], radius) - - for splat in splats: - x, y = splat['x'] + shift, splat['y'] + shift - t = splat['t'] - if t == 1: - red_splat.paste_onto(im, (x, y)) - elif t == 2: - blue_splat.paste_onto(im, (x, y)) - - def get_color(self, i, j): - return self.pixels[i, j][:3] - - def get_wall(self, i, j): - max_width = self.max_x - 1 - max_height = self.max_y - 1 - north, south, west, east = [False] * 4 - if j > 0: - north = self.get_color(i, j - 1) == self.colormap[ - 'wall'] - if j < max_height: - south = self.get_color(i, j + 1) == self.colormap['wall'] - if i > 0: - west = self.get_color(i - 1, j) == self.colormap['wall'] - if i < max_width: - east = self.get_color(i + 1, j) == self.colormap['wall'] - return self.wall_dirs[(north, south, east, west)] - - def _draw_over(self): - draw = functools.partial(self.draw, tiles=self.tiles, - preview=self._preview, draw_background=False) - marsballs = [] - if 'marsballs' in self.json: - marsballs.extend((int(coordinates['x']), int(coordinates['y'])) - for coordinates in self.json['marsballs']) - - for i, j in self.all_coords: - try: - source = None - color = self.get_color(i, j) - if color == self.colormap['wall']: - a, b = self.get_wall(i, j) - elif color == self.colormap['portal']: - if (i, j) in self.portal_entrances: - a, b = 0, 0 - else: - a, b = 4, 0 - source = self.portal - elif color in self.coord_map: - a, b, source = self.coord_map[color] - elif color == self.colormap['black']: - self._preview.paste((0, 0, 0, 255), ( - i * TILE_SIZE, j * TILE_SIZE, (i + 1) * TILE_SIZE, - (j + 1) * TILE_SIZE)) - continue - else: - raise KeyError("Unknown RGB value {}".format(color)) - draw((a, b), (i, j), source=source) - except KeyError as e: - print >> sys.stderr, e - - for i, j in marsballs: - draw((11, 0), - (i - fractions.Fraction('1/2'), j - fractions.Fraction('1/2')), - draw_num_tiles=2) - - def preview(self, splats=None, save=None): - self._preview = Image.new('RGBA', (self.max_x * TILE_SIZE, - self.max_y * TILE_SIZE)) - - self._draw_under() - if splats: - self._draw_splats(splats) - self._draw_over() - - if save: - self._preview.save(save, 'PNG') - - temp = cStringIO.StringIO() - self._preview.save(temp, 'PNG') - return temp - - + # Sprite directory + sprite_list = listdir("sprites/") + if 'Thumbs.db' in sprite_list: + sprite_list.remove('Thumbs.db') + for pic in sprite_list: + sprites[pic] = Image.open("sprites/"+pic) + # Odd Indentation Error + def __init__(self, pngpath, jsonpath): + if 'http' in pngpath: + png_handle = cStringIO.StringIO(urllib.urlopen(pngpath).read()) + png = Image.open(png_handle) + else: + png = Image.open(pngpath) + if png.mode != 'RGBA': + png = png.convert('RGBA') + self.png = png + self.max_x, self.max_y = self.png.size + if self.max_x * self.max_y > SIZE_LIMIT: + error_msg = "Image '{}' is too large. Limit is {} px, but it is {}x{}.".format( + pngpath, SIZE_LIMIT, self.max_x, self.max_y) + raise ValueError(error_msg) + self.pixels = png.load() + self._preview = None + self.portal_entrances = [] + if 'http' in jsonpath: + json_file = urllib.urlopen(jsonpath) + self.json = load(json_file) + else: + with open(jsonpath) as fp: + self.json = load(fp) + def adj_walls(x, y, paste): + corr_adj = { + "U": [(128, 112, 64), (128, 64, 112), (120, 120, 120)], + "R": [(128, 112, 64), (64, 128, 80), (120, 120, 120)], + "D": [(64, 128, 80), (64, 80, 128), (120, 120, 120)], + "L": [(64, 80, 128), (128, 64, 112), (120, 120, 120)] + } + adj = paste + # If within boundaries + # If wall dir corresponds + # Exclude wall type duplicates - Experimental 50% Success at catching odd 45s + # Add dir string + if y != 0: + if pixels[x,y-1] in corr_adj["U"]: + if ('315' and '45') not in adj: + adj += "U" + if x != WIDTH-1: + if pixels[x+1,y] in corr_adj["R"]: + if '135' not in adj: + adj += "R" + if y != HEIGHT-1: + if pixels[x,y+1] in corr_adj["D"]: + if '135' not in adj: + adj += "D" + if x != 0: + if pixels[x-1,y] in corr_adj["L"]: + if '225' and '315' not in adj: + adj += "L" + return adj + def draw(data, pixels): + for w in range(WIDTH): + for h in range(HEIGHT): + map[(w,h)] = rgbs[pixels[w,h]] + + for item in map: + paste = map[item] + if paste == 'gate': + cord_key = "%d,%d" % (item[0], item[1]) + if cord_key in data['fields']: + if data['fields'][cord_key]['defaultState'] != 'off': + paste = data['fields'][cord_key]['defaultState']+"_gate" + if paste == 'portaloff': + cord_key = "%d,%d" % (item[0], item[1]) + try: + if "destination" in data['portals'][cord_key]: + paste = "portal" + except KeyError: + pass + if paste in WALLS: + # Good Function call? + paste = adj_walls(item[0], item[1], paste) + if paste+'.png' in sprites: + img.paste(sprites[paste+'.png'],(item[0]*TILE_SIZE,item[1]*TILE_SIZE)) + else: + fails += 1 + if 'marsballs' in data: + for mars in range(len(data['marsballs'])): + img.paste(sprites['marsball.png'],(data['marsballs'][mars]['x']*TILE_SIZE, data['marsballs'][mars]['y']*TILE_SIZE)) + # Good return? + return img def main(): if len(sys.argv) < 3: usage() return 1 - + # Removed anything with splats, wasn't sure if neccessary png_path = sys.argv[1] json_path = sys.argv[2] - splats = sys.argv[3] if len(sys.argv) > 3 else None + # Good calls and returns? map_ = Map(png_path, json_path) - preview = map_.preview(splats=splats) + preview = map_.draw(png_path, json_path) sys.stdout.write(preview.getvalue()) - - + if '__main__' == __name__: status = main() sys.exit(status) From eafb9119e2132785a10d850c8a6347964e482499 Mon Sep 17 00:00:00 2001 From: GreenVars Date: Sat, 23 Aug 2014 18:58:47 -0400 Subject: [PATCH 2/8] Fix name incompatibilities and syntax errors Added line to generate image to paste on --- previewer.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/previewer.py b/previewer.py index e04fe87..e8a7706 100755 --- a/previewer.py +++ b/previewer.py @@ -42,7 +42,7 @@ def usage(): } # Er good class use? class Map(): - # Sprite directory +# Sprite directory sprite_list = listdir("sprites/") if 'Thumbs.db' in sprite_list: sprite_list.remove('Thumbs.db') @@ -88,11 +88,11 @@ def adj_walls(x, y, paste): if pixels[x,y-1] in corr_adj["U"]: if ('315' and '45') not in adj: adj += "U" - if x != WIDTH-1: + if x != self.max_x-1: if pixels[x+1,y] in corr_adj["R"]: if '135' not in adj: adj += "R" - if y != HEIGHT-1: + if y != self.max_y-1: if pixels[x,y+1] in corr_adj["D"]: if '135' not in adj: adj += "D" @@ -101,9 +101,10 @@ def adj_walls(x, y, paste): if '225' and '315' not in adj: adj += "L" return adj - def draw(data, pixels): - for w in range(WIDTH): - for h in range(HEIGHT): + def draw(pixels, data): + img = Image.new("RGB", (self.max_x*40,self.max_y*40), "white") + for w in range(self.max_x): + for h in range(self.max_y): map[(w,h)] = rgbs[pixels[w,h]] for item in map: From 1b96fe9c276a22b584247b7980de474ff5d28eb6 Mon Sep 17 00:00:00 2001 From: GreenVars Date: Sun, 31 Aug 2014 12:40:14 -0400 Subject: [PATCH 3/8] Apparently xrange is a thing --- previewer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/previewer.py b/previewer.py index e8a7706..527110a 100755 --- a/previewer.py +++ b/previewer.py @@ -103,6 +103,7 @@ def adj_walls(x, y, paste): return adj def draw(pixels, data): img = Image.new("RGB", (self.max_x*40,self.max_y*40), "white") + # xrange???? for w in range(self.max_x): for h in range(self.max_y): map[(w,h)] = rgbs[pixels[w,h]] @@ -129,6 +130,7 @@ def draw(pixels, data): else: fails += 1 if 'marsballs' in data: + # xrange???? for mars in range(len(data['marsballs'])): img.paste(sprites['marsball.png'],(data['marsballs'][mars]['x']*TILE_SIZE, data['marsballs'][mars]['y']*TILE_SIZE)) # Good return? From 0d4ee0c67f19a3e32e73b66e1fdb6c9c0f979a91 Mon Sep 17 00:00:00 2001 From: GreenVars Date: Mon, 1 Sep 2014 13:56:43 -0400 Subject: [PATCH 4/8] I DID IT I finally read the part in my book on classes and methods and such. I went through my previous version and made it work. I'm almost completely positive this will work with no issues and will generate previews. Object-Oriented and everything. CHANGES: Put class specific variables in the __init__ The dictionary of cords and what sprite they are is now generated in its own function Changed several variable names as map was used too much Draw no longer needs parameters Took adj_walls out of the plot class Added some debug data in __str__ Final Concerns: Will the previews work in some_bot and JukeJuice? Shouldn't the png mode be RGB and not RGBA? I think RGBA gives a 4th tuple value which messes up the program but ill leave it up to you. Are variables in the right scope? I'm horrible at github so these commit changes might look weird but who needs previous versions when this works? --- previewer.py | 161 +++++++++++++++++++++++++++------------------------ 1 file changed, 84 insertions(+), 77 deletions(-) diff --git a/previewer.py b/previewer.py index 527110a..1449d6b 100755 --- a/previewer.py +++ b/previewer.py @@ -4,15 +4,48 @@ from os import listdir from json import load from PIL import Image -map = {} -sprites = {} WALLS = ["45", "135", "225", "315", "wall"] -fails = 0 TILE_SIZE = 40 SIZE_LIMIT = 100*100 +# Sprite directory +sprites = {} +sprite_list = listdir("sprites/") +if 'Thumbs.db' in sprite_list: + sprite_list.remove('Thumbs.db') +for pic in sprite_list: + sprites[pic] = Image.open("sprites/"+pic) def usage(): - print >> sys.stderr, 'Usage: {} PNG JSON [SPLATS] > PREVIEW'.format( - sys.argv[0]) + print >> sys.stderr, 'Usage: {} PNG JSON [SPLATS] > PREVIEW'.format( + sys.argv[0]) +def adj_walls(x, y, paste): + corr_adj = { + "U": [(128, 112, 64), (128, 64, 112), (120, 120, 120)], + "R": [(128, 112, 64), (64, 128, 80), (120, 120, 120)], + "D": [(64, 128, 80), (64, 80, 128), (120, 120, 120)], + "L": [(64, 80, 128), (128, 64, 112), (120, 120, 120)] + } + adj = paste + # If within boundaries + # If wall dir corresponds + # Exclude wall type duplicates - Experimental 50% Success at catching odd 45s + # Add dir string + if y != 0: + if pixels[x,y-1] in corr_adj["U"]: + if ('315' and '45') not in adj: + adj += "U" + if x != self.max_x-1: + if pixels[x+1,y] in corr_adj["R"]: + if '135' not in adj: + adj += "R" + if y != self.max_y-1: + if pixels[x,y+1] in corr_adj["D"]: + if '135' not in adj: + adj += "D" + if x != 0: + if pixels[x-1,y] in corr_adj["L"]: + if '225' and '315' not in adj: + adj += "L" + return adj rgbs = { (0, 0, 0): "black", (120, 120, 120): "wall", @@ -40,113 +73,87 @@ def usage(): (64, 80, 128): "225", (128, 64, 112): "315" } -# Er good class use? -class Map(): -# Sprite directory - sprite_list = listdir("sprites/") - if 'Thumbs.db' in sprite_list: - sprite_list.remove('Thumbs.db') - for pic in sprite_list: - sprites[pic] = Image.open("sprites/"+pic) - # Odd Indentation Error +class plot(): def __init__(self, pngpath, jsonpath): if 'http' in pngpath: png_handle = cStringIO.StringIO(urllib.urlopen(pngpath).read()) png = Image.open(png_handle) else: png = Image.open(pngpath) + # SHOULD THIS BE RGB------------? if png.mode != 'RGBA': png = png.convert('RGBA') self.png = png self.max_x, self.max_y = self.png.size + self.fails = 0 + self.cords = map_cords() if self.max_x * self.max_y > SIZE_LIMIT: error_msg = "Image '{}' is too large. Limit is {} px, but it is {}x{}.".format( pngpath, SIZE_LIMIT, self.max_x, self.max_y) raise ValueError(error_msg) self.pixels = png.load() - self._preview = None - self.portal_entrances = [] if 'http' in jsonpath: json_file = urllib.urlopen(jsonpath) self.json = load(json_file) else: with open(jsonpath) as fp: self.json = load(fp) - def adj_walls(x, y, paste): - corr_adj = { - "U": [(128, 112, 64), (128, 64, 112), (120, 120, 120)], - "R": [(128, 112, 64), (64, 128, 80), (120, 120, 120)], - "D": [(64, 128, 80), (64, 80, 128), (120, 120, 120)], - "L": [(64, 80, 128), (128, 64, 112), (120, 120, 120)] - } - adj = paste - # If within boundaries - # If wall dir corresponds - # Exclude wall type duplicates - Experimental 50% Success at catching odd 45s - # Add dir string - if y != 0: - if pixels[x,y-1] in corr_adj["U"]: - if ('315' and '45') not in adj: - adj += "U" - if x != self.max_x-1: - if pixels[x+1,y] in corr_adj["R"]: - if '135' not in adj: - adj += "R" - if y != self.max_y-1: - if pixels[x,y+1] in corr_adj["D"]: - if '135' not in adj: - adj += "D" - if x != 0: - if pixels[x-1,y] in corr_adj["L"]: - if '225' and '315' not in adj: - adj += "L" - return adj - def draw(pixels, data): - img = Image.new("RGB", (self.max_x*40,self.max_y*40), "white") - # xrange???? + def __str__(self): + return """Map Name: {} + Map Author: {} + Map Height: {} + Map Width: {} + Tile Number: {} + Preview Height: {} + Preview Width: {} + Failed Displays: {} + """.format(self.json["info"]["name"], self.json["info"]["author"], + self.max_y, self.max_x, self.max_x*self.max_y, self.max_y*40, self.max_x*40, self.fails) + def map_cords(): + cords = {} for w in range(self.max_x): for h in range(self.max_y): - map[(w,h)] = rgbs[pixels[w,h]] - - for item in map: - paste = map[item] + cords[(w,h)] = rgbs[self.pixels[w,h]] + return cords + def draw(self): + img = Image.new("RGB", (self.max_x*40,self.max_y*40), "white") + for item in self.cords: + paste = self.cords[item] if paste == 'gate': cord_key = "%d,%d" % (item[0], item[1]) - if cord_key in data['fields']: - if data['fields'][cord_key]['defaultState'] != 'off': - paste = data['fields'][cord_key]['defaultState']+"_gate" + if cord_key in self.json['fields']: + if self.json['fields'][cord_key]['defaultState'] != 'off': + paste = self.json['fields'][cord_key]['defaultState']+"_gate" if paste == 'portaloff': cord_key = "%d,%d" % (item[0], item[1]) try: - if "destination" in data['portals'][cord_key]: + if "destination" in self.json['portals'][cord_key]: paste = "portal" except KeyError: pass if paste in WALLS: - # Good Function call? paste = adj_walls(item[0], item[1], paste) - if paste+'.png' in sprites: + if paste+'.png' in sprites: img.paste(sprites[paste+'.png'],(item[0]*TILE_SIZE,item[1]*TILE_SIZE)) else: fails += 1 - if 'marsballs' in data: - # xrange???? - for mars in range(len(data['marsballs'])): - img.paste(sprites['marsball.png'],(data['marsballs'][mars]['x']*TILE_SIZE, data['marsballs'][mars]['y']*TILE_SIZE)) - # Good return? - return img + # Add all marsballs specified in json + if 'marsballs' in self.json: + for mars in range(len(self.json['marsballs'])): + img.paste(sprites['marsball.png'],(self.json['marsballs'][mars]['x']*TILE_SIZE, self.json['marsballs'][mars]['y']*TILE_SIZE)) + return img def main(): - if len(sys.argv) < 3: - usage() - return 1 - # Removed anything with splats, wasn't sure if neccessary - png_path = sys.argv[1] - json_path = sys.argv[2] - # Good calls and returns? - map_ = Map(png_path, json_path) - preview = map_.draw(png_path, json_path) - sys.stdout.write(preview.getvalue()) - + if len(sys.argv) < 3: + usage() + return 1 + + png_path = sys.argv[1] + json_path = sys.argv[2] + map_ = plot(png_path, json_path) + preview = map_.draw() + # I DONT KNOW WHAT THIS DOES BUT IT LOOKS IMPORTANT + sys.stdout.write(preview.getvalue()) + if '__main__' == __name__: - status = main() - sys.exit(status) + status = main() + sys.exit(status) From 1003aedba06c41af5eb2c81bf99409e5c34a27cc Mon Sep 17 00:00:00 2001 From: GreenVars Date: Mon, 1 Sep 2014 14:15:44 -0400 Subject: [PATCH 5/8] Fixed a couple variable names --- previewer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/previewer.py b/previewer.py index 1449d6b..4ee1815 100755 --- a/previewer.py +++ b/previewer.py @@ -86,7 +86,7 @@ def __init__(self, pngpath, jsonpath): self.png = png self.max_x, self.max_y = self.png.size self.fails = 0 - self.cords = map_cords() + self.cords = self.map_cords() if self.max_x * self.max_y > SIZE_LIMIT: error_msg = "Image '{}' is too large. Limit is {} px, but it is {}x{}.".format( pngpath, SIZE_LIMIT, self.max_x, self.max_y) @@ -136,7 +136,7 @@ def draw(self): if paste+'.png' in sprites: img.paste(sprites[paste+'.png'],(item[0]*TILE_SIZE,item[1]*TILE_SIZE)) else: - fails += 1 + self.fails += 1 # Add all marsballs specified in json if 'marsballs' in self.json: for mars in range(len(self.json['marsballs'])): From b3d63a110ba8269cd6d9caf82ac98d1a1c86b5ee Mon Sep 17 00:00:00 2001 From: GreenVars Date: Mon, 1 Sep 2014 20:27:41 -0400 Subject: [PATCH 6/8] Ok im absolutely positive now After doing a few more tests and actually trying it on my own computer I have finished. I put adj walls back into the plot class because it uses class attributes. I also fixed a few typos and missed places where self should be. I'm learning so much. This is most definitely the final version. --- previewer.py | 65 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/previewer.py b/previewer.py index 4ee1815..5414b9f 100755 --- a/previewer.py +++ b/previewer.py @@ -17,35 +17,6 @@ def usage(): print >> sys.stderr, 'Usage: {} PNG JSON [SPLATS] > PREVIEW'.format( sys.argv[0]) -def adj_walls(x, y, paste): - corr_adj = { - "U": [(128, 112, 64), (128, 64, 112), (120, 120, 120)], - "R": [(128, 112, 64), (64, 128, 80), (120, 120, 120)], - "D": [(64, 128, 80), (64, 80, 128), (120, 120, 120)], - "L": [(64, 80, 128), (128, 64, 112), (120, 120, 120)] - } - adj = paste - # If within boundaries - # If wall dir corresponds - # Exclude wall type duplicates - Experimental 50% Success at catching odd 45s - # Add dir string - if y != 0: - if pixels[x,y-1] in corr_adj["U"]: - if ('315' and '45') not in adj: - adj += "U" - if x != self.max_x-1: - if pixels[x+1,y] in corr_adj["R"]: - if '135' not in adj: - adj += "R" - if y != self.max_y-1: - if pixels[x,y+1] in corr_adj["D"]: - if '135' not in adj: - adj += "D" - if x != 0: - if pixels[x-1,y] in corr_adj["L"]: - if '225' and '315' not in adj: - adj += "L" - return adj rgbs = { (0, 0, 0): "black", (120, 120, 120): "wall", @@ -86,12 +57,12 @@ def __init__(self, pngpath, jsonpath): self.png = png self.max_x, self.max_y = self.png.size self.fails = 0 - self.cords = self.map_cords() if self.max_x * self.max_y > SIZE_LIMIT: error_msg = "Image '{}' is too large. Limit is {} px, but it is {}x{}.".format( pngpath, SIZE_LIMIT, self.max_x, self.max_y) raise ValueError(error_msg) self.pixels = png.load() + self.cords = self.map_cords() if 'http' in jsonpath: json_file = urllib.urlopen(jsonpath) self.json = load(json_file) @@ -109,12 +80,42 @@ def __str__(self): Failed Displays: {} """.format(self.json["info"]["name"], self.json["info"]["author"], self.max_y, self.max_x, self.max_x*self.max_y, self.max_y*40, self.max_x*40, self.fails) - def map_cords(): + def map_cords(self): cords = {} for w in range(self.max_x): for h in range(self.max_y): cords[(w,h)] = rgbs[self.pixels[w,h]] return cords + def adj_walls(self, x, y, paste): + corr_adj = { + "U": [(128, 112, 64), (128, 64, 112), (120, 120, 120)], + "R": [(128, 112, 64), (64, 128, 80), (120, 120, 120)], + "D": [(64, 128, 80), (64, 80, 128), (120, 120, 120)], + "L": [(64, 80, 128), (128, 64, 112), (120, 120, 120)] + } + adj = paste + # If within boundaries + # If wall dir corresponds + # Exclude wall type duplicates - Experimental 50% Success at catching odd 45s + # Add dir string + if y != 0: + if self.pixels[x,y-1] in corr_adj["U"]: + if ('315' and '45') not in adj: + adj += "U" + if x != self.max_x-1: + if self.pixels[x+1,y] in corr_adj["R"]: + if '135' not in adj: + adj += "R" + if y != self.max_y-1: + if self.pixels[x,y+1] in corr_adj["D"]: + if '135' not in adj: + adj += "D" + if x != 0: + if self.pixels[x-1,y] in corr_adj["L"]: + if '225' and '315' not in adj: + adj += "L" + return adj + def draw(self): img = Image.new("RGB", (self.max_x*40,self.max_y*40), "white") for item in self.cords: @@ -132,7 +133,7 @@ def draw(self): except KeyError: pass if paste in WALLS: - paste = adj_walls(item[0], item[1], paste) + paste = self.adj_walls(item[0], item[1], paste) if paste+'.png' in sprites: img.paste(sprites[paste+'.png'],(item[0]*TILE_SIZE,item[1]*TILE_SIZE)) else: From d48510c853e80f34f47ea8242ce1fa66fa6ca9a3 Mon Sep 17 00:00:00 2001 From: GreenVars Date: Tue, 30 Sep 2014 23:53:56 -0400 Subject: [PATCH 7/8] Fixed certain tile combinations not working I don't know if this will ever happen but now the previewer will never fail to display a tile if there's an odd assortment of tiles around it. --- previewer.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/previewer.py b/previewer.py index 5414b9f..bbb854a 100755 --- a/previewer.py +++ b/previewer.py @@ -93,26 +93,27 @@ def adj_walls(self, x, y, paste): "D": [(64, 128, 80), (64, 80, 128), (120, 120, 120)], "L": [(64, 80, 128), (128, 64, 112), (120, 120, 120)] } + wall_excep = [('31','45'),('13','45'),('13,22'),('22','31')] adj = paste # If within boundaries # If wall dir corresponds - # Exclude wall type duplicates - Experimental 50% Success at catching odd 45s + # Exclude wall type duplicates # Add dir string if y != 0: if self.pixels[x,y-1] in corr_adj["U"]: - if ('315' and '45') not in adj: + if adj[:2] not in wall_excep[0]: adj += "U" if x != self.max_x-1: if self.pixels[x+1,y] in corr_adj["R"]: - if '135' not in adj: + if adj[:2] not in wall_excep[1]: adj += "R" if y != self.max_y-1: if self.pixels[x,y+1] in corr_adj["D"]: - if '135' not in adj: + if adj[:2] not in wall_excep[2]: adj += "D" if x != 0: if self.pixels[x-1,y] in corr_adj["L"]: - if '225' and '315' not in adj: + if adj[:2] not in wall_excep[3]: adj += "L" return adj From 9aa76b3c47f797bb04db88a5bd92e6556929c401 Mon Sep 17 00:00:00 2001 From: GreenVars Date: Wed, 1 Oct 2014 00:24:51 -0400 Subject: [PATCH 8/8] Dictionary Comprehensions are cool too --- previewer.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/previewer.py b/previewer.py index bbb854a..e05a224 100755 --- a/previewer.py +++ b/previewer.py @@ -8,12 +8,10 @@ TILE_SIZE = 40 SIZE_LIMIT = 100*100 # Sprite directory -sprites = {} sprite_list = listdir("sprites/") if 'Thumbs.db' in sprite_list: sprite_list.remove('Thumbs.db') -for pic in sprite_list: - sprites[pic] = Image.open("sprites/"+pic) +sprites = {pic: Image.open("sprites/"+pic) for pic in sprite_list} def usage(): print >> sys.stderr, 'Usage: {} PNG JSON [SPLATS] > PREVIEW'.format( sys.argv[0]) @@ -81,11 +79,7 @@ def __str__(self): """.format(self.json["info"]["name"], self.json["info"]["author"], self.max_y, self.max_x, self.max_x*self.max_y, self.max_y*40, self.max_x*40, self.fails) def map_cords(self): - cords = {} - for w in range(self.max_x): - for h in range(self.max_y): - cords[(w,h)] = rgbs[self.pixels[w,h]] - return cords + return {(w,h): rgbs[self.pixels[w,h]] for w in range(self.max_x) for h in range(self.max_y)} def adj_walls(self, x, y, paste): corr_adj = { "U": [(128, 112, 64), (128, 64, 112), (120, 120, 120)],