diff options
Diffstat (limited to 'oo.py')
-rw-r--r-- | oo.py | 147 |
1 files changed, 133 insertions, 14 deletions
@@ -71,10 +71,15 @@ class ooPuzzle: (3, 2) : (1, 0, 1, 0), (3, 3) : (0, 1, 0, 1), - (4, 0) : (1, 1, 1, 1), - (4, 1) : (1, 1, 1, 1), - (4, 2) : (1, 1, 1, 1), - (4, 3) : (1, 1, 1, 1) } + (4, 0) : (0, 1, 1, 1), + (4, 1) : (1, 0, 1, 1), + (4, 2) : (1, 1, 0, 1), + (4, 3) : (1, 1, 1, 0), + + (5, 0) : (1, 1, 1, 1), + (5, 1) : (1, 1, 1, 1), + (5, 2) : (1, 1, 1, 1), + (5, 3) : (1, 1, 1, 1) } def set_pieces_from_edges(self, horiz_edges, vert_edges): """Convert edge dictionaries into a puzzle state. @@ -178,7 +183,7 @@ class ooPuzzle: """Randomly rotate the current pieces.""" for x in range(self.X): for y in range(self.Y): - self.pieces[x, y] = random.randrange(4) + self.orients[x, y] = random.randrange(4) def is_solved(self): """Checks whether the puzzle is in a solved state.""" @@ -186,8 +191,8 @@ class ooPuzzle: # check internal edge pairs for x in range(self.X - 1): - for y in range(self.Y - 1): - + for y in range(self.Y): + # check horizontal edge pair right of (x, y) l_piece = self.pieces [x, y] @@ -198,6 +203,9 @@ class ooPuzzle: r_edge = self.PIECE_ORIENT_TO_EDGES[r_piece, r_orient][0] if l_edge != r_edge: return False + for x in range(self.X): + for y in range(self.Y - 1): + # check vertical edge pair below (x, y) u_piece = self.pieces [x, y] @@ -254,8 +262,10 @@ class ooPlay: self.screen.clear() # draw the help area and board state + self.help_ind = 0 border_line = self.X * "═" self.screen.addstr(self.Y - 2, 0, border_line) + self.write() self.display() # start the main loop @@ -270,8 +280,16 @@ class ooPlay: "┝┯┥┷", "┿┿┿┿"] + def display_pos(self, x, y): + """Update one position on the board, refresh screen.""" + piece = self.puzzle.pieces [x, y] + orient = self.puzzle.orients[x, y] + string = self.PIECE_ORIENT_TO_STRING[piece][orient] + self.screen.addstr(y, x, string) + self.screen.refresh() + def display(self): - """Display the state of the board, refresh screen.""" + """Update the state of the board, refresh screen.""" for x in range(self.puzzle.X): for y in range(self.puzzle.Y): piece = self.puzzle.pieces [x, y] @@ -280,9 +298,91 @@ class ooPlay: self.screen.addstr(y, x, string) self.screen.refresh() + pause_length = 80 + def write(self, string=None, pause=None): + """Write string to the bottom line. + + if string is narrower than line: + centers string within the line + if string is wider than line: + scrolls through string + + if a string is not given, then "h" is used + if pause is True, there will be a pause for reading + if pause is not given but a string is, there will be a pause + if neither a pause nor a string is given, there will not be a pause + + ooPlay.pause_length is the number of milliseconds per character to pause + """ + if string == None: + string = "h" + if pause == None: + pause = False + if pause == None: + pause = True + width = self.X - 1 + + # writing a string that fits in the width + + if len(string) <= width: + centered_string = string.center(width, " ") + self.screen.addstr(self.Y - 1, 0, centered_string) + self.screen.refresh() + if pause: curses.napms(2 * self.pause_length * len(string)) + curses.ungetch(0) # clear input + return + + # scrolling through a wider string + + strings = [string[i:i + width] for i in range(len(string) - width + 1)] + self.screen.addstr(self.Y - 1, 0, strings[0]) + self.screen.refresh() + curses.napms(self.pause_length * width) + for s in strings: + self.screen.addstr(self.Y - 1, 0, s) + self.screen.refresh() + curses.napms(self.pause_length) + if pause: curses.napms(self.pause_length * width) + self.screen.ungetch(0) # clear input + + def write_help(self): + """Write one of the help messages.""" + if self.help_ind == 0: + self.write("Help on controls.") + self.write("arrow keys: move cursor") + self.write("space bar or return: rotates piece") + self.write("q: quit game") + self.write("n: new game") + self.write("r: randomize rotations") + self.write("t: toggle toroidal mode") + self.write("i: toggle inverted mode") + self.write("The next help is game explanation.") + self.write() + + if self.help_ind == 1: + self.write("Help on game.") + self.write("If game is not inverted," + + " the object is to have every line connect to another.") + self.write("If game is inverted," + + " the object is to have no two lines connected.") + 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.") + self.write("The next help is on controls.") + self.write() + + self.help_ind += 1 + self.help_ind %= 2 + def success(self): - """Display the win screen.""" - curses.flash() + """Write and respond to the win screen.""" + self.write("You won!") + self.write("r n q", pause=False) + while True: + inp = self.screen.getch() + if inp in map(ord, 'QqNnRr'): break + return chr(inp) def keyloop(self): """Wait for and parse keypress.""" @@ -295,12 +395,31 @@ class ooPlay: inp = chr(inp) if inp in " \n": self.puzzle.rotate_cw(self.xpos, self.ypos) - self.display() + self.display_pos(self.xpos, self.ypos) if self.puzzle.is_solved(): - self.success() - return - elif inp in "Qq": + inp = self.success() + if inp in "Qq": + self.write("Quit") return + elif inp in "Rr": + self.write("Randomize") + self.puzzle.random_orients() + self.display() + 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() + elif inp in "Hh": + self.write_help() + elif inp in "Ii": + self.write("Inverted mode is not implemented.") + self.write() + elif inp in "Tt": + self.write("Toroidal mode is not implemented.") + self.write() # parse arrow key input elif inp == curses.KEY_UP and self.ypos > 0: |