// Set up Animations var chain = new MarkovChain(1); chain.Add(new[] { "Sitting" }, "Sitting", 50); chain.Add(new[] { "Sitting" }, "Grooming", 20); chain.Add(new[] { "Sitting" }, "Sleeping", 20); chain.Add(new[] { "Sitting" }, "Playing", 10); chain.Add(new[] { "Playing" }, "Sitting", 100); chain.Add(new[] { "Sleeping" }, "Sleeping", 60); chain.Add(new[] { "Sleeping" }, "Sitting", 40); chain.Add(new[] { "Grooming" }, "Grooming", 20); chain.Add(new[] { "Grooming" }, "Sitting", 80); // Set up Images var framesPerState = new Dictionary { { "Sitting", 5 }, { "Playing", 12 }, { "Sleeping", 3 }, { "Grooming", 8 }, }; var cancelSource = new CancellationTokenSource(); var cancel = cancelSource.Token; // Allow for 1 minute, by default. // You can change this to only cancel when the user requests, etc. cancelSource.CancelAfter(TimeSpan.FromMinutes(1)); foreach (var state in chain.Chain(new[] { "Sitting" })) { if (cancel.IsCancellationRequested) { break; } var frames = framesPerState[state]; for (var i = 0; i < frames; i++) { Console.WriteLine($"Show Frame: {state}-{i}.png"); // You can do this any number of ways, depending on your rendering platform. } Thread.Sleep(TimeSpan.FromSeconds(1.0 / 30)); }