1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ティアキンのモドレコをC#のStackを使って超簡易的に実装してみる

Last updated at Posted at 2025-08-03

プログラマの性

2023年に発売された『ゼルダの伝説 ティアーズ オブ ザ キングダム』を皆さんご存知でしょうか?

大人気のティアキンですが、ある画期的なシステムが話題となりました。そう、"モドレコ"というシステムです。なんとフィールド上のあらゆるオブジェクトの巻き戻しが可能なんです。しかも、動かせるものほとんどが対象で😳

そのシステムを見たとき、私はこう思ったわけです。
これどうやってプログラミングしてるの?
プログラマの性ですかね。

2年前のゲームなので旬は過ぎ去りましたが、超簡易版モドレコをC#のStackを使って実装してみようと思います。

Stackとは?

同じ型のインスタンスの可変サイズの先入れ先出し(Last In, First Out)のコレクションのことです。

実装例で見てもらった方が早いと思います。
Pushで値を追加して、PeekまたはPopで一番上の値を参照します。
Peekは値を残したままで、Popを使うと参照した値は消えます。

// Stackの初期化
var numbers = new Stack<int>();

// Pushを使って1~5を追加
Enumerable.Range(1, 5)
    .ToList()
    .ForEach(numbers.Push);

// すべての要素をPeek
Console.WriteLine("Peek");
Enumerable.Repeat(0, 5)
    .Select(_ => numbers.Peek())
    .ToList()
    .ForEach(Console.WriteLine);

Console.WriteLine("残っている数字");
foreach (var num in numbers)
{
    Console.WriteLine(num);
}

// すべての要素をPop
Console.WriteLine("Pop");
Enumerable.Range(0, numbers.Count)
    .Select(_ => numbers.Pop())
    .ToList()
    .ForEach(Console.WriteLine);

Console.WriteLine("残っている数字");
foreach (var num in numbers)
{
    Console.WriteLine(num);
}

出力結果

Peek
5
5
5
5
5
残っている数字
5
4
3
2
1
Pop
5
4
3
2
1
残っている数字

今回簡易版モドレコ実装で使うのはPopです。

いざ実装!

コード

using System;
using System.Collections.Generic;
using System.Threading;

class Program
{
    static void Main()
    {
        // Stackで位置の履歴を記録
        var history = new Stack<int>();
        // 現在の位置
        int position = 0;
        // 巻き戻しが実行中か
        bool isRewinding = false;

        Console.WriteLine("Enterでモドレコ(逆再生)を開始します。Escで終了");

        while (true)
        {
            if (Console.KeyAvailable)
            {
                var key = Console.ReadKey(true).Key;

                if (key == ConsoleKey.Enter)
                {
                    // Enterキー押下で巻き戻しを実行する
                    isRewinding = true;
                }
                else if (key == ConsoleKey.Escape)
                {
                    // Escでアプリ終了
                    break;
                }
            }

            if (isRewinding)
            {
                // 巻き戻し実行中の処理
                if (history.Count > 0)
                {
                    // 過去の位置に戻して位置を描画
                    position = history.Pop();
                    Draw(position);
                }
                else
                {
                    // Stackがない場合は巻き戻しを終了して通常の方向へ
                    isRewinding = false;
                    Console.WriteLine("巻き戻し終了!");
                }
            }
            else
            {
                // 巻き戻し実行中は現在位置を記録して前身させる
                history.Push(position);
                position++;
                Draw(position);
            }

            Thread.Sleep(300); // 動作間隔
        }
    }

    static void Draw(int pos)
    {
        Console.Clear();
        Console.WriteLine("位置: " + pos);
        Console.WriteLine(new string(' ', pos) + "●"); // ●が進んだり戻ったり
    }
}

Stack型のhistoryに位置を記録させておいて、巻き戻し中か否かで進む方向を制御します。

画面表示

画面収録 2025-08-03 20.03.39.gif

超簡易ですが無事動きましたね🎉

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?