Unityでボードゲームでよく使われるデザインパターン

ボードゲームは、Unityで作成されるゲームの一種であり、いくつかのデザインパターンがよく使用されます。以下は、Unityでボードゲームでよく使用されるデザインパターンのいくつかの例です。

1. Stateパターン

Stateパターンは、オブジェクトの状態に応じて振る舞いを変更するためのパターンです。ボードゲームでは、プレイヤーのターンやゲームの状態によって異なる振る舞いが必要になることがあります。以下は、Stateパターンの例です。

public abstract class GameState
{
    protected Game game;

    public GameState(Game game)
    {
        this.game = game;
    }

    public abstract void Start();
    public abstract void Update();
    public abstract void End();
}

public class SetupState : GameState
{
    public SetupState(Game game) : base(game) { }

    public override void Start()
    {
        Debug.Log("Setting up game");
    }

    public override void Update()
    {
        // do nothing
    }

    public override void End()
    {
        game.SetState(new PlayState(game));
    }
}

public class PlayState : GameState
{
    public PlayState(Game game) : base(game) { }

    public override void Start()
    {
        Debug.Log("Starting game");
    }

    public override void Update()
    {
        // do game logic
    }

    public override void End()
    {
        game.SetState(new EndState(game));
    }
}

public class EndState : GameState
{
    public EndState(Game game) : base(game) { }

    public override void Start()
    {
        Debug.Log("Ending game");
    }

    public override void Update()
    {
        // do nothing
    }

    public override void End()
    {
        // do nothing
    }
}

public class Game : MonoBehaviour
{
    private GameState currentState;

    private void Start()
    {
        SetState(new SetupState(this));
    }

    private void Update()
    {
        currentState.Update();
    }

    public void SetState(GameState state)
    {
        currentState = state;
        currentState.Start();
    }

    public void EndGame()
    {
        currentState.End();
    }
}

この例では、GameStateクラスがState、SetupStateクラスとPlayStateクラスとEndStateクラスがConcrete State、GameクラスがContextとして実装されています。GameStateクラスには、Start()Update()End()メソッドがあります。SetupStateクラスとPlayStateクラスとEndStateクラスは、それぞれのStateに応じた振る舞いを実装します。Gameクラスには、currentStateフィールドとSetState()メソッドがあります。Update()メソッドは、現在のStateに応じた処理を実行するために使用されます。

2. Commandパターン

Commandパターンは、操作をオブジェクト化し、実行時に操作を実行するためのパターンです。ボードゲームでは、プレイヤーの行動やゲームの進行に応じて、コマンドを実行する必要があることがあります。以下は、Commandパターンの例です。

public interface ICommand
{
    void Execute();
}

public class MoveCommand : ICommand
{
    private GameObject piece;
    private Vector3 destination;

    public MoveCommand(GameObject piece, Vector3 destination)
    {
        this.piece = piece;
        this.destination = destination;
    }

    public void Execute()
    {
        piece.transform.position = destination;
    }
}

public class UndoCommand : ICommand
{
    private CommandManager commandManager;

    public UndoCommand(CommandManager commandManager)
    {
        this.commandManager = commandManager;
    }

    public void Execute()
    {
        commandManager.Undo();
    }
}

public class CommandManager
{
    private Stack<ICommand> commands;

    public CommandManager()
    {
        commands = new Stack<ICommand>();
    }

    public void ExecuteCommand(ICommand command)
    {
        command.Execute();
        commands.Push(command);
    }

    public void Undo()
    {
        if (commands.Count > 0)
        {
            ICommand command = commands.Pop();
            command.Undo();
        }
    }
}

この例では、ICommandインターフェースがCommand、MoveCommandクラスとUndoCommandクラスがConcrete Command、CommandManagerクラスがInvokerとして実装されています。ICommandインターフェースには、Execute()メソッドがあります。MoveCommandクラスとUndoCommandクラスは、それぞれのCommandに応じた操作を実装します。CommandManagerクラスには、commandsスタックとExecuteCommand()メソッドとUndo()メソッドがあります。ExecuteCommand()メソッドは、コマンドを実行し、スタックにコマンドをプッシュします。Undo()メソッドは、スタックからコマンドをポップし、Undo()メソッドを呼び出します。

3. Observerパターン

Observerパターンは、オブジェクトの状態変化を監視し、状態が変化した場合に通知するためのパターンです。ボードゲームでは、プレイヤーの行動やゲームの進行に応じて、他のオブジェクトの状態を変更する必要があることがあります。以下は、Observerパターンの例です。

public interface IObserver
{
    void Update();
}

public class Player : MonoBehaviour, IObserver
{
    private int score;

    public void Update()
    {
        score++;
        Debug.Log("Score: " + score);
    }
}

public class GameManager : MonoBehaviour
{
    private List<IObserver> observers;

    private void Start()
    {
        observers = new List<IObserver>();
        Player player1 = Instantiate(playerPrefab).GetComponent<Player>();
        Player player2 = Instantiate(playerPrefab).GetComponent<Player>();
}

この例では、`IObserver`インターフェースがObserver、`Player`クラスがConcrete Observer、`GameManager`クラスがSubjectとして実装されています。`IObserver`インターフェースには、`Update()`メソッドがあります。`Player`クラスは、スコアを管理するオブジェクトです。`GameManager`クラスには、`observers`リストと`Update()`メソッドがあります。`Update()`メソッドは、ゲームの進行に応じて、リスト内のObserverに通知します。 以上が、ボードゲームでよく使われるデザインパターンの例です。これらのデザインパターンをうまく活用することで、ボードゲームをスマートに実装することができます。