Copy over template used for Tappy Terror index

Brings over the template used for the Tappy Terorr index page from the web.py
version. The new version still needs to be properly ported to a jinja template
in order to actually do everything the original one did, but this will at
least give a scaffolding to start converting the web layer stuff to flask.
Rename test case to be clearly for the web-facing parts of Tappy Terror
Port Location over

Extracts the Location class from the old Tappy Terror and brings it over to
Flask-land. This was straightforward: the class is self contained and just
encapsulates a bit of logic about mob spawning.

The only hard decision was what to do about the things that were set in module
level variables as configuration in the original Tappy Terror. I've decided to
keep them as module level variables for now just for the ease of porting, but
I think they should go into their own config structure if we end up with
a bunch of them. We didn't change these much when we were setting up the
game initially, but I still find it icky that we had to tune them by
changing code, not data.

Adds tests for mob spawning and removal to ensure that gameplay asusmptions
about mob counts aren't violated.
Port Polygon over

Bring Polygon over in to Flask-land. We used this to represent bounding boxes
for rooms in the game because there obviously isn't a good alternative to
rolling your own class when it comes to representing 2D bounding boxes :)
This was another straightforward section of code to port because it doesn't
depend on anything else.

I'm not sure why this class is around and useful, thanks me from many years
ago. It should have some more behaviors if it's actually going to be more
than "hey here's a vertex list".

Also bring over the floor list, which defines the bounds of various rooms
in the game. This is the primary place that Polygons get constructed,
so it's easy to pull over at the same time.

Adds a couple of silly tests that basically just construct Polygons so
that there's at least a little test coverage.
Port draw_image()

Ports draw_image() to draw_board_image(game_board, rooms). draw_image() poked
in to the core data to pull the list of rooms and a representation of the
current board state. I've ported that code into a function which takes those
inputs as args to make it more testable.

test_draw_board_image() uses empty location data; this is the same as the
start of the game. Code copypasta'd from the old initalize_game_board().

Still to do with this:
- Confirm we're correctly displaying this on the frontend
- Symlink a "static/latest.png" to the last created board
- Update template to use latest.pnge
Symlink latest.png -> last generated board image

Finishes up the TODOs from my previous commit. Only needed to do the symlink
on the python side because I had already made the template point to latest.png.
Port TappyTerrorGame

Brings TappyTerrorGame over to flask land. In the original version, this class
also managed spawning and culling threads. I've removed that for now because
the implementation left a little much to be desired (many threads updating
data structures without obvious mutexes... ouch). The changes here mean that
the game is pretty useless until I hook up alternative pumps to those threads.

TODOs:
- [ ] Implement shelve_data() or figure out a better way to deal with state
- [ ] Implement endpoint for AMD data pushes
- [ ] Implement alternative parser to real_get_location_dump
Hoist bounds and location name into Location

The code uses two maps indexed by location name to track the location data
and the location bounds. This can all just live in the Location objects
so that things are a little clearer.
Port shelve_data()

Brings shelve_data() over into flaskland. This just shelves the class objects
that are stored in TappyTerrorGame. It ought to be something more robust, but
for whatever reason we didn't implement it like that. I'm going to port this
over to something SQLite based.
Port unshelving to index render