Skip to content

Instantly share code, notes, and snippets.

@gaxar77
Created March 28, 2010 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaxar77/347070 to your computer and use it in GitHub Desktop.
Save gaxar77/347070 to your computer and use it in GitHub Desktop.
This is a demonstration of how to compose verses based on iambic patameter. The demonstration consists of three files. The two C# code files are meant to be included in one project and compiled, and the xml file is to be placed in the same directory as th
<bank>
<word text="a" part="article" stress="u"/>
<word text="an" part="article" stress="u"/>
<word text="the" part="article" stress="u"/>
<word text="and" part="conjunction" stress="u"/>
<word text="but" part="conjunction" stress="u"/>
<word text="for" part="conjunction" stress="u"/>
<word text="to" part="preposition" stress="u"/>
<word text="from" part="preposition" stress="u"/>
<word text="of" part="preposition" stress="u"/>
<word text="when" part="relativepronoun" stress="u"/>
<word text="who" part="relativepronoun" stress="u"/>
<word text="will" part="verb" stress="u"/>
<word text="whose" part="relativepronoun" stress="u"/>
<word text="in" part="preposition" stress="u"/>
<word text="within" part="preposition" stress="us"/>
<word text="begin" part="verb" stress="us"/>
<word text="pretend" part="verb" stress="us"/>
<word text="all" part="pronoun" stress="u"/>
<word text="all" part="pronoun" stress="s"/>
<word text="cat" part="noun" stress="s"/>
<word text="cake" part="noun" stress="s"/>
<word text="form" part="noun" stress="s"/>
<word text="crave" part="verb" stress="s"/>
<word text="storm" part="noun" stress="s"/>
<word text="frame" part="verb" stress="s"/>
<word text="part" part="noun" stress="s"/>
<word text="frame" part="verb" stress="s"/>
<word text="frame" part="verb" stress="s"/>
<word text="shallow" part="noun" stress="su"/>
<word text="only" part="adverb" stress="su"/>
<word text="cavern" part="noun" stress="su"/>
<word text="treasure" part="noun" stress="su"/>
<word text="flower" part="noun" stress="su"/>
<word text="research" part="noun" stress="su"/>
<word text="freedom" part="noun" stress="su"/>
<word text="assume" part="verb" stress="us"/>
<word text="reprove" part="verb" stress="us"/>
<word text="disguize" part="verb" stress="us"/>
<word text="remain" part="verb" stress="us"/>
<word text="create" part="verb" stress="us"/>
<word text="unveil" part="verb" stress="us"/>
<word text="theraflu" part="noun" stress="sus"/>
<word text="capricorn" part="noun" stress="sus"/>
<word text="apricot" part="noun" stress="sus"/>
<word text="salary" part="noun" stress="sus"/>
<word text="memory" part="noun" stress="sus"/>
<word text="permeate" part="noun" stress="sus"/>
<word text="calender" part="noun" stress="sus"/>
<word text="monitor" part="verb" stress="sus"/>
<word text="rivalry" part="noun" stress="sus"/>
<word text="telephone" part="noun" stress="sus"/>
<word text="azula" part="noun" stress="usu"/>
<word text="granola" part="noun" stress="usu"/>
<word text="disfigure" part="noun" stress="usu"/>
<word text= "untangle" part="verb" stress="usu"/>
<word text= "dsishevel" part="verb" stress="usu"/>
<word text= "uncertain" part="verb" stress="usu"/>
<word text= "destruction" part="noun" stress="usu"/>
<word text= "construction" part="noun" stress="usu"/>
<word text= "remember" part="verb" stress="usu"/>
<word text= "insider" part="noun" stress="usu"/>
<word text= "imposter" part="noun" stress="usu"/>
<word text="" part="noun" stress="susu"/>
<word text="" part="noun" stress="susu"/>
<word text="" part="noun" stress="susu"/>
<word text="" part="verb" stress="susu"/>
<word text="" part="noun" stress="usus"/>
<word text="" part="noun" stress="usus"/>
<word text="" part="noun" stress="usus"/>
<word text="" part="verb" stress="usus"/>
</bank>
/* Nonsensical Poem Generater
* Author: Guido Arbia
*
* Description
* =======================================================
* This program uses a very simple class library I wrote
* to generate nonsensical verses in iambic patameter.
* It cannot produce meaningful information, or anything
* poetically deep, because it does not deal with meaning.
* That project would be far more difficult. But it does
* take a list of words and according to their meter string
* them together to form a poem that has perfect rhythm.
*
* When the program runs, merely type the path of the
* XML Word dictionary file, and hit enter. It will then use
* my class library to produce three nonsensical verses
* of iambic patameter.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Words;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the path of the XML Word Dictionary: ");
string path = Console.ReadLine();
TextReader fs = File.OpenText(path);
string xmlstuff = fs.ReadToEnd();
WordList wl = new WordList(xmlstuff);
IambicWordPicker wp = new IambicWordPicker(wl);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
Console.WriteLine(GenerateIambicLine(wp));
}
Console.WriteLine();
}
Console.ReadKey();
}
static string GenerateIambicLine(IambicWordPicker wp)
{
IambicSyllableTank st = new IambicSyllableTank(8);
IambicSyllableLengthPattern slp = new IambicSyllableLengthPattern(8, 3);
string line = "";
while (slp.LengthsNext())
{
int l = slp.NextLength();
string wt = wp.Pick(st.IsNextSyllableStressed(), l).Text;
st.ConsumeSyllables(l);
line += wt + " ";
}
return line;
}
}
}
/* File: Words.CS
* Author: Guido Arbia
*
* Description:
* ========================================================
* Enables you to compose verses of imabic patameter albeit
* generating ungramatical and incoherent texts. This is not a
* demonstration on my part to compose meaningful
* information through code, but a demonstration of how to
* string together words from a given vocabulary so that
* it flows perfectly in iambic patameter.
*
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace Words
{
class InvalidStructureException : Exception
{
public InvalidStructureException(string message)
: base(message)
{
}
}
class XmlWordListParser
{
XmlDocument xmlDoc = null;
XmlElement xmlWordBankTag = null;
WordList List = null;
String Xml = null;
public XmlWordListParser(string xml, WordList list)
{
List = list;
Xml = xml;
}
public void Parse()
{
xmlDoc = new XmlDocument();
xmlDoc.LoadXml(Xml);
if (!FindWordBankTag()) throw new InvalidStructureException("Cannot find word bank tag.");
GenerateList(List);
}
private void GenerateList(WordList list)
{
for (int i = 0; i < xmlWordBankTag.ChildNodes.Count; i++)
{
XmlElement tag = (XmlElement)xmlWordBankTag.ChildNodes.Item(i);
if (IsWordTag(tag))
{
list.Add(WordFromTag(tag));
}
else
{
throw new InvalidStructureException("Must contain only word tags.");
}
}
}
private PartOfSpeech TranslatePart(string part)
{
switch (part.ToLower())
{
case "adjective":
return PartOfSpeech.Adjective;
case "adverb":
return PartOfSpeech.Adverb;
case "article":
return PartOfSpeech.Article;
case "noun":
return PartOfSpeech.Noun;
case "relativepronoun":
return PartOfSpeech.RelativePronoun;
case "preposition":
return PartOfSpeech.Preposition;
case "verb":
return PartOfSpeech.Verb;
case "conjuction":
return PartOfSpeech.Conjuction;
}
return PartOfSpeech.Unknown;
}
private Word WordFromTag(XmlElement tag)
{
string text = tag.Attributes.GetNamedItem("text").Value;
string stress = tag.Attributes.GetNamedItem("stress").Value;
string part = tag.Attributes.GetNamedItem("part").Value;
return new Word(text, stress, TranslatePart(part));
}
private bool IsWordTag(XmlElement el)
{
if (el.Name.ToLower() == "word") return true;
return false;
}
private bool FindWordBankTag()
{
for (int i = 0; i < xmlDoc.ChildNodes.Count; i++)
{
XmlElement tag = (XmlElement)xmlDoc.ChildNodes.Item(i);
if (tag.Name.ToLower() == "bank")
{
xmlWordBankTag = tag;
return true;
}
}
return false;
}
}
class WordList : List<Word>
{
public WordList()
: base()
{
}
public WordList(string Xml)
{
LoadFromXML(Xml, false);
}
public void LoadFromXML(string XML)
{
LoadFromXML(XML, true);
}
public void LoadFromXML(string XML, bool clearFirst)
{
if (this.Count() > 0 && clearFirst) this.Clear();
(new XmlWordListParser(XML, this)).Parse();
}
public WordList ThoseWithStress(string[] stresses)
{
WordList newList = new WordList();
for (int i = 0; i < this.Count(); i++)
{
Word currentWord = this.ElementAt(i);
if (currentWord.MatchesStress(stresses))
newList.Add(new Word(currentWord));
}
return newList;
}
public WordList ThoseWithText(string[] texts)
{
WordList newList = new WordList();
for (int i = 0; i < this.Count(); i++)
{
Word currentWord = this.ElementAt(i);
if (currentWord.MatchesText(texts))
newList.Add(new Word(currentWord));
}
return newList;
}
public WordList ThoseWithPartOfSpeech(PartOfSpeech[] partsOfSpeech)
{
WordList newList = new WordList();
for (int i = 0; i < this.Count(); i++)
{
Word currentWord = this.ElementAt(i);
if (currentWord.MatchesPartOfSpeech(partsOfSpeech))
newList.Add(new Word(currentWord));
}
return newList;
}
}
class Word
{
public string Text { get; set; }
public string Stress { get; set; }
public PartOfSpeech PartOfSpeech { get; set; }
public Word(string text, string stress, PartOfSpeech partofSpeech)
{
Text = text;
Stress = stress;
PartOfSpeech = partofSpeech;
}
public Word(Word otherWord)
{
Text = otherWord.Text;
Stress = otherWord.Stress;
PartOfSpeech = otherWord.PartOfSpeech;
}
public bool MatchesPartOfSpeech(PartOfSpeech[] partsOfSpeech)
{
for (int i = 0; i < partsOfSpeech.Count(); i++)
{
if (PartOfSpeech == partsOfSpeech[i])
{
return true;
}
}
return false;
}
public bool MatchesStress(string[] stresses)
{
for (int i = 0; i < stresses.Count(); i++)
{
if (Stress == stresses[i])
{
return true;
}
}
return false;
}
public bool MatchesText(string[] texts)
{
for (int i = 0; i < texts.Count(); i++)
{
if (Text == texts[i])
{
return true;
}
}
return false;
}
}
enum PartOfSpeech
{
Misc,
Unknown,
Verb,
Noun,
Adjective,
Adverb,
Preposition,
Article,
RelativePronoun,
Pronoun,
Conjuction
}
class SyllableTank
{
public int NumberOfSyllables { get; set; }
public SyllableTank(int numberOfSyllables)
{
NumberOfSyllables = numberOfSyllables;
}
public void ConsumeSyllables(int howMany)
{
if (howMany > NumberOfSyllables)
{
NumberOfSyllables = 0;
return;
}
NumberOfSyllables -= howMany;
}
public bool AnyMoreSyllables()
{
return NumberOfSyllables > 0 ? true : false;
}
}
class IambicSyllableTank : SyllableTank
{
public IambicSyllableTank(int numberOfSyllables) : base(numberOfSyllables) { }
public bool IsNextSyllableStressed()
{
return (NumberOfSyllables % 2 == 0) ? false : true;
}
}
class IambicSyllableLengthPattern
{
public static Random random = null;
public static int randomsDone = -1;
private SyllableTank tank;
private List<int> wordMesurements;
private int maxPerWord;
int lengthIndex = 0;
private int NumberOfLengths
{
get
{
return wordMesurements.Count;
}
}
public IambicSyllableLengthPattern(int numberOfSyllables, int maxSyllablesPerWord)
{
tank = new SyllableTank(numberOfSyllables);
wordMesurements = new List<int>();
maxPerWord = maxSyllablesPerWord;
while (tank.AnyMoreSyllables())
{
UpdateRandomizer();
GenerateLength();
}
}
public void ResetLengthIndex()
{
lengthIndex = 0;
}
public int NextLength()
{
int nextLength = wordMesurements[lengthIndex];
lengthIndex++;
return nextLength;
}
public bool LengthsNext()
{
return NumberOfLengths > lengthIndex ? true : false;
}
private void GenerateLength()
{
int length = 0;
int left = tank.NumberOfSyllables;
length = (left < maxPerWord) ? RandomLength(left) : RandomLength(maxPerWord);
tank.ConsumeSyllables(length);
wordMesurements.Add(length);
}
private int RandomLength(int max)
{
randomsDone++;
return random.Next(1, max + 1);
}
private static void UpdateRandomizer()
{
if (randomsDone == 10)
{
random = new Random(random.Next(100));
randomsDone = 0;
}
else if (random == null)
{
random = new Random();
}
}
}
class IambicWordPicker
{
WordList[] startingStressed;
WordList[] startingUnstressed;
Random random;
public IambicWordPicker(WordList wl)
{
random = new Random();
startingStressed = new WordList[4];
startingUnstressed = new WordList[4];
startingStressed[0] = wl.ThoseWithStress(new String[] { "s" });
startingStressed[1] = wl.ThoseWithStress(new String[] { "su" });
startingStressed[2] = wl.ThoseWithStress(new String[] { "sus" });
startingStressed[3] = wl.ThoseWithStress(new String[] { "susu" });
startingUnstressed[0] = wl.ThoseWithStress(new String[] { "u" });
startingUnstressed[1] = wl.ThoseWithStress(new String[] { "us" });
startingUnstressed[2] = wl.ThoseWithStress(new String[] { "usu" });
startingUnstressed[3] = wl.ThoseWithStress(new String[] { "usus" });
}
public Word Pick(bool startsStressed, int numberOfSyllables)
{
WordList[] wll = startsStressed ? startingStressed : startingUnstressed;
WordList wl = wll[numberOfSyllables - 1];
int listSize = wl.Count;
int index = random.Next(0, listSize);
return wl[index];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment