キヨシチェックをC#とReavtiveExtentionsで書いてみた。


Rxの勉強で例のキヨシチェックを書いてみた。
他の言語はこんな感じみたいです。
ColdとHotの違いがちょっとだけわかった。
もっとうまく書ける気がする(´・ω・`)

追記:
コメントでBuffer使うと良いってアドバイス貰いました。
使ってみたらけっこう良い感じに書けました。

変更後

using System;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;

namespace Zundoko
{
    internal class Program
    {
        private const string Zun = "ズン";
        private const string Doko = "ドコ";
        private const string Kiyoshi = "キ・ヨ・シ! ((└(:3」┌)┘))";

        private static void Main(string[] args)
        {
            var rm = new Random();
            Observable
                .Interval(TimeSpan.Zero, CurrentThreadScheduler.Instance)
                .Select((x, y) => rm.Next()%2 == 0 ? Zun : Doko)
                .Do(x => Console.Write($"{x} "))
                .Buffer(5, 1)
                .Where(x => x.SequenceEqual(new[] {Zun, Zun, Zun, Zun, Doko}))
                .Subscribe(x =>
                {
                    Console.WriteLine(Kiyoshi);
                    Console.Read();
                    Environment.Exit(0);
                });
        }
    }
}

変更前

using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading;
using Reactive.Bindings.Extensions;

namespace Zundoko
{
    internal class Program
    {
        private const string Zun = "ズン";
        private const string Doko = "ドコ";
        private const string Kiyoshi = "キ・ヨ・シ! ((└(:3」┌)┘))";

        private static void Main(string[] args)
        {
            var ms = new ManualResetEventSlim();
            var rm = new Random();
            var disposable = new CompositeDisposable();

            var zundokoRiver = Observable
                .Interval(TimeSpan.Zero)
                .Select((x, y) => rm.Next()%2 == 0 ? Zun : Doko)
                .Publish()
                ;

            zundokoRiver
                .Do(x => Console.Write($"{x} "))
                .Zip(
                    zundokoRiver.Skip(1)
                    , zundokoRiver.Skip(2)
                    , zundokoRiver.Skip(3)
                    , zundokoRiver.Skip(4)
                    , (one, two, three, four, five) => new {one, two, three, four, five})
                .Where(x => x.one == Zun && x.two == Zun && x.three == Zun && x.four == Zun && x.five == Doko)
                .Subscribe(x =>
                {
                    Console.WriteLine(Kiyoshi);
                    disposable.Dispose();
                    ms.Set();
                }).AddTo(disposable);

            zundokoRiver.Connect();
            ms.Reset();
            ms.Wait();
            Console.Read();
        }
    }
}