My submission might have been scrubbed because I included a ZIP file,
so here it is again...
Wow, I can't wait to see that generator!
James Edward Gray II
Ok!
It's a bit long and not particularly smart, but here it is. The idea
was to make a sort of Ruby Choose-Your-Own adventure book, where the
computer chooses the adventure. By using variable names which made
sense in the context of the story, I could get the generator to
substitute random alternatives for nouns etc. while leaving the story
failrly easy to follow in code.
Reopening the Array class made multiple decisions very easy to program
- man I love Ruby! In the interim testing I see my unique-item-from-array
helper is not working because the arrays are not static. This makes for
some stories with duplicate names, which isn't nice.
I had some trouble coming up with good names for individual paragraphs
in the story tree, if you look you may see what I mean.
You have to run "story_generator.rb".
Les
------------------ Another run --------------------------------
A long time ago in the land of Middle-Earth there was a loyal Knight named
Sweetcheeks. Sweetcheeks lived there with her interesting Eyebrow
Derick, and the two were pals.
Middle-Earth was in uproar because the Necronomicon, the book of the
dead, had been stolen
by the smelly witch Smythe. Smythe had hidden the book in the Batpoo
Cave and it's presence there
would raise the dastardly Armies of Darkness at midnight!
Sweetcheeks's plan was to recover the book of the dead and outwit the
Armies of Darkness, with Derick serving as her navigator.
While Derick memorized the layout of the Batpoo Cave, Sweetcheeks
memorized the magical words needed to safely
retrieve the Necronomicon.
Sweetcheeks and Derick spent days exploring the Batpoo Cave, stumbling
through the damp undergrowth and biting insects.
When they finally found the Necronomicon, Sweetcheeks prepared to say
the secret phrase - but could not remember it!
'Flitzen!' she said, pretending to remember. With a shudder the earth
split open and the Armies of Darkness rose!
Sweetcheeks and Derick beat a hasty retreat through the Batpoo Cave,
but the elders of Middle-Earth were not interested in their
excuses and drove them out to face the enemy!
In a final desperate standoff the friends remembered the magic words
and used the secret powers of the Necronomicon to defeat the Armies of
Darkness!
THE END.
--------------------------- THE CODE ----------------------------------
<code>
<story_generator.rb>
require 'helper'
require 'phrase_generator'
require 'character'
class StoryGenerator
def initialize(phraseGenerator, mainCharacter, subCharacter)
@pg = phraseGenerator
@mc = mainCharacter
@sc = subCharacter
getWords
end
def introPhrase
["A long time ago", "In a parallel universe", "On the planet of
Albanara"].any
end
def getWords
@once = introPhrase
@nod = @pg.landName
@brave = @pg.goodAdjective
@loyal = @pg.goodAdjective
@knight = @pg.title
@friends = @pg.bondingPhrase
@john = @mc.name
@his = @mc.hisHer
@him = @mc.himHer
@he = @mc.heShe
@dog = @sc.species
@skip = @sc.name
@consternation = @pg.consternation
@evil = @pg.evilAdjective
@scary = @pg.evilAdjective
@dragon = @pg.evilSpecies
@smarg = @pg.evilName
@clever = @pg.clever
@rent, @ribbons = @pg.outcome
@sword = @pg.cuttingWeapon
@whirling = @pg.distraction
@armies = @pg.evilArmy
@forest = @pg.hidingPlace
@necronomicon, @magicalBook = @pg.mysteriousArtifact
@abracadabra = @pg.magicWord
@scardyPants = [@john, @skip].any
@braveSirRobin = ([@john, @skip] - [@scardyPants]).to_s
@mummydesc, @mummy = @pg.magicalRescuer
end
def story
"#{@once} in the land of #{@nod} there was a #{@brave} #{@knight} named\n" +
"#{@john}. #{@john} lived there with #{@his} #{@loyal} #{@dog} #{@skip}, " +
"and the two were #{@friends}.\n\n" +
[premiseBattle, premiseNecro].any
end
def premiseBattle
"The land of #{@nod} was in #{@consternation} because of the #{@evil}\n" +
"influence of a #{@scary} #{@dragon} named #{@smarg}.\n\n" +
[distactPlanBattle, catapultPlanBattle].any
end
def distactPlanBattle
"#{@john} and #{@skip} came up with a #{@clever} plan - #{@skip} would\n" +
"distract the #{@dragon}, giving #{@john} the opportunity to
attack unseen.\n\n" +
executionBattle
end
def catapultPlanBattle
"#{@john} and #{@skip} came up with a #{@clever} plan - #{@skip}
would lure the\n" +
"#{@dragon} from it's lair while #{@john} would use one of
#{@nod}'s catapults to blast\n" +
"it from a safe distance.\n\n" +
catapultPlanOutcome
end
def catapultPlanOutcome
"#{@skip} bravely taunted the #{@dragon} and when it was in range,
#{@john} fired the catapult.\n" +
["The ball of flaming pitch struck the side of the #{@dragon} and
enveloped it in flames! Before\n" +
"long, nothing was left og the #{@scary} #{@dragon} was a pile of
cinders. " + returnToNod1,
"The ball of flaming pitch struck #{@skip} squarely between the
eyes! Before anyone could react,\n" +
"#{@skip} had disappeared in a ball of flame. #{@john} stared in
stunned silence, but the #{@dragon},\n" +
"sensing an opportunity, blasted #{@john} with it's magic.\n\n" +
failedCatapult,
].any
end
def failedCatapult
"#{@john} was crumpled by the blast, and that was the tragic end
of the two friends. The #{@dragon}'s\n" +
"reign of terror continued unabated over the unfortunate land of
#{@nod} for many years thereafter.\n\n"
end
def executionBattle
"They rode bravely into battle and #{@john} #{@rent} the #{@scary}
#{@dragon} in\n" +
"#{@ribbons} with #{@his} #{@sword} while #{@skip} created a
diversion by #{@whirling}!\n" +
resultBattle
end
def resultBattle
["#{@john} and #{@skip} became the heroes of #{@nod} and lived
happily ever after.\n\n",
"#{@john} and #{@skip} became well-reknowned in #{@nod} and lived
to be old and wise.\n\n",
"The wise friends were the heroes of the day but were soon
forgotten by the ungrateful citizens of #{@nod}.\n\n",
"#{@john} and #{@skip} left the land of #{@nod} to seek fame and
fortune and great pizza!\n\n"].any
end
def premiseNecro
"#{@nod} was in #{@consternation} because the #{@necronomicon},
the #{@magicalBook}, had been stolen\n" +
"by the #{@scary} #{@dragon} #{@smarg}. #{@smarg} had hidden the
book in the #{@forest} and it's presence there\n" +
"would raise the #{@evil} #{@armies} at midnight!\n\n" +
planNecro
end
def planNecro
"#{@john}'s plan was to recover the #{@magicalBook} and outwit the
#{@armies}, with #{@skip} serving as #{@his} navigator.\n" +
"While #{@skip} memorized the layout of the #{@forest}, #{@john}
memorized the magical words needed to safely\n" +
"retrieve the #{@necronomicon}.\n\n" +
[executionNecro1, executionNecro2].any
end
def executionNecro1
"The two friends set off to the #{@forest} to find the
#{@necronomicon}. They searched for many hours, fighting\n" +
"through the tangled vegetation and being scratched by long thorns
and briars. Deep in the darkest part of #{@forest}\n" +
"they finally found the #{@necronomicon}. #{@john} spoke the magic
phrase perfectly and the #{@magicalBook} flashed\n" +
"into #{@his} hands... \n\n" +
[resultNecro1, resultNecro2].any
end
def resultNecro1
"#{@john} was instantly subverted by the dark power of the magical
device! #{@he.capitalize} rose as the leader of the #{@armies}\n" +
"in siege against the land of #{@nod}, burning it to the ground.\n\n"
end
def resultNecro2
"#{@john}'s personality was instantly joined with the magical
device, moulding it's power for good. #{@he.capitalize} rose in great
power\n" +
"and with trusty #{@skip} by #{@his} side, #{@he} singlehandedly
destroyed the #{@armies}!\n\n" +
[returnToNod1, returnToNod2].any
end
def returnToNod1
"Returning to #{@nod}, #{@john} and #{@skip} were hailed as heroes
and crowned rulers of the land. They ruled justly\n" +
"for many years in the future.\n\n"
end
def returnToNod2
"Returning to #{@nod} however, #{@john} was subverted by #{@his}
newfound power. When the city elders would not crown #{@him} ruler,\n"
ยทยทยท
On 10/1/06, James Edward Gray II <james@grayproductions.net> wrote:
+
"#{@he} tried to take power from them. After a bitter war, #{@he}
was overcome and killed by the people of #{@nod}, led by #{@his}\n" +
"old friend #{@skip}.\n\n"
end
def executionNecro2
"#{@john} and #{@skip} spent hours exploring the #{@forest},
stumbling through the damp undergrowth and biting insects (sic).\n" +
"When they finally found the #{@necronomicon}, #{@john} prepared
to say the secret phrase - but could not remember it!\n" +
"'#{@abracadabra}!' #{@he} said, pretending to remember. With a
shudder the earth split open and the #{@armies} rose!\n\n" +
resultNecro3
end
def resultNecro3
["#{@john} and #{@skip} beat a hasty retreat through the
#{@forest}, but the elders of #{@nod} were not interested in their\n"
+
"excuses and drove them out to face the enemy!\n" +
"In a final desperate standoff the friends " + outcomeNecro,
"#{@john} and #{@skip} ran themselves ragged through the
brambles but the #{@armies} were gaining on them. Eventually\n" +
"they tumbled down an embankment and stumbled on " + salvationNecro
].any
end
def salvationNecro
"a #{@mummydesc}!\n" +
"#{@scardyPants} cowered in fear, but #{@braveSirRobin} quickly
started flattering their potential ally.\n\n" +
salvationOutcomeNecro
end
def salvationOutcomeNecro
[
"The #{@mummy} was so grateful to have found friends after so
many lonely years in the #{@forest} that he accepted their request\n"
+
"and rose in their defense. He singlehandedly crushed the
#{@armies} with powerful magic. For years the friends lived on
together\n" +
"in the #{@forest}, the #{@mummy} learning to adapt to #{@skip}
and #{@john} and them learning to love the #{@forest}.\n\n",
"The #{@mummy} was touched but not fooled. Annoyed by their
pleading, he blasted the two friends with his magic and then\n" +
"joined the evil #{@armies} to bring devastation to the whole
land of #{@nod}.\n\n"
].any
end
def outcomeNecro
["were crushed by the evil minions as they marched unopposed over
the whole land of #{@nod}.\n\n",
"remembered the magic words and used the secret powers of the
#{@necronomicon} to defeat the #{@armies}!\n\n",
"turned tail and ran.\n" +
"Skirting the land of #{@nod} they escaped to the kingdom of
Darrel, leaving #{@nod} to fend for itself.\n\n"
].any
end
def generate
response = story
response << "THE END.\n\n"
end
end
pg = PhraseGenerator.new
characters =
2.times do
name, hisHer, heShe, himHer = pg.goodName
characters << Character.new(name, hisHer, heShe, himHer,
pg.goodAdjective, pg.goodSpecies)
end
sg = StoryGenerator.new(pg, characters[0], characters[1])
puts sg.generate
</story_generator.rb>
<character.rb>
class Character
attr_reader :name, :hisHer, :heShe, :himHer, :adjective, :species
def initialize(name, hisHer, heShe, himHer, adjective, species)
@name = name
@hisHer = hisHer
@heShe = heShe
@himHer = himHer
@adjective = adjective
@species = species
end
end
</character.rb>
<helper.rb>
class Array
#Try to get a unique response
def any
@anylist = if !@anylist
response = nil
(self.length*3).times do
response = self[rand(length)]
break if !(@anylist.include? response)
end
@anylist << response
response
end
end
</helper.rb>
<phrase_generator.rb>
require 'helper'
class PhraseGenerator
def goodName
response =
if (rand(2)==1)
response << %W[Skip Derick Brian Kevin Brightbritches Lightleaves].any
response << "his"
response << "he"
response << "him"
else
response << %W[Goldilocks Cindy Sweetcheeks Barbara Liselle].any
response << "her"
response << "she"
response << "her"
end
response
end
def landName
%W[Dwenthym Narnia Atlantis Middle-Earth].any
end
def goodAdjective
%W[brave hardcore dedicated loyal honest tireless cool interesting].any
end
def title
%W[Knight Accountant Duke Stable-keep Botanist].any
end
def goodSpecies
%W[Aunt Eyebrow Donkey Armadillo Jellyfish Dog Page Friend].any
end
def consternation
(%W[consternation uproar mayhem] + ["a bind"]).any
end
def evilName
%W[Smarg Argonagas Bel Smythe Zoot].any
end
def evilAdjective
%W[dastardly despicable evil smelly repulsive scary terrifying
horrific].any
end
def evilSpecies
%W[dragon morgawr witch troll].any
end
def clever
%W[clever daring brave smile smart diabolical].any
end
def outcome
[
%W[rent ribbons],
%W[sliced strips],
["stabbed", "the knees"],
].any
end
def cuttingWeapon
["powerful magic sword", "portable angle-grinder"].any
end
def distraction
["whirling like a Dervish", "prancing like a poodle",
"rolling in the dirt", "screaming synonyms"].any
end
def princessName
%W[Leia Arabella Liselle Diana Linda Jenna].any
end
def hidingPlace
["Dark Forest", "Stinky Swamp", "Batpoo Cave"].any
end
def evilArmy
["Armies of Darkness", "Hordes of Hell"].any
end
def mysteriousArtifact
[
["Necronomicon", "book of the dead"],
["Sceptara", "magical Sceptre of Ra"]
].any
end
def magicWord
%W[Flitzen Bratwurst Alacazam Avrocadavra].any
end
def magicalRescuer
[
["massive stone Giant", "giant"],
["powerful magical Unicorn", "unicorn"],
["Mummy Lord", "mummy"]
].any
end
def bondingPhrase
["thick as thieves", "never apart", "always together", "secretly
lovers", "pals"].any
end
end
</phrase_generator.rb>
<test_helper.rb>
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
require 'helper'
class TestArray < Test::Unit::TestCase
def test_any
a = [1, 2, 3, 4, 5]
outOfBounds = false
100.times do
any = a.any
outOfBounds = true if !(a.include? any)
end
assert(!outOfBounds, "Item returned is not in the array")
end
def test_any_coverage
a = [1, 2, 3, 4, 5]
coverage = {}
count = 0
loop do
any = a.any
coverage[any] = 0
break if coverage.keys.length == 5
count += 1
if count > 100
assert(false, message="Possible random number problem,
coverage not achieved after 100 iterations")
return
end
end
assert(coverage.keys.length == 5)
assert(coverage.keys.inject{|a, b| a > b ? a : b} == 5) #max = 5
assert(coverage.keys.inject{|a, b| a < b ? a : b} == 1) #min = 1
end
def test_any_variance
a = [1, 2]
any1 = a.any
any2 = a.any
assert(any2 == 2) if any1 == 1
assert(any2 == 1) if any1 == 2
assert(a.include?(a.any))
end
end
</test_helper.rb>
</code>