A simple algorithm for generating crosswords with Swift.
Based on Python Crossword Puzzle Generator.
CocoaPods:
pod 'CrosswordsGenerator'
Manual:
Copy CrosswordsGenerator.swift, Array2D.swift, ArrayShuffle.swift files to your project.
Initialization and crosswords generation:
let generator = CrosswordsGenerator(columns: 10, rows: 10, maxLoops: 2000, words: ["saffron", "pumpernickel", "leaven", "coda", "paladin", "syncopation", "albatross", "harp", "piston", "caramel", "coral", "dawn", "pitch", "fjord", "lip", "lime", "mist", "plague", "yarn", "snicker"]) generator.generate()
To get result:
let result = crosswordsGenerator.result
The result is an array of structures:
public struct Word { public var word = "" public var column = 0 public var row = 0 public var direction: WordDirection = .Vertical }
The sample of working:
--- Words --- ["pumpernickel", "syncopation", "albatross", "saffron", "paladin", "caramel", "snicker", "leaven", "piston", "plague", "coral", "pitch", "fjord", "coda", "harp", "dawn", "lime", "mist", "yarn", "lip"] --- Result --- pumpernickel- ---a-------e- ---l-------a- caramel-f--v- o--d----j--e- r--i----o--n- a-snicker---- l----o--dawn- -----d------- ----harp----- ------------- ------------- -------------
To generate the best crosswords in 10 attempts:
let crosswordsGenerator = CrosswordsGenerator() crosswordsGenerator.words = ["saffron", "pumpernickel", "leaven", "coda", "paladin", "syncopation", "albatross", "harp", "piston", "caramel", "coral", "dawn", "pitch", "fjord", "lip", "lime", "mist", "plague", "yarn", "snicker"] crosswordsGenerator.columns = 10 crosswordsGenerator.rows = 10 var bestResult: Array = Array() let attempts = 10 for var i: Int = 0; i < attempts; ++i { crosswordsGenerator.generate() let result = crosswordsGenerator.result if result.count > bestResult.count { bestResult.removeAll() for word in result { bestResult.append(word) } } }
To generate the best crosswords in 60 seconds:
let crosswordsGenerator = CrosswordsGenerator() crosswordsGenerator.words = ["saffron", "pumpernickel", "leaven", "coda", "paladin", "syncopation", "albatross", "harp", "piston", "caramel", "coral", "dawn", "pitch", "fjord", "lip", "lime", "mist", "plague", "yarn", "snicker"] crosswordsGenerator.columns = 10 crosswordsGenerator.rows = 10 var bestResult: Array = Array() let startTime = NSDate() let timeInterval: NSTimeInterval = 10 while (fabs(startTime.timeIntervalSinceNow) < timeInterval) { crosswordsGenerator.generate() let result = crosswordsGenerator.result if result.count > bestResult.count { bestResult.removeAll() for word in result { bestResult.append(word) } } }
Also we have option fillAllWords. After generation of crosswords you can fill words to grid in random places that have not intersections. For example:
let crosswordsGenerator = CrosswordsGenerator(columns: 15, rows: 15, words: ["beijing", "havana", "rome", "paris", "amsterdam"]) crosswordsGenerator.fillAllWords = true crosswordsGenerator.generate() amsterdam-b-h-- -----o----e-a-- -----m----i-v-- -----e----j-a-- paris-----i-n-- ----------n-a-- ----------g---- --------------- ---------------
In this repository you can find sample of working of this algorithm. Feel free. Happy coding!