【趣味】【ゲーム開発】共通状態と固有状態を混在させた、ステート管理用スクリプト
プログラムには「ステートマシン」というデザインパターンがある。
(詳細はぐぐってほしい)
そのIDとしてEnum列挙体を使うことがしばしばある。
…が、一度定義したEnumは拡張できない。
なので、↓このようにint型にキャストするなどしないといけない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
// C# システム using System; public class Hello { // 車共通 public class Car { // 車共通状態 public enum State { Disable=-1, // 無効なステート Parking, // 駐車中 Drive, // 運転中 WaitLight, // 信号待ち中 Qty, // 状態数 } // 状態数 public virtual int stateQty { get { return GetID(State.Qty); } } // 状態列挙隊からID取得 public int GetID(State state) { return (int)state; } // 状態IDが共通固有問わず、有効か確認 public virtual bool IsStateID(int stateID) { return IsCommonStateID(stateID); } // 状態IDが共通状態か確認 public bool IsCommonStateID(int stateID) { return (GetID(State.Disable) < stateID && stateID < GetID(State.Qty)); } // 状態IDが固有状態か確認 public virtual bool IsUniqueStateID(int stateID) { return false; } // 状態IDから状態列挙隊取得 public State GetCommonState(int stateID) { return IsCommonStateID(stateID) ? (State)stateID : State.Disable; } // 状態ID public int _state; } // 救急車 public class Ambulance : Car { // 救急車状態 public enum State { Disable=-1, // 無効なステート FirstAid, // 応急処置中 Carrying, // 搬送中 Qty, // 状態数 } // 状態数 public override int stateQty { get { return GetID(Car.State.Qty) + GetID(State.Qty); } } // 状態列挙隊からID取得 public int GetID(State state) { return GetID(Car.State.Qty) + (int)state; } // 状態IDが共通固有問わず、有効か確認 public override bool IsStateID(int stateID) { return (GetID(Car.State.Disable) < stateID && stateID < GetID(State.Qty)); } // 状態IDが有効か確認 public override bool IsUniqueStateID(int stateID) { return (GetID(State.Disable) < stateID && stateID < GetID(State.Qty)); } // 状態IDから状態列挙隊取得 public State GetUniqueState(int stateID) { return IsUniqueStateID(stateID) ? (State)(stateID - GetID(Car.State.Qty)) : State.Disable; } } // キャンピングカー public class CampingCar : Car { // キャンピングカー状態 public enum State { Disable=-1, // 無効なステート Camping, // キャンプ中 Qty, // 状態数 } // 状態数 public override int stateQty { get { return GetID(Car.State.Qty) + GetID(State.Qty); } } // 状態列挙隊からID取得 public int GetID(State state) { return GetID(Car.State.Qty) + (int)state; } // 状態IDが共通固有問わず、有効か確認 public override bool IsStateID(int stateID) { return (GetID(Car.State.Disable) < stateID && stateID < GetID(State.Qty)); } // 状態IDが有効か確認 public override bool IsUniqueStateID(int stateID) { return (GetID(State.Disable) < stateID && stateID < GetID(State.Qty)); } // 状態IDから状態列挙隊取得 public State GetUniqueState(int stateID) { return IsUniqueStateID(stateID) ? (State)(stateID - GetID(Car.State.Qty)) : State.Disable; } } // メイン関数 public static void Main() { Console.WriteLine("救急車の状態表示"); Ambulance ambulance = new Ambulance(); for (int i = 0; ambulance.IsStateID(i); i++) { if (ambulance.IsCommonStateID(i)) { Console.WriteLine("" + ambulance.GetCommonState(i)); } else { Console.WriteLine("" + ambulance.GetUniqueState(i)); } } Console.WriteLine(""); Console.WriteLine("キャンピングカーの状態表示"); CampingCar campingCar = new CampingCar(); for (int i = 0; campingCar.IsStateID(i); i++) { if (campingCar.IsCommonStateID(i)) { Console.WriteLine("" + campingCar.GetCommonState(i)); } else { Console.WriteLine("" + campingCar.GetUniqueState(i)); } } } } |
↓実行結果
救急車の状態表示
Parking
Drive
WaitLight
FirstAid
Carryingキャンピングカーの状態表示
Parking
Drive
WaitLight
Camping
…あとはそれぞれのクラスに様々な実装を加えるといい。