Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import math
- import os
- import sys
- import time
- class Program:
- def __init__(self,world):
- if str(type(world)) == "<class 'str'>":
- from_string = True
- else:
- from_string = False
- if not from_string:
- self.world = world
- else:
- self.world = {}
- y_layers = world.split("\n\n")
- y_index = 0
- for y_layer in y_layers:
- z_layers = y_layer.split("\n")
- z_index = 0
- for z_layer in z_layers:
- x_index = 0
- for char in z_layer:
- if not x_index in self.world:
- self.world[x_index] = {}
- if not y_index in self.world[x_index]:
- self.world[x_index][y_index] = {}
- self.world[x_index][y_index][z_index] = ord(char) - 32
- x_index += 1
- z_index += 1
- y_index += 1
- self.cursor = {}
- self.cursor["x"] = 0
- self.cursor["y"] = 0
- self.cursor["z"] = 0
- self.cursor["dir"] = 1
- self.search = False
- self.search_score = 0
- self.skip = False
- self.pointer = 0
- self.memp = 0
- self.needle = 0
- self.lifetime = 0
- self.abandoned = 0
- self.cells = {}
- self.drive = {}
- self.memory = {}
- self.ops = [self.noop, self.increment_pointer, self.decrement_pointer, self.increment_cell, self.decrement_cell, self.output, self.input, self.jump_forward, self.jump_backward, self.dir_posx, self.dir_posz, self.dir_negx, self.dir_negz, self.dir_posy, self.dir_negy, self.end_program, self.add_surrounding, self.subtract_surrounding, self.multiply_surrounding, self.divide_surrounding, self.equal_left, self.swap, self.equal_left_less, self.equal_left_greater, self.mod_surrounding, self.equal_right, self.equal_right_less, self.equal_left_greater, self.if_zero, self.if_non_zero, self.if_equal_left, self.if_equal_right, self.if_less_left, self.if_less_right, self.if_more_left, self.if_more_right, self.playsound, self.big_output, self.set_zero, self.write_drive, self.receive_drive, self.increment_needle, self.decrement_needle, self.increment_memp, self.decrement_memp, self.receive_memory, self.write_memory, self.create_op, self.async_input, self.create_marker, self.delete_marker, self.goto_marker, self.set_needle, self.set_memp, self.set_pointer, self.set_cursor, self.get_op, self.relative_set_cursor, self.get_pointer, self.get_memp, self.get_needle]
- self.markers = []
- def get_world(self):
- return self.world
- def run(self,delay,limit=-1,timeout=500,verbose=False):
- self.cursor = {}
- self.cursor["x"] = 0
- self.cursor["y"] = 0
- self.cursor["z"] = 0
- self.cursor["dir"] = 1
- self.search = False
- self.search_score = 0
- self.skip = False
- self.pointer = 0
- self.memp = 0
- self.needle = 0
- self.lifetime = 0
- self.abandoned = 0
- self.cells = {}
- self.memory = {}
- self.running = True
- while self.running == True:
- if verbose == True:
- print("Cursor Dir: " + str(self.cursor["dir"]) + " X: " + str(self.cursor["x"]) + " Y:" + str(self.cursor["y"]) + " Z:" + str(self.cursor["z"]))
- print("Pointer Pos: " + str(self.pointer) + " Cells: " + str(self.cells))
- print("Mem Pointer Pos: " + str(self.memp) + " Memory: " + str(self.memory))
- print("Needle Pos: " + str(self.needle) + " Drive: " + str(self.drive))
- self.lifetime += 1
- if self.lifetime == limit:
- self.running = False
- if self.abandoned >= timeout:
- self.running = False
- time.sleep(delay)
- try:
- if self.skip == False:
- op = self.world[self.cursor["x"]][self.cursor["y"]][self.cursor["z"]]
- else:
- self.skip = False
- op = 0
- except KeyError:
- op = 0
- try:
- if self.search == False:
- self.ops[op]()
- if verbose == True:
- print(self.ops[op].__name__)
- else:
- if op == 7:
- self.search_score += 1
- elif op == 8:
- self.search_score -= 1
- if search_score == 0:
- self.search = False
- except IndexError:
- pass
- if self.search_score >= 0:
- if self.cursor["dir"] == 1:
- self.cursor["x"] += 1
- elif self.cursor["dir"] == 2:
- self.cursor["z"] += 1
- elif self.cursor["dir"] == 3:
- self.cursor["x"] -= 1
- elif self.cursor["dir"] == 4:
- self.cursor["z"] -= 1
- elif self.cursor["dir"] == 5:
- self.cursor["y"] += 1
- elif self.cursor["dir"] == 6:
- self.cursor["y"] -= 1
- else:
- if self.cursor["dir"] == 1:
- self.cursor["x"] -= 1
- elif self.cursor["dir"] == 2:
- self.cursor["z"] -= 1
- elif self.cursor["dir"] == 3:
- self.cursor["x"] += 1
- elif self.cursor["dir"] == 4:
- self.cursor["z"] += 1
- elif self.cursor["dir"] == 5:
- self.cursor["y"] -= 1
- elif self.cursor["dir"] == 6:
- self.cursor["y"] += 1
- def get_cell(self, pos):
- try:
- return self.cells[pos]
- except KeyError:
- self.cells[pos] = 0
- return self.cells[pos]
- def get_drive(self, pos):
- try:
- return self.drive[pos]
- except KeyError:
- self.drive[pos] = 0
- return self.drive[pos]
- def get_memory(self, pos):
- try:
- return self.memory[pos]
- except KeyError:
- self.memory[pos] = 0
- return self.memory[pos]
- def noop(self):
- #Does nothing, counts as an abandoned
- self.abandoned += 1
- def increment_pointer(self):
- #Increment pointer position
- self.pointer += 1
- def decrement_pointer(self):
- #Decrements pointer position
- self.pointer -= 1
- def increment_cell(self):
- #Increments current cell
- try:
- self.cells[self.pointer] += 1
- except KeyError:
- self.cells[self.pointer] = 1
- def decrement_cell(self):
- #Decrements current cell
- try:
- self.cells[self.pointer] -= 1
- except KeyError:
- self.cells[self.pointer] = -1
- def output(self):
- #Output Ascii Character
- try:
- print(chr(self.cells[self.pointer]))
- except KeyError:
- print(chr(0))
- def input(self):
- #Get one character of input
- self.cells[self.pointer] = wait_key()
- def jump_forward(self):
- #Jump to ] if cell is 0
- try:
- if self.cells[self.pointer] == 0:
- #Search for ]
- self.search = True
- self.search_score = 1
- except KeyError:
- self.cells[self.pointer] = 0
- #Search for ]
- self.search = True
- self.search_score = 1
- def jump_backward(self):
- #Jump to [ if cell is not 0
- try:
- if self.cells[self.pointer] != 0:
- #Search for ]
- self.search = True
- self.search_score = -1
- except KeyError:
- pass
- def dir_posx(self):
- #Set direction to +X
- self.cursor["dir"] = 1
- def dir_posz(self):
- #Set direction to +Z
- self.cursor["dir"] = 2
- def dir_negx(self):
- #Set direction to -X
- self.cursor["dir"] = 3
- def dir_negz(self):
- #Set direction to -Z
- self.cursor["dir"] = 4
- def dir_posy(self):
- #Set direction to +Y
- self.cursor["dir"] = 5
- def dir_negy(self):
- #Set direction to -Y
- self.cursor["dir"] = 6
- def end_program(self):
- #Ends Program
- self.running = False
- def add_surrounding(self):
- #Adds Surrounding Cells
- cell_left = self.get_cell(self.pointer-1)
- cell_right = self.get_cell(self.pointer+1)
- self.cells[self.pointer] = cell_left + cell_right
- def subtract_surrounding(self):
- #Subtract Surrounding Cells
- cell_left = self.get_cell(self.pointer-1)
- cell_right = self.get_cell(self.pointer+1)
- self.cells[self.pointer] = cell_left - cell_right
- def multiply_surrounding(self):
- #Multiply Surrounding Cells
- cell_left = self.get_cell(self.pointer-1)
- cell_right = self.get_cell(self.pointer+1)
- self.cells[self.pointer] = cell_left * cell_right
- def divide_surrounding(self):
- #Divide & Floor Surrounding Cells
- cell_left = self.get_cell(self.pointer-1)
- cell_right = self.get_cell(self.pointer+1)
- self.cells[self.pointer] = math.floor(cell_left / cell_right)
- def equal_left(self):
- #Set to Left Cell
- try:
- self.cells[self.pointer] = self.cells[self.pointer-1]
- except KeyError:
- self.cells[self.pointer-1] = 0
- self.cells[self.pointer] = self.cells[self.pointer-1]
- def swap(self):
- #Swap left and right Cells
- cell_left = self.get_cell(self.pointer-1)
- cell_right = self.get_cell(self.pointer+1)
- self.cells[self.pointer-1] = cell_right
- self.cells[self.pointer+1] = cell_left
- def equal_left_less(self):
- #Set to Left Cell if less than Left Cell
- try:
- if self.cells[self.pointer-1] > self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer-1]
- except KeyError:
- if not self.pointer-1 in self.cells:
- self.cells[self.pointer-1] = 0
- if not self.pointer in self.cells:
- self.cells[self.pointer] = 0
- if self.cells[self.pointer-1] > self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer-1]
- def equal_left_greater(self):
- #Set to Left Cell if more than Left Cell
- try:
- if self.cells[self.pointer-1] < self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer-1]
- except KeyError:
- if not self.pointer-1 in self.cells:
- self.cells[self.pointer-1] = 0
- if not self.pointer in self.cells:
- self.cells[self.pointer] = 0
- if self.cells[self.pointer-1] < self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer-1]
- def mod_surrounding(self):
- #Do modulo on surrounding cells
- cell_left = self.get_cell(self.pointer-1)
- cell_right = self.get_cell(self.pointer+1)
- self.cells[self.pointer] = cell_left % cell_right
- def equal_right(self):
- #Set cell to cell right
- try:
- self.cells[self.pointer] = self.cells[self.pointer+1]
- except KeyError:
- self.cells[self.pointer+1] = 0
- self.cells[self.pointer] = self.cells[self.pointer+1]
- def equal_right_less(self):
- #Set to Right Cell if less than Right Cell
- try:
- if self.cells[self.pointer+1] > self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer+1]
- except KeyError:
- if not self.pointer+1 in self.cells:
- self.cells[self.pointer+1] = 0
- if not self.pointer in self.cells:
- self.cells[self.pointer] = 0
- if self.cells[self.pointer+1] > self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer+1]
- def equal_right_greater(self):
- #Set to Right Cell if more than Right Cell
- try:
- if self.cells[self.pointer+1] < self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer+1]
- except KeyError:
- if not self.pointer+1 in self.cells:
- self.cells[self.pointer+1] = 0
- if not self.pointer in self.cells:
- self.cells[self.pointer] = 0
- if self.cells[self.pointer+1] < self.cells[self.pointer]:
- self.cells[self.pointer] = self.cells[self.pointer+1]
- def if_zero(self):
- #Skip if not zero
- if self.get_cell(self.pointer) == 0:
- pass
- else:
- self.skip = True
- def if_non_zero(self):
- #Skip if zero
- if self.get_cell(self.pointer) != 0:
- pass
- else:
- self.skip = True
- def if_equal_left(self):
- #Skip if cell equals left cell
- if self.get_cell(self.pointer) == self.get_cell(self.pointer-1):
- pass
- else:
- self.skip = True
- def if_equal_right(self):
- #Skip if cell equals right cell
- if self.get_cell(self.pointer) == self.get_cell(self.pointer+1):
- pass
- else:
- self.skip = True
- def if_less_left(self):
- #Skip if cell is less than left cell
- if self.get_cell(self.pointer) < self.get_cell(self.pointer-1):
- pass
- else:
- self.skip = True
- def if_less_right(self):
- #Skip if cell is less than right cell
- if self.get_cell(self.pointer) < self.get_cell(self.pointer+1):
- pass
- else:
- self.skip = True
- def if_more_left(self):
- #Skip if cell is more than left cell
- if self.get_cell(self.pointer) > self.get_cell(self.pointer-1):
- pass
- else:
- self.skip = True
- def if_more_right(self):
- #Skip if cell is more than right cell
- if self.get_cell(self.pointer) > self.get_cell(self.pointer+1):
- pass
- else:
- self.skip = True
- def playsound(self):
- #TODO: Play sound of pitch cell
- pitch = self.get_cell(self.pointer)
- def big_output(self):
- #Output 80 characters
- result = ""
- for i in range(80):
- cur = self.get_cell(self.pointer + i)
- if cur >= 32 and cur <= 127:
- result += chr(cur)
- print(result)
- def set_zero(self):
- #Set cell to 0
- self.cells[self.pointer] = 0
- def write_drive(self):
- #Write cell to drive
- self.drive[self.needle] = self.get_cell(self.pointer)
- def receive_drive(self):
- #Write drive to cell
- self.cells[self.pointer] = self.get_drive(self.needle)
- def increment_needle(self):
- #Move needle +1
- self.needle += 1
- def decrement_needle(self):
- #Move needle -1
- self.needle -= 1
- def increment_memp(self):
- #Move memp +1
- self.memp += 1
- def decrement_memp(self):
- #Move memp -1
- self.memp -= 1
- def receive_memory(self):
- #Write memory to cell
- self.cells[self.pointer] = self.get_memory(self.memp)
- def write_memory(self):
- #Write cell to memory
- self.memory[self.memp] = self.get_cell(self.pointer)
- def create_op(self):
- #Creates an op
- self.world[self.get_cell(self.pointer+1)+self.cursor["x"]][self.get_cell(self.pointer+2)+self.cursor["y"]][self.get_cell(self.pointer+3)+self.cursor["z"]] = self.get_cell(self.pointer)
- def async_input(self):
- #TODO: Async Input
- pass
- def create_marker(self):
- #Create marker
- self.markers.insert(0,{"x":self.cursor["x"],"y":self.cursor["y"],"z":self.cursor["z"],"dir":self.cursor["dir"]})
- def delete_marker(self):
- #Delete first marker
- self.markers.pop(0)
- def goto_marker(self):
- #Goto first marker and kill it
- self.cursor["x"] = self.markers[0]["x"]
- self.cursor["y"] = self.markers[0]["y"]
- self.cursor["z"] = self.markers[0]["z"]
- self.cursor["dir"] = self.markers[0]["dir"]
- self.markers.pop(0)
- def set_needle(self):
- #Set needle pos to cell
- self.needle = self.get_cell(self.pointer)
- def set_memp(self):
- #Set memory pointer pos to cell
- self.memp = self.get_cell(self.pointer)
- def set_pointer(self):
- #Set pointer pos to cell
- self.pointer = self.get_cell(self.pointer)
- def set_cursor(self):
- #Set cursor pos
- self.cursor["x"] = self.get_cell(self.pointer)
- self.cursor["y"] = self.get_cell(self.pointer+1)
- self.cursor["z"] = self.get_cell(self.pointer+2)
- def get_op(self):
- #Get op of pos
- if self.get_cell(self.pointer) in self.world:
- if self.get_cell(self.pointer+1) in self.world[self.get_cell(self.pointer)]:
- if self.get_cell(self.pointer+2) in self.world[self.get_cell(self.pointer)][self.get_cell(self.pointer+1)]:
- self.cells[self.pointer] = self.world[self.get_cell(self.pointer)][self.get_cell(self.pointer+1)][self.get_cell(self.pointer+2)]
- else:
- self.cells[self.pointer] = 0
- else:
- self.cells[self.pointer] = 0
- else:
- self.cells[self.pointer] = 0
- def relative_set_cursor(self):
- #Relative set cursor pos
- self.cursor["x"] += self.get_cell(self.pointer)
- self.cursor["y"] += self.get_cell(self.pointer+1)
- self.cursor["z"] += self.get_cell(self.pointer+2)
- def get_pointer(self):
- #Set cell to pointer pos
- self.cells[self.pointer] = self.pointer
- def get_memp(self):
- #Set cell to memp pos
- self.cells[self.pointer] = self.memp
- def get_needle(self):
- #Set cell to needle pos
- self.cells[self.pointer] = self.needle
- def wait_key():
- ''' Wait for a key press on the console and return it. '''
- #Curtesy of http://stackoverflow.com/a/34956791/6150373
- result = None
- if os.name == 'nt':
- import msvcrt
- result = msvcrt.getch()
- else:
- import termios
- fd = sys.stdin.fileno()
- oldterm = termios.tcgetattr(fd)
- newattr = termios.tcgetattr(fd)
- newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
- termios.tcsetattr(fd, termios.TCSANOW, newattr)
- try:
- result = sys.stdin.read(1)
- except IOError:
- pass
- finally:
- termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
- return result
Advertisement
Add Comment
Please, Sign In to add comment