シン・エンドレスエイト

The Pioneer

シン・エンドレスエイト

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;


namespace ShinEndlessEight

{

public class Program

{

private const int ButThatOnlyGodKnows = 15498;


private const int PredeterminedPoolCount = 15497;

private const int PredeterminedBonFestivalCount = 15495;

private const int PredeterminedGoldfishScoopingCount = 15058;

private const int PredeterminedPartTimeJobCount = 9025;

private const int PredeterminedBaloonVendingCount = 6011;

private const int PredeterminedTwoOrMorePartTimeJobsCount = 360;


private const int PredeterminedRecognitionCount = 8768;


private static readonly List<string> PartTimeJobList = new List<string>()

{

"風船配り",

"荷物運び",

"レジ打ち",

"ビラ配り",

"電話番",

"モデル撮影会"

};


public static void Main(string[] args)

{

int waitTime = 0;


if (args.Length > 0)

{

int.TryParse(args[0], out waitTime);

}


Console.WriteLine("シン・エンドレスエイト");


Haruhi haruhi = new Haruhi();

Kyon kyon = new Kyon();

Nagato nagato = new Nagato();

Mikuru mikuru = new Mikuru();

Koizumi koizumi = new Koizumi();


do

{

EndlessSummer(haruhi, kyon, nagato, mikuru, koizumi, waitTime);

}

while (haruhi.ShouldLoopAgain);


Console.WriteLine();

kyon.Monologue("どうやらアタリを引いたらしい。");

nagato.Monologue("ループからの脱出を確認。");

Console.WriteLine("(The End)");

}


private static void EndlessSummer(Haruhi haruhi, Kyon kyon, Nagato nagato, Mikuru mikuru, Koizumi koizumi, int waitTime)

{

Console.WriteLine();


kyon.RecognitionProbability = Math.Pow(nagato.LoopCount / (double)ButThatOnlyGodKnows, 0.78);

haruhi.LoopCount++;

nagato.LoopCount++;

haruhi.PartTimeJobList.Clear();

nagato.Monologue($"{(nagato.RecognizeTheLoop() ? $"{nagato.LoopCount}回目。" : "……。")}");


bool isPredeterminedFinalSequence = nagato.LoopCount == ButThatOnlyGodKnows;

bool isLoopRecognized = kyon.RecognizeTheLoop(nagato.RecognitionCount, PredeterminedRecognitionCount, nagato.LoopCount, ButThatOnlyGodKnows, isPredeterminedFinalSequence);


if (isLoopRecognized)

{

kyon.Monologue("何かがおかしい。そう気付き始めたのは、お盆を過ぎた夏の盛りの日のことだ。");

}


if (haruhi.MakeDecision(haruhi.PoolCount, PredeterminedPoolCount, ButThatOnlyGodKnows, true))

{

haruhi.PoolCount++;

nagato.PoolCount++;

haruhi.Dialogue("それじゃあ、全員も揃ったことだし、出発しましょ");

kyon.Dialogue("どこに?");

haruhi.Dialogue("市民プールに決まっているじゃないの");

nagato.Monologue($"市民プールに行った。{nagato.PoolCount}回目。");

}


bool wentToBon = haruhi.MakeDecision(haruhi.BonFestivalCount, PredeterminedBonFestivalCount, ButThatOnlyGodKnows, true);

bool wentToGoldfishScooping = false;


if (wentToBon)

{

haruhi.BonFestivalCount++;

nagato.BonFestivalCount++;

kyon.Monologue("盆踊り会場が見つかった。時間は今夜。");

kyon.Monologue("だそうだ。");

nagato.Monologue($"盆踊りに行った。{nagato.BonFestivalCount}回目。");


wentToGoldfishScooping = haruhi.MakeDecision(haruhi.GoldfishScoopingCount, PredeterminedGoldfishScoopingCount, haruhi.BonFestivalCount, PredeterminedBonFestivalCount, ButThatOnlyGodKnows, true);


if (wentToGoldfishScooping)

{

haruhi.GoldfishScoopingCount++;

nagato.GoldfishScoopingCount++;

haruhi.Dialogue("みくるちゃん、あなたがやりたがっていた金魚すくいもあるわよ");

nagato.Monologue($"金魚すくいを行った。{nagato.GoldfishScoopingCount}回目。");

}

}


if (haruhi.MakeDecision(ButThatOnlyGodKnows))

{

haruhi.Dialogue("花火しましょう花火");

nagato.Monologue("花火をした。");

}


if (haruhi.MakeDecision(ButThatOnlyGodKnows))

{

haruhi.Dialogue("じゃあ、明日は昆虫採集ね");

nagato.Monologue("昆虫採集を行った。");

}


bool wentToPartTime = haruhi.MakeDecision(haruhi.PartTimeJobCount, PredeterminedPartTimeJobCount, ButThatOnlyGodKnows, true);

bool wentToBaloonVending = false;


if (wentToPartTime)

{

haruhi.PartTimeJobCount++;

nagato.PartTimeJobCount++;


kyon.Monologue("次の日は、アルバイトが待ち受けていた。");

string partTime;


wentToBaloonVending = haruhi.MakeDecision(haruhi.BaloonVendingCount, PredeterminedBaloonVendingCount, haruhi.PartTimeJobCount, PredeterminedPartTimeJobCount, ButThatOnlyGodKnows, true);


if (wentToBaloonVending)

{

haruhi.BaloonVendingCount++;

nagato.BaloonVendingCount++;

partTime = "風船配り";

nagato.Monologue($"風船配りを行った。{nagato.BaloonVendingCount}回目。アルバイト全体では{nagato.PartTimeJobCount}回目。");

}

else

{

partTime = haruhi.SelectFirstPartTimeJob(true);

nagato.Monologue($"{partTime}を行った。アルバイト全体では{nagato.PartTimeJobCount}回目。");

}


haruhi.PartTimeJobList.Add(partTime);


if (haruhi.MakeDecision(haruhi.TwoOrMorePartTimeJobsCount, PredeterminedTwoOrMorePartTimeJobsCount, haruhi.PartTimeJobCount, PredeterminedPartTimeJobCount, ButThatOnlyGodKnows, false))

{

haruhi.TwoOrMorePartTimeJobsCount++;

nagato.TwoOrMorePartTimeJobsCount++;

kyon.Monologue("またその次の日も、アルバイトが待ち受けていた。");


do

{

partTime = haruhi.SelectSecondOrMorePartTimeJob(PredeterminedBaloonVendingCount, PredeterminedPartTimeJobCount, ButThatOnlyGodKnows);


if (partTime == "風船配り")

{

haruhi.BaloonVendingCount++;

nagato.BaloonVendingCount++;

}


haruhi.PartTimeJobList.Add(partTime);

nagato.Monologue($"{partTime}を行った。{(partTime == "風船配り" ? $"{nagato.BaloonVendingCount}回目。" : string.Empty)}");

}

while (!haruhi.MakeDecision(ButThatOnlyGodKnows) && haruhi.PartTimeJobList.Count < (haruhi.BaloonVendingCount == PredeterminedBaloonVendingCount ? 5 : 6));

nagato.Monologue($"二種類以上のアルバイトが重複したパターンを観測。{nagato.TwoOrMorePartTimeJobsCount}回目。");

wentToBaloonVending = haruhi.PartTimeJobList.Contains("風船配り");

}

}


if (isLoopRecognized)

{

nagato.RecognitionCount++;

mikuru.Dialogue("未来に帰れなくなりましたぁ……");

koizumi.Dialogue("我々は同じ時間を延々とループしているのです");

nagato.Dialogue($"今回が、{nagato.LoopCount}回目に該当する");

kyon.Monologue("思わずクラリときたね。");


nagato.Dialogue($"過去{nagato.LoopCount - 1}回のシークエンスにおいて、涼宮ハルヒが取った行動はすべてが一致しているわけではない");

nagato.Dialogue($"{nagato.LoopCount - 1}回中、");


if (wentToBon && nagato.LoopCount - nagato.BonFestivalCount > 0)

{

nagato.Dialogue($"盆踊りに行かなかったシークエンスが{nagato.LoopCount - nagato.BonFestivalCount}回ある");


if (wentToGoldfishScooping && nagato.BonFestivalCount - nagato.GoldfishScoopingCount > 0)

{

nagato.Dialogue($"盆踊りに行ったが金魚すくいをしなかったパターンは{nagato.BonFestivalCount - nagato.GoldfishScoopingCount}回が該当する");

}

}


nagato.Dialogue("市民プールには今のところ毎回行っている");


if (wentToPartTime)

{

nagato.Dialogue($"アルバイトをおこなったのは{nagato.PartTimeJobCount - 1}回であるが、アルバイトの内容は六つに分岐する");


StringBuilder sentenceBuilder = new StringBuilder();

haruhi.PartTimeJobList.ForEach(job =>

{

if (sentenceBuilder.Length > 0)

{

sentenceBuilder.Append("、");

}


sentenceBuilder.Append(job);

});


if (haruhi.PartTimeJobList.Count < 6)

{

sentenceBuilder.Append("以外では");


PartTimeJobList.ForEach(job =>

{

if (!haruhi.PartTimeJobList.Contains(job))

{

sentenceBuilder.Append("、");

sentenceBuilder.Append(job);

}

});

}


sentenceBuilder.Append("があり、");


nagato.Dialogue(sentenceBuilder.ToString());


if (wentToBaloonVending)

{

nagato.Dialogue($"そのうち風船配りは{nagato.BaloonVendingCount - 1}回おこない、");

}


nagato.Dialogue($"二種類以上が重複したパターンは{nagato.TwoOrMorePartTimeJobsCount}回");

}


kyon.Monologue("まったくもって……。");

kyon.Monologue("またアホな話を聞いてしまったな。");

nagato.Monologue($"ループが発覚した。{nagato.RecognitionCount}回目。");

}


if (haruhi.MakeDecision(ButThatOnlyGodKnows))

{

haruhi.Dialogue("いないのかしら");

kyon.Dialogue("何がだ");

haruhi.Dialogue("火星人");


if (isLoopRecognized)

{

kyon.Dialogue("何がしたいんだろうな、こいつは");

koizumi.Dialogue("試しにこうしてみてはどうです?背後から突然抱きしめて、耳元でアイラブユーとでも囁くんです");

kyon.Dialogue("拒否権を発動するぜ。パス一だ");

koizumi.Dialogue("では、僕がやってみましょうか");

kyon.Monologue("この時俺がどんな顔をしていたのか、自分では見るすべがなかった。");

kyon.Monologue("だが、古泉には見えたようで、");

koizumi.Dialogue("ほんのライトなジョークですよ");

}


nagato.Monologue("天体観測を行った。");

}


if (haruhi.MakeDecision(ButThatOnlyGodKnows))

{

haruhi.Dialogue("バッティングセンターに行きましょうよ");

nagato.Monologue("バッティングセンターに行った。");

}


if (haruhi.MakeDecision(ButThatOnlyGodKnows))

{

kyon.Monologue("本物の花火大会にも行った。");

nagato.Monologue("花火大会に行った。");

}


if (haruhi.MakeDecision(ButThatOnlyGodKnows))

{

kyon.Monologue("また別の日は県境でやってるハゼ釣り大会にも飛び入り参加させられた。");

nagato.Monologue("ハゼ釣り大会に行った。");

}


haruhi.Dialogue("うーん。こんなんでよかったのかしら");

haruhi.Dialogue("まあいいわ。この夏はいっぱい色んな事ができたわよね");

haruhi.Dialogue("また明後日、部室で会いましょう");


if (isLoopRecognized)

{

kyon.Monologue("その時だ。まったくの突然、唐突、突如として忽然と―");

kyon.Monologue("アレが来た。");

kyon.Monologue("今までにない強烈な既視感。");

kyon.Monologue("帰らせてはダメなんだ。それでは変化しない。");

}


Thread.Sleep(waitTime);


kyon.ShouldDoHomework = isPredeterminedFinalSequence;


if (kyon.ShouldDoHomework)

{

kyon.Monologue("考えているヒマはない。何か言え。ダメもとで言っちまえ。");

kyon.Dialogue("俺の課題はまだ終わってねえ!");

kyon.Dialogue("朝比奈さんも来てください");

kyon.Dialogue("俺ん家でやりましょう");

kyon.Dialogue("長門と古泉、できてるところまで俺に写させろ");

haruhi.Dialogue("待ちなさいよ!");

haruhi.Dialogue("あたしも行くからねっ!");

}


haruhi.ShouldLoopAgain = !kyon.ShouldDoHomework;


if (haruhi.ShouldLoopAgain && nagato.RecognizeTheLoop())

{

nagato.Monologue("……ループからの脱出に失敗。");

}

}

}


public class Haruhi : OmnipotentBrigader

{

private readonly Random mind = new Random();


public Haruhi()

{

this.name = "涼宮ハルヒ";

this.PartTimeJobList = new List<string>();

}


public bool ShouldLoopAgain { get; set; }


public List<string> PartTimeJobList { get; set; }


public bool MakeDecision(int butThatOnlyGodKnows)

{

return this.MakeDecision(null, null, butThatOnlyGodKnows, true);

}


public bool MakeDecision(int? currentCount, int? predeterminedConstant, int butThatOnlyGodKnows, bool shouldDoOnFinalSequence)

{

return this.MakeDecision(currentCount, predeterminedConstant, null, null, butThatOnlyGodKnows, shouldDoOnFinalSequence);

}


public bool MakeDecision(int? currentCount, int? predeterminedConstant, int? currentBaseEventCount, int? secondPredeterminedConstant, int butThatOnlyGodKnows, bool shouldDoOnFinalSequence)

{

if (this.LoopCount == butThatOnlyGodKnows)

{

return shouldDoOnFinalSequence;

}


double probabilityBase = secondPredeterminedConstant ?? butThatOnlyGodKnows;

double baseDecision = this.mind.Next((int)probabilityBase) / probabilityBase;

return predeterminedConstant == null

? baseDecision < 0.5

: ((predeterminedConstant - currentCount) == (secondPredeterminedConstant != null

? (secondPredeterminedConstant + 1 - currentBaseEventCount) : (butThatOnlyGodKnows - this.LoopCount))

|| (baseDecision < predeterminedConstant / probabilityBase && currentCount < predeterminedConstant));

}


public string SelectFirstPartTimeJob(bool isFirstTime)

{

switch (this.mind.Next(isFirstTime ? 5 : 6))

{

case 0:

return "荷物運び";

case 1:

return "レジ打ち";

case 2:

return "ビラ配り";

case 3:

return "電話番";

case 4:

return "モデル撮影会";

default:

return null;

}

}


public string SelectSecondOrMorePartTimeJob(int predeterminedBaloonVendingCount, int predeterminedPartTimeJobCount, int butThatOnlyGodKnows)

{

string partTime;


do

{

partTime = this.SelectFirstPartTimeJob(false)

?? (this.MakeDecision(this.BaloonVendingCount, predeterminedBaloonVendingCount, this.PartTimeJobCount, predeterminedPartTimeJobCount, butThatOnlyGodKnows, false)

? "風船配り"

: string.Empty);

}

while (string.IsNullOrEmpty(partTime) || this.PartTimeJobList.Contains(partTime));


return partTime;

}

}


public class Nagato : OmnipotentBrigader

{

public Nagato()

{

this.name = "長門有希";

}


public int RecognitionCount { get; set; }


public override void Monologue(string str)

{

Console.WriteLine($"YUKI.N>{str}");

}


public bool RecognizeTheLoop()

{

return this.LoopCount > 1;

}

}


public class Kyon : Brigader

{

public Kyon()

{

this.name = "キョン";

}


public bool ShouldDoHomework { get; set; }

}


public class Koizumi : Brigader

{

public Koizumi()

{

this.name = "古泉一樹";

}

}


public class Mikuru : Brigader

{

public Mikuru()

{

this.name = "朝比奈みくる";

}

}


public abstract class Brigader

{

private readonly Random someReason = new Random();


protected string name;


public double RecognitionProbability { get; set; }


public bool RecognizeTheLoop(int currentCount, int predeterminedConstant, int countToldByNagato, int butThatOnlyGodKnows, bool isFinalSequence)

{

double mightHaveSomeReason = this.someReason.Next(butThatOnlyGodKnows) / (double)butThatOnlyGodKnows;

return isFinalSequence

|| (predeterminedConstant - currentCount) == (butThatOnlyGodKnows - countToldByNagato)

|| (mightHaveSomeReason < this.RecognitionProbability && currentCount < predeterminedConstant);

}


public virtual void Monologue(string str)

{

Console.WriteLine(str);

}


public void Dialogue(string str)

{

Console.WriteLine($"{this.name}「{str}」");

}

}


public abstract class OmnipotentBrigader : Brigader

{

public int LoopCount { get; set; }


public int PoolCount { get; set; }


public int BonFestivalCount { get; set; }


public int GoldfishScoopingCount { get; set; }


public int PartTimeJobCount { get; set; }


public int BaloonVendingCount { get; set; }


public int TwoOrMorePartTimeJobsCount { get; set; }

}

}

  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

シン・エンドレスエイト The Pioneer @The_Pioneer

★で称える

この小説が面白かったら★をつけてください。おすすめレビューも書けます。

カクヨムを、もっと楽しもう

この小説のおすすめレビューを見る

この小説のタグ