七並べではパスは3回まで。すでに3回パスをしているのにカードが出せない場合は失格です。
失格になったら手持ちのカードをテーブルの上に並べるなければなりません。この処理自体は簡単ですが、その他のプレイヤーが出せるカードがどれになるのか取得する方法を考える必要があります。
これまでは出されているカードの最大値や最小値の次の番号としていましたが、これを使うことはできません。GetCanTakeoutメソッドを作り直す必要があります。
テーブルの上に置かれているカードではなく欠けているカードに着目することができれば簡単でした。これに気づかず、この記事を書き直す前は長いコードを書いていました。(失敗)
カードが1~13まで全部そろっているのであれば出せるカードはない
トンネルが成立していない場合は
1.1~7で欠けているもののうち最大のもの
2.8~13で欠けているもののうち最小のもの
このふたつが出せるカードです。
トンネルが成立している場合、方向を考える必要があるのですが、
1.1~7に欠けているものはあるか
2.8~13に欠けているものはあるか
これを調べればわかります。
あとは
1 ⇒ 13 のトンネルが成立している
13以下で欠けているもののうち最大のものを探す
13 ⇒ 1 のトンネルが成立している
1以上で欠けているもののうち最小のものを探す
これで簡単に答えが出せてしまうのです。
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 |
public partial class Form1 : Form { List<Card> GetCanTakeout(CardMark mark) { List<Card> retCards = new List<Card>(); List<Card> notExistCards = cards.Where(x => x.Mark == mark && !x.isExists).ToList(); // カードはすべてそろっている if(notExistCards.Count == 0) { return retCards; } // トンネルは成立しているか? if(notExistCards.Count(x => x.Number < 7) == 0) { // 1 ⇒ 13 が成立している // 13以下で欠けているもののうち最大のものを探す int i = notExistCards.Where(x => x.Number <= 13).Max(x => x.Number); retCards.Add(GetCard(mark, i)); return retCards; } else if(notExistCards.Count(x => x.Number > 7) == 0) { // 13 ⇒ 1 が成立している // 1以上で欠けているもののうち最小のものを探す int i = notExistCards.Where(x => x.Number >= 1).Min(x => x.Number); retCards.Add(GetCard(mark, i)); return retCards; } // トンネルは成立していない // 番号が小さい側を求める // 1~7で欠けているもののうち最大のものを探す int left = notExistCards.Where(x => x.Number < 7).Max(x => x.Number); // 番号が大きい側を求める // 8~13で欠けているもののうち最小のものを探す int right = notExistCards.Where(x => x.Number > 7).Min(x => x.Number); retCards.Add(GetCard(mark, left)); retCards.Add(GetCard(mark, right)); return retCards; } } |