git @ Cat's Eye Technologies Dipple / master python / room_with_a_view.py
master

Tree @master (Download .tar.gz)

room_with_a_view.py @masterraw · history · blame

# Some classes ostensibly for the purpose of implementing Nhohnhehr
# more efficiently.

# SPDX-FileCopyrightText: Chris Pressey, the original author of this work, has dedicated it to the public domain.
# For more information, please refer to <https://unlicense.org/>
# SPDX-License-Identifier: Unlicense


class Room(object):
    """A square grid of characters.

    >>> r = Room(3)
    >>> r.store(0, 0, 'a')
    >>> r.store(1, 0, 'b')
    >>> r.store(2, 0, 'c')
    >>> r.store(0, 1, '-')
    >>> r.store(0, 2, 'A')
    >>> r.store(2, 2, 'Z')
    >>> print r
    abc
    -  
    A Z

    """
    def __init__(self, size):
        self.size = size
        self.grid = {}

    def fetch(self, x, y):
        return self.grid.setdefault((x, y), ' ')

    def store(self, x, y, c):
        self.grid[(x, y)] = c

    def __str__(self):
        buf = ''
        for y in range(0, self.size):
            line = ''
            for x in range(0, self.size):
                line += self.fetch(x, y)
            buf += line + '\n'
        return buf.rstrip('\n')


class RoomWithAView(object):
    """A square grid of characters, which may be virtually rotated.
    orientation is an integer indicating the amount of rotation, in degrees,
    clockwise from the standard orientation.  It must be one of the following
    values: 0, 90, 180, or 270.

    >>> r = RoomWithAView(Room(3), 0)
    >>> r.store(0, 0, 'a')
    >>> r.store(1, 0, 'b')
    >>> r.store(2, 0, 'c')
    >>> r.store(0, 1, '-')
    >>> r.store(0, 2, 'A')
    >>> r.store(2, 2, 'Z')
    >>> print r
    abc
    -  
    A Z

    >>> r.orientation = 90
    >>> print r
    A-a
      b
    Z c

    >>> r.orientation = 180
    >>> print r
    Z A
      -
    cba

    >>> r.orientation = 270
    >>> print r
    c Z
    b  
    a-A

    """
    def __init__(self, room, orientation):
        self.room = room
        self.orientation = orientation

    @property
    def size(self):
        return self.room.size

    def rotate(self, x, y):
        if self.orientation == 0:
            return (x, y)
        elif self.orientation == 90:
            return (y, (self.size - 1) - x)
        elif self.orientation == 180:
            return ((self.size - 1) - x, (self.size - 1) - y)
        elif self.orientation == 270:
            return ((self.size - 1) - y, x)
        else:
            raise NotImplementedError("Orientation must be 0, 90, 180, or 270")

    def fetch(self, x, y):
        (rx, ry) = self.rotate(x, y)
        return self.room.fetch(rx, ry)

    def store(self, x, y, c):
        (rx, ry) = self.rotate(x, y)
        self.room.store(rx, ry, c)

    def __str__(self):
        buf = ''
        for y in range(0, self.size):
            line = ''
            for x in range(0, self.size):
                line += self.fetch(x, y)
            buf += line + '\n'
        return buf.rstrip('\n')


if __name__ == '__main__':
    import doctest
    doctest.testmod()