Implemented drawing the grid in player application
[getaclue.git] / crosswordpuzzle.py
index 7d3b270..a02f469 100644 (file)
@@ -9,11 +9,14 @@ import cairo
 
 class GridItem:
        # initialize the item
-       def __init__ (self, item_char='.', across_start = False, down_start = False,
-                                       occupied_across = False, occupied_down = False, num = 0,
-                                       clue_across = None, clue_down = None, revealed = False):
+       def __init__ (self, item_char='.', item_guess = None, across_start = False,
+                                       down_start = False,     occupied_across = False,
+                                       occupied_down = False, num = 0, clue_across = None,
+                                       clue_down = None, revealed = False):
                # character in the cell
                self.char = item_char
+               # guess of character in cell
+               self.guess = item_guess
                # is the cell the start of an across word?
                self.across_start = across_start
                # is the cell the start of a down word?
@@ -31,6 +34,59 @@ class GridItem:
                # is the letter revealed or hidden?
                self.revealed = revealed
 
+       # clear the across data
+       def clear_across_data (self):
+               self.across_start = False
+               self.occupied_across = False
+               self.clue_across = None
+               # if no down word starting at item
+               if self.down_start is False:
+                       self.numbered = 0
+               # if no down word at the item
+               if self.occupied_down is False:
+                       self.char = '.'
+                       self.revealed = False
+                       self.guess = None
+
+       # clear the down data
+       def clear_down_data (self):
+               self.down_start = False
+               self.occupied_down = False
+               self.clue_down = None
+               # if no across word starting at item
+               if self.across_start is False:
+                       self.numbered = 0
+               # if no across word at the item
+               if self.occupied_across is False:
+                       self.char = '.'
+                       self.revealed = False
+                       self.guess = None
+
+       # reset a grid item completely - use only to destroy whole grid, otherwise
+       # use either clear_across_data () or clear_down_data () for erasing single
+       # words
+       def reset (self):
+               # character in the cell
+               self.char = '.'
+               # guess of character in cell
+               self.guess = None
+               # is the cell the start of an across word?
+               self.across_start = False
+               # is the cell the start of a down word?
+               self.down_start = False
+               # is the cell occupied by a letter in an across word?
+               self.occupied_across = False
+               # is the cell occupied by a letter in a down word?
+               self.occupied_down = False
+               # numbering of the cell if it is the start of a word
+               self.numbered = 0
+               # clue across if the cell is the start of an across word
+               self.clue_across = None
+               # clue down if the cell is the start of a down word
+               self.clue_down = None
+               # is the letter revealed or hidden?
+               self.revealed = False
+
 # exception for too long words
 class TooLongWordException (Exception):
        def __init__ (self, word, length):
@@ -143,8 +199,9 @@ class CrosswordPuzzle:
                        html_contents.append ("<h2>Across clues</h2>")
                        html_contents.append ("<p>")
                        for word, clue in clues_across:
+                               # clue should be: <num> - clue text (chars)
                                clue_str = str (self.data[word[1]][word[2]].numbered) + " - " \
-                                                       + clue
+                                                       + clue + " (" + str (word[3]) + ")"
                                html_contents.append (clue_str)
                                html_contents.append ("<br />")
                        html_contents.append ("</p>")
@@ -153,7 +210,7 @@ class CrosswordPuzzle:
                        html_contents.append ("<p>")
                        for word, clue in clues_down:
                                clue_str = str (self.data[word[1]][word[2]].numbered) + " - " \
-                                                       + clue
+                                                       + clue + " (" + str (word[3]) + ")"
                                html_contents.append (clue_str)
                                html_contents.append ("<br />")
                        html_contents.append ("</p>")
@@ -335,6 +392,11 @@ class CrosswordPuzzle:
                                if i > 0 and i < len(word) - 1:
                                        if self.data[row+i][col-1].occupied_down is True:
                                                raise IntersectWordException (word, len(word))
+                               # if the previous column is the end of an across word
+                               if (self.data[row+i][col-1].occupied_across is True and
+                                       self.data[row+i][col].occupied_across is False):
+                                       raise IntersectWordException (word, len(word))
+
                        # on the next column except last column
                        if col < len(word) - 1:
                                # except the first and last row check if there is any
@@ -385,6 +447,11 @@ class CrosswordPuzzle:
                                if i > 0 and i < len(word) - 1:
                                        if self.data[row-1][col+i].occupied_across is True:
                                                raise IntersectWordException (word, len(word))
+                               # if the previous row is the end of a down word
+                               if (self.data[row-1][col+i].occupied_down is True and
+                                       self.data[row][col+i].occupied_down is False):
+                                       raise IntersectWordException (word, len(word))
+
                        # on a next row
                        if (row < (self.rows - 1)):
                                # except the first and last letter check if there is
@@ -444,3 +511,48 @@ class CrosswordPuzzle:
 
                self.frozen_grid = False
 
+       # reset the entire grid
+       def reset_grid (self):
+               # run through the grid
+               for row in range (self.rows):
+                       for col in range (self.cols):
+                               # re-initialize all data
+                               self.data[row][col].reset ()
+
+               self.frozen_grid = False
+
+       # remove an across word at position
+       def remove_word_across (self, row, col):
+               # if grid is frozen don't allow removal of word
+               if self.frozen_grid is True:
+                       raise FrozenGridException
+
+               word, brow, bcol, l = self.get_word_across (row, col)
+
+               # traverse from the beginning to end of the word and erase it
+               c = bcol
+               while True:
+                       if self.data[brow][c].occupied_across is True:
+                               self.data[brow][c].clear_across_data ()
+                       else:
+                               break
+                       c += 1
+
+       # remove a down word at position
+       def remove_word_down (self, row, col):
+               # if grid is frozen don't allow removal of word
+               if self.frozen_grid is True:
+                       raise FrozenGridException
+
+               word, brow, bcol, l = self.get_word_down (row, col)
+               # traverse from the beginn to end of the word and erase it
+               r = brow
+               while True:
+                       if self.data[r][bcol].occupied_down is True:
+                               self.data[r][bcol].clear_down_data ()
+                       else:
+                               break
+                       r += 1
+
+
+