root/lang/csharp/DominionEngine/DominionEngine.CardInfo/DDL/AnyPlayer.cs @ 37529

Revision 37529, 14.1 kB (checked in by isaisstillalive, 4 years ago)
  • よく利用される「サプライから条件で選んで取得」をメソッド化
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace DominionEngine.CardInfo
7{
8    public class AnyPlayer : IAnyPlayer
9    {
10        #region コンストラクタとメタ情報
11
12        static AnyPlayer()
13        {
14            ClearEvent();
15        }
16
17        /// <summary>
18        /// プレイヤー番号
19        /// </summary>
20        public virtual int Player { get; internal set; }
21
22        /// <summary>
23        /// コンストラクタ
24        /// </summary>
25        /// <param name="player">プレイヤー番号</param>
26        public AnyPlayer(int player)
27        {
28            Player = player;
29        }
30
31        #endregion
32
33        #region イベントの初期化
34
35        /// <summary>
36        /// イベントをリセット
37        /// </summary>
38        public static void ClearEvent()
39        {
40            CardListGetting = (sender, e) => { };
41            Drawing = (sender, e) => { };
42            Choosing = (sender, e) => { };
43        }
44
45        #endregion
46
47        #region 基本情報
48
49        #region Hand
50
51        /// <summary>
52        /// 手札
53        /// </summary>
54        public CardList Hand
55        {
56            get
57            {
58                CardListGettingEventArgs args = new CardListGettingEventArgs(CardPosition.Hand(Player));
59                CardListGetting(this, args);
60                if (args.Result == null) return new CardList();
61                else return new CardList(args.Result);
62            }
63        }
64
65        public static event EventHandler<CardListGettingEventArgs> CardListGetting;
66
67        public class CardListGettingEventArgs : EventArgs
68        {
69            public CardPosition Position { get; internal set; }
70            public IList<Card> Result { get; set; }
71
72            public CardListGettingEventArgs(CardPosition position)
73            {
74                Position = position;
75            }
76        }
77
78        #endregion
79
80        #region Deck
81
82        /// <summary>
83        /// デッキ
84        /// </summary>
85        public CardList Deck { get; internal set; }
86
87        #endregion
88
89        #endregion
90
91        #region Draw
92
93        /// <summary>
94        /// ドロー
95        /// </summary>
96        /// <param name="quantity">枚数</param>
97        public void Draw(int quantity)
98        {
99            if (quantity <= -1) throw new ArgumentException();
100            Drawing(this, new DrawingEventArgs(Player, quantity));
101        }
102
103        /// <summary>
104        /// ドローイベント
105        /// </summary>
106        public static event EventHandler<DrawingEventArgs> Drawing;
107
108        /// <summary>
109        /// ドローイベント引数
110        /// </summary>
111        public class DrawingEventArgs : EventArgs
112        {
113            public int Player { get; internal set; }
114            public int Quantity { get; internal set; }
115
116            public DrawingEventArgs(int player, int quantity)
117            {
118                Player = player;
119                Quantity = quantity;
120            }
121        }
122
123        #endregion
124
125        #region Choose
126
127        /// <summary>
128        /// カード選択
129        /// </summary>
130        /// <param name="from">選択元</param>
131        /// <param name="minQuantity">最小枚数</param>
132        /// <param name="maxQuantity">最大枚数</param>
133        /// <param name="filter">フィルタ</param>
134        /// <returns></returns>
135        public CardList Choose(CardPosition from, int minQuantity, int maxQuantity, Func<ICardInfo, bool> filter)
136        {
137            ChoosingEventArgs args = new ChoosingEventArgs(Player, from, minQuantity, maxQuantity, filter);
138            Choosing(this, args);
139
140            if (args.Result == null) args.Result = new List<Card>();
141
142            // 選択枚数が指定された範囲内でなければエラー
143            // ※限界枚数が指定された場合は最小枚数を無視する
144            int quantity = args.Result.Count;
145            if (quantity > maxQuantity || (!args.Force && quantity < minQuantity))
146                throw new ChooseQuantityException(quantity, minQuantity, maxQuantity);
147           
148            // CardPositionが異なるかフィルタ制限に引っかかればエラー
149            foreach (Card card in args.Result)
150            {
151                if (card.Position != from) throw new ChooseCardPositionException(card, from);
152                if (!filter(card.CardInfo)) throw new ChooseCardInfoException(card);
153            }
154
155            return new CardList(args.Result);
156        }
157
158        /// <summary>
159        /// カード選択
160        /// </summary>
161        /// <param name="from">選択元</param>
162        /// <param name="minQuantity">最小枚数</param>
163        /// <param name="maxQuantity">最大枚数</param>
164        /// <param name="filter">フィルタ</param>
165        /// <returns></returns>
166        public CardList Choose(CardPositionBuilder from, int minQuantity, int maxQuantity, Func<ICardInfo, bool> filter)
167        {
168            return Choose(from(Player), minQuantity, maxQuantity, filter);
169        }
170
171        /// <summary>
172        /// カード選択
173        /// </summary>
174        /// <param name="from">選択元</param>
175        /// <param name="quantity">枚数</param>
176        /// <param name="filter">フィルタ</param>
177        /// <returns></returns>
178        public CardList Choose(CardPosition from, int quantity, Func<ICardInfo, bool> filter)
179        {
180            return Choose(from, quantity, quantity, filter);
181        }
182
183        /// <summary>
184        /// カード選択
185        /// </summary>
186        /// <param name="from">選択元</param>
187        /// <param name="minQuantity">枚数</param>
188        /// <param name="filter">フィルタ</param>
189        /// <returns></returns>
190        public CardList Choose(CardPositionBuilder from, int quantity, Func<ICardInfo, bool> filter)
191        {
192            return Choose(from, quantity, quantity, filter);
193        }
194
195        /// <summary>
196        /// カードを1枚選択
197        /// </summary>
198        /// <param name="from">選択元</param>
199        /// <param name="filter">フィルタ</param>
200        /// <returns></returns>
201        public CardList Choose(CardPosition from, Func<ICardInfo, bool> filter)
202        {
203            return Choose(from, 1, filter);
204        }
205
206        /// <summary>
207        /// カードを1枚選択
208        /// </summary>
209        /// <param name="from">選択元</param>
210        /// <param name="filter">フィルタ</param>
211        /// <returns></returns>
212        public CardList Choose(CardPositionBuilder from, Func<ICardInfo, bool> filter)
213        {
214            return Choose(from, 1, filter);
215        }
216
217        /// <summary>
218        /// カード選択
219        /// </summary>
220        /// <param name="from">選択元</param>
221        /// <param name="minQuantity">最小枚数</param>
222        /// <param name="maxQuantity">最大枚数</param>
223        /// <returns></returns>
224        public CardList Choose(CardPosition from, int minQuantity, int maxQuantity)
225        {
226            return Choose(from, minQuantity, maxQuantity, cardinfo => true);
227        }
228
229        /// <summary>
230        /// カード選択
231        /// </summary>
232        /// <param name="from">選択元</param>
233        /// <param name="minQuantity">最小枚数</param>
234        /// <param name="maxQuantity">最大枚数</param>
235        /// <returns></returns>
236        public CardList Choose(CardPositionBuilder from, int minQuantity, int maxQuantity)
237        {
238            return Choose(from, minQuantity, maxQuantity, cardinfo => true);
239        }
240
241        /// <summary>
242        /// カード選択
243        /// </summary>
244        /// <param name="from">選択元</param>
245        /// <param name="quantity">枚数</param>
246        /// <returns></returns>
247        public CardList Choose(CardPosition from, int quantity)
248        {
249            return Choose(from, quantity, quantity);
250        }
251
252        /// <summary>
253        /// カード選択
254        /// </summary>
255        /// <param name="from">選択元</param>
256        /// <param name="quantity">枚数</param>
257        /// <returns></returns>
258        public CardList Choose(CardPositionBuilder from, int quantity)
259        {
260            return Choose(from, quantity, quantity);
261        }
262
263        /// <summary>
264        /// カードを1枚選択
265        /// </summary>
266        /// <param name="from">選択元</param>
267        /// <returns></returns>
268        public CardList Choose(CardPosition from)
269        {
270            return Choose(from, 1);
271        }
272
273        /// <summary>
274        /// カードを1枚選択
275        /// </summary>
276        /// <param name="from">選択元</param>
277        /// <returns></returns>
278        public CardList Choose(CardPositionBuilder from)
279        {
280            return Choose(from, 1);
281        }
282
283        /// <summary>
284        /// カード選択イベント
285        /// </summary>
286        public static event EventHandler<ChoosingEventArgs> Choosing;
287
288        /// <summary>
289        /// カード選択イベント引数
290        /// </summary>
291        public class ChoosingEventArgs : EventArgs
292        {
293            /// <summary>
294            /// プレイヤー番号
295            /// </summary>
296            public int Player { get; internal set; }
297
298            /// <summary>
299            /// 選択元
300            /// </summary>
301            public CardPosition From { get; internal set; }
302
303            /// <summary>
304            /// 最小枚数
305            /// </summary>
306            public int MinQuantity { get; internal set; }
307
308            /// <summary>
309            /// 最大枚数
310            /// </summary>
311            public int MaxQuantity { get; internal set; }
312
313            /// <summary>
314            /// フィルタ
315            /// </summary>
316            public Func<ICardInfo, bool> Filter { get; internal set; }
317
318            /// <summary>
319            /// 結果
320            /// </summary>
321            public IList<Card> Result { get; set; }
322
323            /// <summary>
324            /// 最小枚数に満たないが限界まで選択した
325            /// </summary>
326            public bool Force { get; set; }
327
328            public ChoosingEventArgs(int player, CardPosition from, int minQuantity, int maxQuantity, Func<ICardInfo, bool> filter)
329            {
330                Player = player;
331                From = from;
332                MinQuantity = minQuantity;
333                MaxQuantity = maxQuantity;
334                Filter = filter;
335                Force = false;
336            }
337        }
338
339        #region Exception
340
341        public class ChooseException : Exception
342        {
343        }
344
345        public class ChooseQuantityException : ChooseException
346        {
347            public int Quantity { get; internal set; }
348            public int MinQuantity { get; internal set; }
349            public int MaxQuantity { get; internal set; }
350
351            public ChooseQuantityException(int quantity, int minQuantity, int maxQuantity)
352            {
353                Quantity = quantity;
354                MinQuantity = minQuantity;
355                MaxQuantity = maxQuantity;
356            }
357        }
358
359        public class ChooseCardException : ChooseException
360        {
361            public Card Card { get; internal set; }
362
363            public ChooseCardException(Card card)
364            {
365                Card = card;
366            }
367        }
368
369        public class ChooseCardInfoException : ChooseCardException
370        {
371            public ChooseCardInfoException(Card card) : base(card) { }
372        }
373
374        public class ChooseCardPositionException : ChooseCardException
375        {
376            public CardPosition Position { get; internal set; }
377
378            public ChooseCardPositionException(Card card, CardPosition position)
379                : base(card)
380            {
381                Position = position;
382            }
383        }
384
385        #endregion
386
387        #endregion
388
389        #region Gain
390
391        /// <summary>
392        /// 取得する
393        /// </summary>
394        /// <param name="card"></param>
395        public void Gain(Card card)
396        {
397            card.Move(CardPosition.Discard(Player));
398        }
399
400        /// <summary>
401        /// 取得する
402        /// </summary>
403        /// <param name="cards"></param>
404        public void Gain(IList<Card> cards)
405        {
406            foreach (Card card in cards) Gain(card);
407        }
408
409        /// <summary>
410        /// サプライから取得する
411        /// </summary>
412        /// <typeparam name="T">カードの種類</typeparam>
413        public void Gain<T>()
414            where T : ICardInfo, new()
415        {
416            Card card = Card.Select<T>(CardPosition.Supply);
417            Gain(card);
418        }
419
420        /// <summary>
421        /// サプライから選んで取得する
422        /// </summary>
423        /// <param name="filter">フィルタ</param>
424        public void Gain(Func<ICardInfo, bool> filter)
425        {
426            var card = Choose(CardPosition.Supply, filter);
427            Gain(card);
428        }
429
430        /// <summary>
431        /// 手札に取得する
432        /// </summary>
433        /// <param name="card"></param>
434        public void GainToHand(Card card)
435        {
436            card.Move(CardPosition.Hand(Player));
437        }
438
439        /// <summary>
440        /// 手札に取得する
441        /// </summary>
442        /// <param name="cards"></param>
443        public void GainToHand(IList<Card> cards)
444        {
445            foreach (Card card in cards) GainToHand(card);
446        }
447
448        #endregion
449
450        #region イベント
451
452        /// <summary>
453        /// 値を取得する場合のイベント引数
454        /// </summary>
455        public class ValueGettingEventArgs : EventArgs
456        {
457            public int Value { get; set; }
458            public int Player { get; internal set; }
459
460            public ValueGettingEventArgs(int player)
461            {
462                Player = player;
463            }
464        }
465
466        #endregion
467    }
468}
Note: See TracBrowser for help on using the browser.