Next / Previous / Contents / Shipman's homepage

35. Puzzle.scan(): Traverse a row or column of the framework

kkck
# - - -   P u z z l e . s c a n

    def scan ( self, k, isV ):
        '''Scan across row k (isV==0) or down column k (isV==1)
        '''

This method generates a sequence of locations in the puzzle as Coord instances. It works in either horizontal or vertical directions, where k is the row number for a horizontal scan or a column number for a vertical scan.

First we find the limiting value of the scan. For a horizontal scan, this is the number of columns; for a vertical scan, the number of rows. We set limit to the limiting value and opp to the opposite orientation (see Section 12, “perpendicular(): Return the opposite orientation”).

kkck
        #-- 1 --
        # [ if isV is 0 ->
        #     opp  :=  1
        #     limit  :=  self.size[1]
        #   else ->
        #     opp  :=  0
        #     limit  :=  self.size[0] ]
        opp = perpendicular ( isV )
        limit = self.size[opp]

Instances of the Coord class are additive, so we can use an instance to define the step in either direction (see Section 75, “class Coord: One location in the grid”). Again, we eliminate a conditional by using multiplication. Just for utter transparency, here is a truth table for the values used below:

isVoppopp*kisV*k
01k0
100k
kkck
        #-- 2 --
        # [ if isV is 0 ->
        #     start  :=  row k, column 0, as a Coord
        #     step  :=  step 0 rows, 1 column
        #   else ->
        #     start  :=  row 0, column k, as a Coord
        #     step  :=  step 1 rows, 0 columns ]
        start = Coord ( opp*k, isV*k )
        step = Coord ( isV, opp )

        #-- 3 --
        # [ generate values start, start+step, start+step*2, ...,
        #   limit-1 ]
        for i in range(limit):
            yield start
            start += step