Last active
September 22, 2016 07:46
-
-
Save dloscutoff/13212291a16e074c8366402e5b1dd082 to your computer and use it in GitHub Desktop.
Beginnings of a language for programming ASCII art
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CanvasError(Exception): | |
pass | |
class Canvas: | |
def __init__(self, grid=None, default=" "): | |
if grid: | |
self.grid = grid | |
else: | |
self.grid = [[]] | |
self.offsetx = 0 | |
self.offsety = 0 | |
self.default = default | |
self.ptrx = 0 | |
self.ptry = 0 | |
self.direction = (1,0) | |
def __getitem__(self, coords): | |
x, y = coords | |
x += self.offsetx | |
y += self.offsety | |
if 0 <= y < len(self.grid) and 0 <= x < len(self.grid[0]): | |
return self.grid[y][x] | |
else: | |
return None | |
def __setitem__(self, coords, value): | |
if value is not None and (type(value) is not str or len(value) != 1): | |
raise CanvasError("Canvas values must be single char or None, not " | |
"%r" % value) | |
x, y = coords | |
x += self.offsetx | |
y += self.offsety | |
while y < 0: | |
# Add row to the top of the grid | |
row = [None] * len(self.grid[0]) | |
self.grid = [row] + self.grid | |
self.offsety += 1 | |
y += 1 | |
while y >= len(self.grid): | |
# Add row to the bottom of the grid | |
row = [None] * len(self.grid[0]) | |
self.grid += [row] | |
while x < 0: | |
# Add column to the left side of the grid | |
self.grid = [[None] + row for row in self.grid] | |
self.offsetx += 1 | |
x += 1 | |
while x >= len(self.grid[0]): | |
# Add row to the right side of the grid | |
self.grid = [row + [None] for row in self.grid] | |
self.grid[y][x] = value | |
def __str__(self): | |
return "\n".join("".join(c if c else "\0" for c in row) | |
.rstrip("\0").replace("\0", self.default) | |
for row in self.grid) | |
def changeDirection(self, dirCode="."): | |
if dirCode == "↑": | |
self.direction = (0,-1) | |
elif dirCode == "↓": | |
self.direction = (0,1) | |
elif dirCode == "→": | |
self.direction = (1,0) | |
elif dirCode == "←": | |
self.direction = (-1,0) | |
elif dirCode == "↖": | |
self.direction = (-1,-1) | |
elif dirCode == "↗": | |
self.direction = (1,-1) | |
elif dirCode == "↘": | |
self.direction = (1,1) | |
elif dirCode == "↙": | |
self.direction = (-1,1) | |
else: | |
# Unrecognized direction code; for now, ignore silently | |
pass | |
return self | |
def put(self, char): | |
self[self.ptrx, self.ptry] = char | |
return self | |
### Functions that implement language commands start here ### | |
def printString(self, string, direction=None): | |
for char in string: | |
self.put(char).move(direction) | |
return self | |
def multiPrint(self, string, directions): | |
replacements = {ord(key): value | |
for key, value in [("+", "←↑→↓"), | |
("x", "↖↗↘↙"), | |
("*", "←↑→↓↖↗↘↙")]} | |
directions = directions.translate(replacements) | |
for direction in directions: | |
savedPtr = self.ptrx, self.ptry | |
self.printString(string, direction) | |
self.ptrx, self.ptry = savedPtr | |
return self | |
def move(self, direction=None, length=1): | |
if direction is not None: | |
self.changeDirection(direction) | |
self.ptrx += self.direction[0] * length | |
self.ptry += self.direction[1] * length | |
return self | |
def turn(self, direction): | |
pass | |
def jump(self, dx, dy, relative=True): | |
if relative: | |
self.ptrx += dx | |
self.ptry += dy | |
else: | |
self.ptrx = dx | |
self.ptry = dy | |
return self | |
def readCanvasChar(self, x=0, y=0, relative=True): | |
if relative: | |
result = self[x+self.ptrx, y+self.ptry] | |
else: | |
result = self[x, y] | |
return result | |
def readCanvasString(self, direction=None, length=1): | |
result = "" | |
for i in range(length): | |
char = self.readCanvasChar() | |
# TBD: use the canvas default character for empty spaces, or some | |
# other sentinel value (probably not in the printable ASCII range)? | |
result += self.default if char is None else char | |
self.move(direction) | |
return result | |
if __name__ == "__main__": | |
c=Canvas() | |
c.multiPrint("ascii", "x") | |
c.jump(5, -1) | |
c.printString("art", "↓") | |
print(c) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment