Skip to content

Commit

Permalink
add a Grid helper class to assist with looking up clues
Browse files Browse the repository at this point in the history
  • Loading branch information
alexdej committed Sep 20, 2024
1 parent 564fc09 commit 5191405
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 6 deletions.
67 changes: 61 additions & 6 deletions puz.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,17 +305,22 @@ def has_rebus(self):
return self.rebus().has_rebus()

def rebus(self):
return self.helpers.setdefault('rebus', Rebus(self))
if 'rebus' not in self.helpers:
self.helpers['rebus'] = Rebus(self)
return self.helpers['rebus']

def has_markup(self):
return self.markup().has_markup()

def markup(self):
return self.helpers.setdefault('markup', Markup(self))
if 'markup' not in self.helpers:
self.helpers['markup'] = Markup(self)
return self.helpers['markup']

def clue_numbering(self):
numbering = DefaultClueNumbering(self.fill, self.clues, self.width, self.height)
return self.helpers.setdefault('clues', numbering)
if 'clues' not in self.helpers:
self.helpers['clues'] = DefaultClueNumbering(self.fill, self.clues, self.width, self.height)
return self.helpers['clues']

def blacksquare(self):
return BLACKSQUARE2 if self.puzzletype == PuzzleType.Diagramless else BLACKSQUARE
Expand Down Expand Up @@ -506,7 +511,10 @@ def __init__(self, grid, clues, width, height):
'clue': clues[c],
'clue_index': c,
'cell': i,
'len': self.len_across(i)
'row': self.row(i),
'col': self.col(i),
'len': self.len_across(i),
'dir': 'across',
})
c += 1
is_down = self.row(i) == 0 or is_blacksquare(grid[i - width])
Expand All @@ -516,7 +524,10 @@ def __init__(self, grid, clues, width, height):
'clue': clues[c],
'clue_index': c,
'cell': i,
'len': self.len_down(i)
'row': self.row(i),
'col': self.col(i),
'len': self.len_down(i),
'dir': 'down'
})
c += 1
if c > lastc:
Expand Down Expand Up @@ -544,6 +555,50 @@ def len_down(self, index):
return c + 1


class Grid:
def __init__(self, grid, width, height):
self.grid = grid
self.width = width
self.height = height
assert len(self.grid) == self.width * self.height

def get_cell(self, row, col):
return self.grid[self.get_cell_index(row, col)]

def get_cell_index(self, row, col):
return row * self.width + col

def get_range(self, row, col, length, dir='across'):
if dir == 'across':
return self.get_range_across(row, col, length)
elif dir == 'down':
return self.get_range_down(row, col, length)
else:
assert False, "dir not one of 'across' or 'down'"

def get_range_across(self, row, col, length):
start = self.get_cell_index(row, col)
return self.grid[start:start+length]

def get_range_down(self, row, col, length):
return [self.grid[self.get_cell_index(row + i, col)] for i in range(length)]

def get_range_for_clue(self, clue):
return self.get_range(clue['row'], clue['col'], clue['len'], clue['dir'])

def get_string(self, row, col, length, dir='across'):
return ''.join(self.get_range(row, col, length, dir))

def get_string_across(self, row, col, length):
return ''.join(self.get_range_across(row, col, length))

def get_string_down(self, row, col, length):
return ''.join(self.get_range_down(row, col, length))

def get_string_for_clue(self, clue):
return ''.join(self.get_range_for_clue(clue))


class Rebus:
def __init__(self, puzzle):
self.puzzle = puzzle
Expand Down
28 changes: 28 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,34 @@ def test_clue_numbering(self):
self.assertEqual(len(p.clues), len(clues.across) + len(clues.down))
self.assertTrue(len(p.clues) > 0)

a1 = clues.across[0]
self.assertEqual(a1['num'], 1)
self.assertEqual(a1['dir'], 'across')
self.assertEqual(a1['clue'], "Mary's pet")
self.assertEqual(a1['clue_index'], 0)
self.assertEqual(a1['cell'], 0)
self.assertEqual(a1['row'], 0)
self.assertEqual(a1['col'], 0)
self.assertEqual(a1['len'], 4)

self.assertEqual(a1['clue'], p.clues[a1['clue_index']])

d1 = clues.down[0]
self.assertEqual(d1['num'], 1)
self.assertEqual(d1['dir'], 'down')
self.assertEqual(d1['clue'], "Hit high in the air")
self.assertEqual(d1['clue_index'], 1)
self.assertEqual(d1['cell'], 0)
self.assertEqual(d1['row'], 0)
self.assertEqual(d1['col'], 0)
self.assertEqual(d1['len'], 4)

self.assertEqual(d1['clue'], p.clues[d1['clue_index']])

soln = puz.Grid(p.solution, p.width, p.height)
self.assertEqual('LAMB', soln.get_string_for_clue(a1))
self.assertEqual('LOFT', soln.get_string_for_clue(d1))

def test_diagramless_clue_numbering(self):
p = puz.read('testfiles/nyt_diagramless.puz')
clues = p.clue_numbering()
Expand Down
4 changes: 4 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ description = run unit tests
commands =
python tests.py

[testenv:unittest]
description = quick run unit tests without installing package
skip_install = true

[testenv:lint]
description = run flake8 on source code
commands =
Expand Down

0 comments on commit 5191405

Please sign in to comment.