diff --git a/70_Poetry/csharp/Context.cs b/70_Poetry/csharp/Context.cs new file mode 100644 index 00000000..f9aecc06 --- /dev/null +++ b/70_Poetry/csharp/Context.cs @@ -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; } +} diff --git a/70_Poetry/csharp/IOExtensions.cs b/70_Poetry/csharp/IOExtensions.cs new file mode 100644 index 00000000..a2089264 --- /dev/null +++ b/70_Poetry/csharp/IOExtensions.cs @@ -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); +} diff --git a/70_Poetry/csharp/Phrase.cs b/70_Poetry/csharp/Phrase.cs new file mode 100644 index 00000000..1df6a774 --- /dev/null +++ b/70_Poetry/csharp/Phrase.cs @@ -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 _condition; + private readonly string _text; + private readonly Action _update; + + private Phrase(Predicate condition, string text) + : this(condition, text, _ => { }) + { + } + + private Phrase(string text, Action update) + : this(_ => true, text, update) + { + } + + private Phrase(string text) + : this(_ => true, text, _ => { }) + { + } + + private Phrase(Predicate condition, string text, Action 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); + } +} \ No newline at end of file diff --git a/70_Poetry/csharp/Poem.cs b/70_Poetry/csharp/Poem.cs new file mode 100644 index 00000000..ed08d30c --- /dev/null +++ b/70_Poetry/csharp/Poem.cs @@ -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; + } + } + } + } +} \ No newline at end of file diff --git a/70_Poetry/csharp/Poetry.csproj b/70_Poetry/csharp/Poetry.csproj index d3fe4757..6d06ca76 100644 --- a/70_Poetry/csharp/Poetry.csproj +++ b/70_Poetry/csharp/Poetry.csproj @@ -6,4 +6,7 @@ enable enable + + + diff --git a/70_Poetry/csharp/Program.cs b/70_Poetry/csharp/Program.cs new file mode 100644 index 00000000..8920b37e --- /dev/null +++ b/70_Poetry/csharp/Program.cs @@ -0,0 +1,5 @@ +global using Games.Common.IO; +global using Games.Common.Randomness; +global using Poetry; + +Poem.Compose(new ConsoleIO(), new RandomNumberGenerator()); \ No newline at end of file