Skip to content

Commit ce9de09

Browse files
committed
Add Hunt-and-Kill algorithm
1 parent 5d6f9c8 commit ce9de09

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ A small remark: Code is not a 1:1 copy of the book's. For example I built render
1010

1111
- `AldousBroder`
1212
- `BinaryTree`
13+
- `HuntAndKill`
1314
- `Sidewinder`
1415
- `Wilson`
1516

algorithms/hunt_and_kill.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from random import choice
2+
3+
from typing import cast, Optional # noqa: F401
4+
5+
from base.grid import Grid
6+
from base.cell import Cell # noqa: F401
7+
8+
"""
9+
Hunt-and-Kill algorithm picks a random starting cell and randomly walks. It cannot walk on an already visited cell, and
10+
if finds at a dead-end (no more unvisited cells around current one), "hunts" from the northwest corner the first cell
11+
that is unvisted and has at least one visited neighbor; then starts walking again.
12+
"""
13+
14+
15+
class HuntAndKill:
16+
17+
@staticmethod
18+
def on(grid: Grid) -> Grid:
19+
current_cell = grid.random_cell() # type: Optional[Cell]
20+
21+
while current_cell is not None:
22+
unvisited_neighbors = \
23+
[neighbor for neighbor in current_cell.neighbors if len(neighbor.links) == 0] # type: ignore
24+
25+
if len(unvisited_neighbors) > 0:
26+
# as long as there are unvisited paths, walk them
27+
neighbor = cast(Cell, choice(unvisited_neighbors))
28+
current_cell.link(neighbor)
29+
current_cell = neighbor
30+
else:
31+
# enter hunt mode, find first unvisited cell near any visited cell
32+
current_cell = None
33+
for cell in grid.each_cell():
34+
visited_neighbors = [neighbor for neighbor in cell.neighbors if len(neighbor.links) > 0]
35+
if len(cell.links) == 0 and len(visited_neighbors) > 0:
36+
current_cell = cast(Cell, cell)
37+
neighbor = choice(visited_neighbors)
38+
current_cell.link(neighbor)
39+
break
40+
41+
return grid

demos/demo_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
from algorithms.sidewinder import Sidewinder
66
from algorithms.aldous_broder import AldousBroder
77
from algorithms.wilson import Wilson
8+
from algorithms.hunt_and_kill import HuntAndKill
89

910
import renderers.ascii_renderer as ASCIIRenderer
1011
import renderers.unicode_renderer as UNICODERenderer
1112
import renderers.png_renderer as PNGRenderer
1213

13-
ALGORITHMS = [BinaryTree, Sidewinder, AldousBroder, Wilson]
14+
ALGORITHMS = [AldousBroder, BinaryTree, HuntAndKill, Sidewinder, Wilson]
1415
ALL_RENDERERS = [UNICODERenderer, ASCIIRenderer, PNGRenderer]
1516

1617

0 commit comments

Comments
 (0)