diff --git a/.gitignore b/.gitignore index af3a6ff..98bb947 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ /dumps /finish.htm /tools/ackermann.o +/tools/venv +/tools/*.pdf diff --git a/notes.md b/notes.md index 9d24cf1..a4ba51b 100644 --- a/notes.md +++ b/notes.md @@ -136,7 +136,7 @@ So far so good, but what's this?? Aah, so it looks like each room is stored as a block of 5 words, the first four pointers to lengths of words: a string (the title), a string (the text), a list of pointers to strings (the exit names) and a list of pointers to more rooms (the exits), followed by a memory location to `call` (or `0000`). -Further analysis suggests that this particular call relates to the step counter for the Grues in the maze. +Further analysis suggests that this particular call relates to keeping track of which rooms in the maze have been visited, which is used to determine whether the code is shown when arriving at the designated room in the maze. We probably could have reached these same conclusions by analysing the suspicious-looking block of code following the room definitions, but assembly makes my head spin so ¯\\\_(ツ)\_/¯ diff --git a/tools/graph.py b/tools/graph.py new file mode 100755 index 0000000..403afd9 --- /dev/null +++ b/tools/graph.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# synacor.py - An implementation of the Synacor Challenge +# Copyright © 2017 RunasSudo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import struct +import textwrap + +rooms = {} + +class Door: + def __init__(self): + self.name = None + self.destination = None + +class Room: + def __init__(self): + self.location = None + self.name = None + self.description = None + self.doors = [] + self.callback = None + + def __str__(self): + return """< +{:04x}: {} +
{} +{} +>""".format( + self.location, + self.name, + '
'.join(textwrap.wrap(textwrap.shorten(self.description, 300), 50)), + '
Callback: {:04x}'.format(self.callback) if self.callback != 0 else '') + +items = {} + +class Item: + def __init__(self): + self.location = None + self.name = None + self.description = None + self.room = None + self.callback = None + + + def __str__(self): + return """< +{:04x}: {} +
{} +{} +>""".format( + self.location, + self.name, + '
'.join(textwrap.wrap(textwrap.shorten(self.description, 300), 50)), + '
Callback: {:04x}'.format(self.callback) if self.callback != 0 else '') + +# Read code into memory +SYN_MEM = [0] * 32768 + +with open('../dumps/init.raw', 'rb') as data: + i = 0 + while True: + byteData = data.read(2) + if len(byteData) < 2: + break + SYN_MEM[i] = struct.unpack('