diff options
| -rw-r--r-- | oo.py | 96 | 
1 files changed, 69 insertions, 27 deletions
@@ -13,6 +13,13 @@ class ooPuzzle:              each position of form (x in range(self.X),                                     y in range(self.Y))              to a piece id in range(6) + +        inverted_pieces is a closely related mapping to pieces, +        where all edges swap filled state +        NOT IMPLEMENTED + +        not_inverted_pieces is similar, but only swaps border edges +        NOT IMPLEMENTED          orients is a dictionary mapping:              each position of form (x in range(self.X), @@ -46,27 +53,18 @@ class ooPuzzle:          game_id is an integer used by set_pieces_from_game_id              It uniquely corresponds to the solution. -        inverted is a bool indicating whether -            pieces and inverted_pieces have been swapped -            NOT IMPLEMENTED! -          toroidal is a bool indicating whether              the border of the puzzle loops back to the opposite side -            NOT IMPLEMENTED!      """ -    def __init__(self, X, Y, game_id=None, inverted=False, toroidal=False): +    def __init__(self, X, Y, game_id=None, toroidal=False):          """Create a new ooPuzzle instance.          Arguments.                   X,Y : horizontal and vertical size of the puzzle               game_id : passed to ooPuzzle.set_pieces_from_game_id -            inverted : bool for swapping to "dark mode"              toroidal : bool for looping around the end of the puzzle - -        NotImplemented: inverted, toroidal          """          self.X, self.Y = X, Y -        self.inverted = inverted          self.toroidal = toroidal          self.pieces  = {}          self.orients = {} @@ -172,8 +170,6 @@ class ooPuzzle:                  self.pieces [x, y] = piece                  self.orients[x, y] = orient -        #TODO: properly account for the borders if toroidal -      def set_pieces_from_game_id(self, game_id=None):          """Convert game_id value into a solution puzzle state. @@ -204,15 +200,13 @@ class ooPuzzle:          vert_edges  = {}          horiz_edges = {} -        # set the border edges -        # if toroidal, these will be overwritten +        # set the right and bottom border edges +        # if toroidal, these will be overwritten in the next step          for x in range(self.X): -            vert_edges[x,      0] = 0              vert_edges[x, self.Y] = 0          for y in range(self.Y): -            horiz_edges[     0, y] = 0              horiz_edges[self.X, y] = 0          # set the edges determined by game_id @@ -227,6 +221,14 @@ class ooPuzzle:              game_id, bit = divmod(game_id, 2)              horiz_edges[col+1, y] = bit +        # make the left and top border edges match the opposite sides + +        for y in range(self.Y): +            horiz_edges[0, y] = horiz_edges[self.X, y] + +        for x in range(self.X): +            vert_edges[x, 0] = vert_edges[x, self.Y] +          # turn edges into pieces          self.set_pieces_from_edges(horiz_edges, vert_edges) @@ -332,7 +334,7 @@ class ooPuzzle:  class ooPlay:      """Encapsulates an oo game instance. -    Renders and interacts with an ooPuzzle instance. +    Renders and interacts with an ooPuzzle instance using curses.      """      def __init__(self, screen):          """Create a new ooPlay instance. @@ -344,7 +346,6 @@ class ooPlay:          self.Y, self.X = self.screen.getmaxyx()          self.puzzle = ooPuzzle(self.X, self.Y-2)          self.puzzle.random_orients() -        self.screen.clear()          # set up colors          curses.start_color() @@ -353,16 +354,48 @@ class ooPlay:          curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)          curses.init_pair(3, curses.COLOR_RED, curses.COLOR_GREEN) -        # draw the help area and board state +        # initialize flags          self.help_ind = 0          self.show_errors = False -        self.write() +        self.toroidal = False +        self.inverted = False + +        # draw the board state and help area +        self.screen.clear()          self.display() +        self.write()          # start the main loop          self.xpos, self.ypos = 0, 0          self.keyloop() +    def new_game(self): +        """Restarts an already-running ooPlay instance. +         +        Flags are preserved, and toroidal is implemented. +        toroidal is also passed to ooPuzzle at this point, +        so self.toroidal == self.puzzle.toroidal afterwards. +        """ +        self.Y, self.X = self.screen.getmaxyx() +        if self.toroidal: +            self.X = (self.X // 2) * 2 +            self.Y = (self.Y // 2) * 2 +            X = self.X       // 2 +            Y = (self.Y - 2) // 2 +        else: +            X = self.X +            Y = self.Y - 2 +        self.puzzle = ooPuzzle(X, Y, toroidal = self.toroidal) +        self.puzzle.random_orients() + +        # draw the board state and help area +        self.screen.clear() +        self.display() +        self.write() + +        # return to the main loop +        self.xpos, self.ypos = 0, 0 +      PIECE_ORIENT_TO_STRING = \          ["    ",           "╸╵╺╷", @@ -373,6 +406,10 @@ class ooPlay:      def display_subroutine(self, x, y):          """Update one position on the board.""" +        #TODO: use inverted_pieces and not_inverted_pieces +        #      if self.inverted +        #TODO: quadruple the display of the puzzle +        #      if self.puzzle.toroidal          piece  = self.puzzle.pieces [x, y]          orient = self.puzzle.orients[x, y]          string = self.PIECE_ORIENT_TO_STRING[piece][orient] @@ -473,7 +510,8 @@ class ooPlay:              self.write("If game is not toroidal," +                         " the borders cannot have lines extending outwards.")              self.write("If game is toroidal," + -                       " the borders loop back and may connect to the opposite side.") +                       " the borders loop back" + +                       " and may connect to the opposite side.")              self.write("The next help is on controls.")              self.write() @@ -513,10 +551,7 @@ class ooPlay:                      self.write()                  elif inp in "Nn":                      self.write("New Game") -                    self.puzzle.set_pieces_from_game_id() -                    self.puzzle.random_orients() -                    self.display() -                    self.write() +                    self.new_game()                  elif inp in "H":                      self.write_help()                  elif inp in "Ss": @@ -525,10 +560,17 @@ class ooPlay:                      self.display()                      self.write()                  elif inp in "Ii": -                    self.write("Inverted mode is not implemented.") +                    self.write("Puzzle is now" +                             + " NOT"*self.inverted +                             + " inverted.") +                    self.inverted = not self.inverted +                    self.display()                      self.write()                  elif inp in "Tt": -                    self.write("Toroidal mode is not implemented.") +                    self.write("Next new game will" +                             + " NOT"*self.toroidal +                             + " be toroidal.") +                    self.toroidal = not self.toroidal                      self.write()                  elif inp in "k" and self.ypos > 0:                      self.ypos -= 1  | 
