root/lang/csharp/DominionEngine/DominionEngine.CardInfo/Unit/Worth.cs @ 37574

Revision 37574, 6.0 kB (checked in by isaisstillalive, 3 years ago)
  • Worthの比較メソッドを実装
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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}
Note: See TracBrowser for help on using the browser.