Skip to content

Commit

Permalink
add "Houston's algorithm" as an example of how to implement a hybrid …
Browse files Browse the repository at this point in the history
…algorithm
  • Loading branch information
jamis committed Jan 21, 2011
1 parent 80a7860 commit 7a233e8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
9 changes: 9 additions & 0 deletions examples/maze.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<script src="../lib/algorithms/division.js" type="text/javascript"></script>
<script src="../lib/algorithms/eller.js" type="text/javascript"></script>
<script src="../lib/algorithms/growing_tree.js" type="text/javascript"></script>
<script src="../lib/algorithms/houston.js" type="text/javascript"></script>
<script src="../lib/algorithms/hunt_and_kill.js" type="text/javascript"></script>
<script src="../lib/algorithms/kruskal.js" type="text/javascript"></script>
<script src="../lib/algorithms/prim.js" type="text/javascript"></script>
Expand Down Expand Up @@ -131,6 +132,14 @@ <h1>Wilson's Algorithm</h1>
</div>
<hr />

<h1>Houston's Algorithm</h1>
<div class="row">
<script type="text/javascript">Maze.createWidget("Houston", 5, 5, { "class": "small" });</script>
<script type="text/javascript">Maze.createWidget("Houston", 15, 15, { "class": "medium", id: "houston_bigger", interval: 25 });</script>
<script type="text/javascript">Maze.createWidget("Houston", 30, 30, { "class": "large", id: "houston_biggest", interval: 10 });</script>
</div>
<hr />

<h1>"Hunt and Kill" Algorithm</h1>
<div class="row">
<script type="text/javascript">Maze.createWidget("HuntAndKill", 5, 5, { "class": "small" });</script>
Expand Down
46 changes: 46 additions & 0 deletions src/algorithms/houston.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
###
Author: Jamis Buck <jamis@jamisbuck.org>
License: Public domain, baby. Knock yourself out.
The original CoffeeScript sources are always available on GitHub:
http://github.com/jamis/csmazes
###

# This hybrid algorithm was described to me by Robin Houston. It
# begins with the Aldous-Broder algorithm, to fill out the grid,
# and then switches to Wilson's after the grid is about 1/3
# populated.
#
# This gives you better performance than either algorithm by itself,
# and still ensures that the resulting maze is a uniform spanning
# tree.
class Maze.Algorithms.Houston extends Maze.Algorithm
constructor: (maze, options) ->
super
@options = options
@worker = new Maze.Algorithms.AldousBroder(maze, options)
@threshold = 2 * @maze.width * @maze.height / 3

isCurrent: (x, y) -> @worker.isCurrent(x, y)
isVisited: (x, y) -> @worker.isVisited(x, y)

step: ->
if @worker.remaining < @threshold
# kind of messy, need to tell the callback listener that
# current cell is no longer current, since the algorithm
# is changing.
[x, y] = [@worker.x, @worker.y]
delete @worker.x
delete @worker.y
@callback @maze, x, y

# switch to wilsons and redefine the step method so it
# no longer watches the threshold.
wilsons = new Maze.Algorithms.Wilson(@maze, @options)
wilsons.state = 1
wilsons.remaining = @worker.remaining

@worker = wilsons
@step = -> @worker.step()

@worker.step()
6 changes: 6 additions & 0 deletions src/widget.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ Maze.createWidget = (algorithm, width, height, options) ->
else if maze.algorithm.isVisited(x, y)
classes.push "f"

Houston: (maze, x, y, classes) ->
if maze.algorithm.worker.isVisited?
ACTIONS.Wilson(maze, x, y, classes)
else
ACTIONS.AldousBroder(maze, x, y, classes)

default: (maze, x, y, classes) ->
unless maze.isBlank(x, y)
classes.push "in"
Expand Down

0 comments on commit 7a233e8

Please sign in to comment.