Word-Walker

Word-Walker

Word-Walker is a prototype tool for generating grids of letters that can be traversed with Boggle-rules to spell out the seed string. Usage is described in the readme.

Context

While working on our final project for Lighthouse Labs, I had the idea of creating an interactive story game engine in which the player/reader travels along a grid of seemingly scrambled letters in order to spell out the words of the narrative. At various points, multiple paths would be valid:

Y-O-U - S-E-E - A - (C-A-S-T-L-E…) / (C-O-W…)

… with the player then continuing down the chosen path and a modified story becoming available. Distant regions of the grid (or areas that are no longer on the chosen path) might fade from view to be overlaid with storybook illustrations, etc.

I haven’t yet tried to build that game, but as a weekend project I took a shot at building a tool for generating a letter grid based on a provided string.

Example Usage

Seeding

passage = <<-PASSAGE
Shall I compare thee to a summer's day?
Thou art more lovely and more temperate:
Rough winds do shake the darling buds of May,
And summer's lease hath all too short a date:
PASSAGE

# Initialize a project and immediately build the grids:
project = WordWalker.build!(passage, passes: 1000)

# Alternatively, initialize the project and build the grids later:
project = WordWalker.read(passage)
project.build_grids(1000)

Output

# When ready, print the report (specify the number of top
# candidates to display, default 3):
passage.results(2)
##### RESULTS #####


##### TOP 2 GRIDS #####

[ -7, -6 ] => [ 2, 5 ]
D N M E E H A T . .
S M A Y R S L E H .
F U B G N I L R A L
D O H A K E T H D L
S O S U S A O T E T
N D D M M A R E T O
I . . E P O L S H O
W . L R S C I L A S
H L E O D A Y T H O
G Y V M T R A U O R
U A N D M O R E T D
O R E T A R E P M A
Score: 111.67

[ -9, -5 ] => [ 4, 3 ]
. H A S A E L S R E M U S D
. T E V . L Y A N D M O A N
L H O L E R O M T R A R M Y
L A E S D A Y T H O U E A F
T O R M U E T R C I L T M O
O S D M S H E A O S L R P S
R H D S A O T P M H A A E D
T A K N I W H G U O R E T U
D E T H E D A R L I N G B .
Score: 106.36


##### WORST QUALIFYING GRID #####

[ -3, -11 ] => [ 11, 5 ]
. . . . . . . . L H A H E S A
. . . . . . . L A T M E S E .
. . . . . . . H T O U M R L .
. . . . . . E S O N D S . . .
. . . . . . . T R Y A F . . .
. . . . . . D A T S O M . . .
. . . . . . . . B U D . . . .
A E R U G H W I N G N . . . .
T R E O M D N A Y D I . . . .
. P R R E M U S L S L . . . .
. M E S M A P A E D R . . . .
. T D S H M R O V O A . . . .
. . A A L O E T O S D . . . .
. . Y L I C T E L H E . . . .
. . T H O U E H E A H . . . .
. . . . A R T M R K T . . . .
. . . . . . . . O E . . . . .
Score: 52.14


##### STATISTICS #####

Failure Rate: 94.84%
Average completion rate of failed grids: 32.67%

Exporting

project.export  #=> ./output/word_walker_output.json

project.export(file_name: "my_grid.json") #=> ./output/my_grid.json

# #export can also take a grid argument, which can be :best, :worst, or a specific Grid instance.
project.export(grid: :best, file_name: "my_best_grid.json")
project.export(grid: :worst, file_name: "yucky.json")

this_grid = project.grids[57]
project.export(grid: this_grid, file_name: "just_right.json")

Notable Features

  • The string is “discoverable” within the grid by finding the starting point and using “Boggle-rules” to traverse one letter at a time.
  • An arbitrary number of build attempts can be made to find the optimal grid (in this case, optimal being the “tightest” grid, with the most reuse of letters across multiple words).
  • Specifiable and insightful console-level reporting to display best and worst grids across multiple builds, the build failure-rate, and the average completion-before-failure percentage.
  • Export results to JSON

Planned Features

  • Importing JSON Results: as one could expect.
  • Improved Path-Finding: Currently, new letters are distributed in random, adjacent directions from the previous ones with preference given to cells already occupied with that letter (ie., a look-ahead of 1). This can lead to dead-ending which causes the current build attempt to fail; asking for multiple builds brute-forces this problem, but ultimately, the longer the string, the less likely any success will be possible.
    • Ideally, solutions should be modular so that different path-finding strategies and settings can be used to create grids with different characteristics as desired.
  • Branching-Path Accommodation: Currently, only a single string can be used as the seed for a grid; as per the goal of the larger project, this program needs to be able to accept strings with branch-points (and ideally convergence-points) and still create a single grid.
  • Export to PDF: Even simple, non-branching grids seem like they might furnish “fun” classroom worksheets for young students to work on as mild puzzles. Being able to export printable handouts with options for displaying the entire seed text, blanks with spaces to show the shape of the expected words, etc., would make it configurable for teachers in various contexts, too.
  • Proper Ruby Gemification: It would be much slicker to use this tool from the command line. I think I’m pretty close as it stands.