| 1 | using System;
|
|---|
| 2 | using System.Collections.Generic;
|
|---|
| 3 | using System.Linq;
|
|---|
| 4 | using System.Text;
|
|---|
| 5 |
|
|---|
| 6 | namespace DominionEngine.CardInfo
|
|---|
| 7 | {
|
|---|
| 8 | /// <summary>
|
|---|
| 9 | /// 価値
|
|---|
| 10 | /// </summary>
|
|---|
| 11 | public class Worth: IEquatable<Worth>
|
|---|
| 12 | {
|
|---|
| 13 | #region ビルダ
|
|---|
| 14 |
|
|---|
| 15 | /// <summary>
|
|---|
| 16 | /// 無価値
|
|---|
| 17 | /// </summary>
|
|---|
| 18 | public static readonly Worth None = new Worth(new Dictionary<Type, int>());
|
|---|
| 19 |
|
|---|
| 20 | /// <summary>
|
|---|
| 21 | /// 新たな価値
|
|---|
| 22 | /// </summary>
|
|---|
| 23 | /// <typeparam name="T">価値の種類</typeparam>
|
|---|
| 24 | /// <param name="value">個数</param>
|
|---|
| 25 | /// <returns></returns>
|
|---|
| 26 | public static Worth Create<T>(int value)
|
|---|
| 27 | where T : Unit
|
|---|
| 28 | {
|
|---|
| 29 | Dictionary<Type, int> items = new Dictionary<Type, int>();
|
|---|
| 30 | items.Add(typeof(T), value);
|
|---|
| 31 | return new Worth(items);
|
|---|
| 32 | }
|
|---|
| 33 |
|
|---|
| 34 | /// <summary>
|
|---|
| 35 | /// コイン
|
|---|
| 36 | /// </summary>
|
|---|
| 37 | /// <param name="value">個数</param>
|
|---|
| 38 | /// <returns>価値</returns>
|
|---|
| 39 | public static Worth Coin(int value) { return Create<CoinUnit>(value); }
|
|---|
| 40 |
|
|---|
| 41 | #endregion
|
|---|
| 42 |
|
|---|
| 43 | #region フィールドとコンストラクタ
|
|---|
| 44 |
|
|---|
| 45 | /// <summary>
|
|---|
| 46 | /// 価値ごとの個数
|
|---|
| 47 | /// </summary>
|
|---|
| 48 | internal Dictionary<Type, int> items;
|
|---|
| 49 |
|
|---|
| 50 | /// <summary>
|
|---|
| 51 | /// 価値を作成
|
|---|
| 52 | /// </summary>
|
|---|
| 53 | internal Worth(Dictionary<Type, int> items) {
|
|---|
| 54 | this.items = items;
|
|---|
| 55 |
|
|---|
| 56 | hashCode = 0;
|
|---|
| 57 | foreach (var item in items)
|
|---|
| 58 | {
|
|---|
| 59 | hashCode += item.Key.GetHashCode() * item.Value;
|
|---|
| 60 | }
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | #endregion
|
|---|
| 64 |
|
|---|
| 65 | /// <summary>
|
|---|
| 66 | /// コストが支払えるかどうか
|
|---|
| 67 | /// </summary>
|
|---|
| 68 | /// <param name="cost">対象のコスト</param>
|
|---|
| 69 | /// <returns></returns>
|
|---|
| 70 | public bool IsAfford(Worth cost)
|
|---|
| 71 | {
|
|---|
| 72 | foreach (var item in cost.items)
|
|---|
| 73 | {
|
|---|
| 74 | if (this[item.Key] < item.Value) return false;
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | return true;
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | /// <summary>
|
|---|
| 81 | /// ToString
|
|---|
| 82 | /// </summary>
|
|---|
| 83 | /// <returns></returns>
|
|---|
| 84 | public override string ToString()
|
|---|
| 85 | {
|
|---|
| 86 | return String.Format("{0}C", CoinValue);
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | /// <summary>
|
|---|
| 90 | /// 指定したカードのコストより現在の価値だけ大きい新しい価値
|
|---|
| 91 | /// </summary>
|
|---|
| 92 | /// <param name="card"></param>
|
|---|
| 93 | /// <returns></returns>
|
|---|
| 94 | public Worth MoreThan(ICardInfo card)
|
|---|
| 95 | {
|
|---|
| 96 | return card.Cost + this;
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | #region 単位ごと価値
|
|---|
| 100 |
|
|---|
| 101 | /// <summary>
|
|---|
| 102 | /// 単位ごとの価値
|
|---|
| 103 | /// </summary>
|
|---|
| 104 | /// <param name="key"></param>
|
|---|
| 105 | /// <returns></returns>
|
|---|
| 106 | internal int this[Type key]
|
|---|
| 107 | {
|
|---|
| 108 | get { return items.ContainsKey(key) ? items[key] : 0; }
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | /// <summary>
|
|---|
| 112 | /// 単位ごとの価値
|
|---|
| 113 | /// </summary>
|
|---|
| 114 | /// <typeparam name="T">価値の単位</typeparam>
|
|---|
| 115 | /// <returns></returns>
|
|---|
| 116 | public int Value<T>()
|
|---|
| 117 | where T : Unit
|
|---|
| 118 | {
|
|---|
| 119 | return this[typeof(T)];
|
|---|
| 120 | }
|
|---|
| 121 |
|
|---|
| 122 | /// <summary>
|
|---|
| 123 | /// コイン価値
|
|---|
| 124 | /// </summary>
|
|---|
| 125 | /// <returns></returns>
|
|---|
| 126 | public int CoinValue { get { return Value<CoinUnit>(); } }
|
|---|
| 127 |
|
|---|
| 128 | #endregion
|
|---|
| 129 |
|
|---|
| 130 | #region 算術演算子
|
|---|
| 131 |
|
|---|
| 132 | public static Worth operator +(Worth cost1, Worth cost2)
|
|---|
| 133 | {
|
|---|
| 134 | Dictionary<Type, int> items = new Dictionary<Type, int>(cost1.items);
|
|---|
| 135 |
|
|---|
| 136 | foreach (var item in cost2.items)
|
|---|
| 137 | {
|
|---|
| 138 | if (!items.ContainsKey(item.Key)) items[item.Key] = 0;
|
|---|
| 139 | items[item.Key] += item.Value;
|
|---|
| 140 | }
|
|---|
| 141 | return new Worth(items);
|
|---|
| 142 | }
|
|---|
| 143 |
|
|---|
| 144 | public static Worth operator -(Worth cost1, Worth cost2)
|
|---|
| 145 | {
|
|---|
| 146 | Dictionary<Type, int> items = new Dictionary<Type, int>(cost1.items);
|
|---|
| 147 |
|
|---|
| 148 | foreach (var item in cost2.items)
|
|---|
| 149 | {
|
|---|
| 150 | if (!items.ContainsKey(item.Key)) items[item.Key] = 0;
|
|---|
| 151 | items[item.Key] -= item.Value;
|
|---|
| 152 | }
|
|---|
| 153 | return new Worth(items);
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | #endregion
|
|---|
| 157 |
|
|---|
| 158 | #region 等価比較
|
|---|
| 159 |
|
|---|
| 160 | public override bool Equals(object obj)
|
|---|
| 161 | {
|
|---|
| 162 | if (obj is Worth) return Equals((Worth)obj);
|
|---|
| 163 | return false;
|
|---|
| 164 | }
|
|---|
| 165 |
|
|---|
| 166 | public bool Equals(Worth other)
|
|---|
| 167 | {
|
|---|
| 168 | return hashCode == other.hashCode;
|
|---|
| 169 | }
|
|---|
| 170 |
|
|---|
| 171 | public static bool operator ==(Worth x, Worth y)
|
|---|
| 172 | {
|
|---|
| 173 | // 同一のオブジェクトなら常に等価
|
|---|
| 174 | if (System.Object.ReferenceEquals(x, y)) return true;
|
|---|
| 175 | // それ以外なら内容を比較
|
|---|
| 176 | return x.Equals(y);
|
|---|
| 177 | }
|
|---|
| 178 |
|
|---|
| 179 | public static bool operator !=(Worth a, Worth b)
|
|---|
| 180 | {
|
|---|
| 181 | return !(a == b);
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 | internal int hashCode;
|
|---|
| 185 |
|
|---|
| 186 | public override int GetHashCode()
|
|---|
| 187 | {
|
|---|
| 188 | return hashCode;
|
|---|
| 189 | }
|
|---|
| 190 |
|
|---|
| 191 | #endregion
|
|---|
| 192 |
|
|---|
| 193 | #region 価値の単位
|
|---|
| 194 |
|
|---|
| 195 | /// <summary>
|
|---|
| 196 | /// 価値の単位
|
|---|
| 197 | /// </summary>
|
|---|
| 198 | public interface Unit { };
|
|---|
| 199 |
|
|---|
| 200 | /// <summary>
|
|---|
| 201 | /// コイン
|
|---|
| 202 | /// </summary>
|
|---|
| 203 | public class CoinUnit : Unit { }
|
|---|
| 204 |
|
|---|
| 205 | #endregion
|
|---|
| 206 |
|
|---|
| 207 | /// <summary>
|
|---|
| 208 | /// デフォルトの比較クラス
|
|---|
| 209 | /// </summary>
|
|---|
| 210 | public class DefaultComparer : Comparer<Worth>
|
|---|
| 211 | {
|
|---|
| 212 | public override int Compare(Worth x, Worth y)
|
|---|
| 213 | {
|
|---|
| 214 | // コインが低い順
|
|---|
| 215 | if (x.CoinValue != y.CoinValue) return x.CoinValue.CompareTo(y.CoinValue);
|
|---|
| 216 |
|
|---|
| 217 | return 0;
|
|---|
| 218 | }
|
|---|
| 219 | }
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | public static class WorthExtension
|
|---|
| 223 | {
|
|---|
| 224 | public static Worth Coin(this Int32 value)
|
|---|
| 225 | {
|
|---|
| 226 | return Worth.Coin(value);
|
|---|
| 227 | }
|
|---|
| 228 | }
|
|---|
| 229 | }
|
|---|