mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 15:37:51 -08:00
Implement poetry generator
This commit is contained in:
11
70_Poetry/csharp/Context.cs
Normal file
11
70_Poetry/csharp/Context.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Poetry;
|
||||
|
||||
internal class Context
|
||||
{
|
||||
public int U { get; set; }
|
||||
public int I { get; set; }
|
||||
public int J { get; set; }
|
||||
public int K { get; set; }
|
||||
public bool SkipComma { get; set; }
|
||||
public bool UseGroup2 { get; set; }
|
||||
}
|
||||
8
70_Poetry/csharp/IOExtensions.cs
Normal file
8
70_Poetry/csharp/IOExtensions.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Poetry;
|
||||
|
||||
internal static class IOExtensions
|
||||
{
|
||||
|
||||
internal static void WritePhrase(this IReadWrite io, Context context)
|
||||
=> Phrase.GetPhrase(context).Write(io, context);
|
||||
}
|
||||
83
70_Poetry/csharp/Phrase.cs
Normal file
83
70_Poetry/csharp/Phrase.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
namespace Poetry;
|
||||
|
||||
internal class Phrase
|
||||
{
|
||||
private static Phrase[][] _phrases = new Phrase[][]
|
||||
{
|
||||
new Phrase[]
|
||||
{
|
||||
new("midnight dreary"),
|
||||
new("fiery eyes"),
|
||||
new("bird or fiend"),
|
||||
new("thing of evil"),
|
||||
new("prophet")
|
||||
},
|
||||
new Phrase[]
|
||||
{
|
||||
new("beguiling me", ctx => ctx.U = 2),
|
||||
new("thrilled me"),
|
||||
new("still sitting....", ctx => ctx.SkipComma = true),
|
||||
new("never flitting", ctx => ctx.U = 2),
|
||||
new("burned")
|
||||
},
|
||||
new Phrase[]
|
||||
{
|
||||
new("and my soul"),
|
||||
new("darkness there"),
|
||||
new("shall be lifted"),
|
||||
new("quoth the raven"),
|
||||
new(ctx => ctx.U != 0, "sign of parting")
|
||||
},
|
||||
new Phrase[]
|
||||
{
|
||||
new("nothing more"),
|
||||
new("yet again"),
|
||||
new("slowly creeping"),
|
||||
new("...evermore"),
|
||||
new("nevermore")
|
||||
}
|
||||
};
|
||||
|
||||
private readonly Predicate<Context> _condition;
|
||||
private readonly string _text;
|
||||
private readonly Action<Context> _update;
|
||||
|
||||
private Phrase(Predicate<Context> condition, string text)
|
||||
: this(condition, text, _ => { })
|
||||
{
|
||||
}
|
||||
|
||||
private Phrase(string text, Action<Context> update)
|
||||
: this(_ => true, text, update)
|
||||
{
|
||||
}
|
||||
|
||||
private Phrase(string text)
|
||||
: this(_ => true, text, _ => { })
|
||||
{
|
||||
}
|
||||
|
||||
private Phrase(Predicate<Context> condition, string text, Action<Context> update)
|
||||
{
|
||||
_condition = condition;
|
||||
_text = text;
|
||||
_update = update;
|
||||
}
|
||||
|
||||
public static Phrase GetPhrase(Context context)
|
||||
{
|
||||
var group = context.UseGroup2 ? _phrases[1] : _phrases[context.J];
|
||||
context.UseGroup2 = false;
|
||||
return group[context.I % 5];
|
||||
}
|
||||
|
||||
public void Write(IReadWrite io, Context context)
|
||||
{
|
||||
if (_condition.Invoke(context))
|
||||
{
|
||||
io.Write(_text);
|
||||
}
|
||||
|
||||
_update.Invoke(context);
|
||||
}
|
||||
}
|
||||
56
70_Poetry/csharp/Poem.cs
Normal file
56
70_Poetry/csharp/Poem.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
namespace Poetry;
|
||||
|
||||
internal class Poem
|
||||
{
|
||||
internal static void Compose(IReadWrite io, IRandom random)
|
||||
{
|
||||
var context = new Context();
|
||||
|
||||
while (true)
|
||||
{
|
||||
io.WritePhrase(context);
|
||||
|
||||
if (!context.SkipComma && context.U != 0 && random.NextFloat() <= 0.19)
|
||||
{
|
||||
io.Write(",");
|
||||
context.U = 2;
|
||||
}
|
||||
|
||||
if (random.NextFloat() <= 0.65)
|
||||
{
|
||||
io.Write(" ");
|
||||
context.U += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
io.WriteLine();
|
||||
context.U = 0;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
context.I = random.Next(1, 6);
|
||||
context.J += 1;
|
||||
context.K += 1;
|
||||
|
||||
if (context.U == 0 && context.J % 2 == 0)
|
||||
{
|
||||
io.Write(" ");
|
||||
}
|
||||
|
||||
if (context.J < 4) { break; }
|
||||
|
||||
context.J = 0;
|
||||
io.WriteLine();
|
||||
|
||||
if (context.K > 20)
|
||||
{
|
||||
io.WriteLine();
|
||||
context.U = context.K = 0;
|
||||
context.UseGroup2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\00_Common\dotnet\Games.Common\Games.Common.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
5
70_Poetry/csharp/Program.cs
Normal file
5
70_Poetry/csharp/Program.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
global using Games.Common.IO;
|
||||
global using Games.Common.Randomness;
|
||||
global using Poetry;
|
||||
|
||||
Poem.Compose(new ConsoleIO(), new RandomNumberGenerator());
|
||||
Reference in New Issue
Block a user