In our first design (look at feature/bottleneck branch first commit SHA: 3e747b2), every position in the 2-D Maze would contain a TypeAwareList of instances of MazeComponents (Food, Free, Wall). While this gives extreme flexibility, it also turned out to severely slow down the deepcopying of the Maze, which is needed when we send the universe to the players. The game was basically not playable on a realisticly sized layout. We didn't notice that before because we were always testing on small layouts.
Just using strings instead of objects as an internal representation (SHA: 185d7ed) already makes the game something like 30-times faster. Using a multicharacter string instead of a list (SHA:???) gives another 2/3-fold speed increase.
This is all good, but the Maze now has an inconsistent API, that coudl lead to confusion. On the one hand, you access the MazeComponents with a OO interface (Maze.pos_of, Maze.get_at, Maze.remove_at, Maze.has_at). On the other hand, just accessing Maze values, like in Maze[0,1], would return the string representation of the MazeComponents.
We agreed that the string representation should remain an internal implementation detail of the Maze class, and that access to the Maze should be mediated by an OO API. The question is what API?