殺しの七並べでは横だけでなく縦や斜めでつながっていてもカードを出すことができます。前回はそのルールにあわせてカードが出せるか判定する方法を考えました。
今回はカードが出されたことでカードが死ぬかどうかを判定する方法を考えます。
Contents
カードが置かれることで死ぬカードとは
カードが置かれることで死ぬカードは、そのカードの上下左右にあるカードとそれとつながっているカードで、まだテーブルのうえに出されていないカードです。
そこで置かれたカードの上下左右のカードについて、そのカードと縦または横でつながっている出されていないカードを取得します。そのカード群が長方形になっていれば殺されたカードということになります。
出されたカードの上隣りにあるカードを北、右なら東、左なら西、下なら南と定義します。
隣り合うカード群を取得する
まずは北側のカードと隣り合うカード群を取得するメソッド GetNorthTenvironmentCardを示します。
マークが同じなら前後の番号のカードを取得すればいいのですが、上下にあるカードは番号が同じでマークが異なるカードです。そのため引数のカードのマークを取得して、上下にくるカードをマークを調べています。
そしてカードの上下左右にあるカードを取得するメソッド GeTenvironmentCardを再帰呼び出ししています。これで置かれたカードの北側にあるカード群を取得することができます。
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 |
public partial class Form1 : Form { List<Card> GetNorthTenvironmentCard(Card card) { List<Card> gotCardsNorth = new List<Card>(); CardMark northCardMark = CardMark.none; if(card.Mark == CardMark.hart) northCardMark = CardMark.spade; if(card.Mark == CardMark.dia) northCardMark = CardMark.hart; if(card.Mark == CardMark.club) northCardMark = CardMark.dia; if(northCardMark != CardMark.none) { Card northCard = GetCard(northCardMark, card.Number); if(northCard != null && !northCard.isExists) { gotCardsNorth.Add(northCard); GeTenvironmentCard(northCard, gotCardsNorth); } } return gotCardsNorth; } } |
GetCardメソッドの修正
GeTenvironmentCardメソッドは引数で指定されたカードの上下左右にあるもので、テーブルのうえに存在しないカードを取得します。内部でGetCardメソッドを使用していますが、これまでのGetCardメソッドには欠陥がありました。
これまで使用してきたGetCardメソッドを示します。
1 2 3 4 5 6 7 |
public partial class Form1 : Form { Card GetCard(CardMark mark, int number) { return cards.First(x => x.Number == number && x.Mark == mark); } } |
これでは第二引数に0以下や14以上の値を指定したとき、例外が発生してしまいます。そこで以下のように修正しました。
第二引数に0以下や14以上の値を指定したときはnullを返します。ということはGetCardメソッドを使うときは戻り値チェックが必要になることになります。
1 2 3 4 5 6 7 8 9 10 |
public partial class Form1 : Form { Card GetCard(CardMark mark, int number) { if(1 <= number && number <= 13) return cards.First(x => x.Number == number && x.Mark == mark); else return null; } } |
つながったカード群を取得するGeTenvironmentCardメソッド
そのカードの上下左右にあってテーブルのうえに存在しないカードを取得するGeTenvironmentCardメソッドを示します。
再帰呼び出しをしているのですが、すでに取得したカードを引数にした再帰呼び出しはしないようにしています。
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 |
public partial class Form1 : Form { void GeTenvironmentCard(Card card, List<Card> gotCards) { List<Card> cards0 = new List<Card>(); if(card.Mark == CardMark.spade) { Card card2 = GetCard(CardMark.spade, card.Number-1); if(card2 != null && !card2.isExists) cards0.Add(card2); Card card3 = GetCard(CardMark.spade, card.Number + 1); if(card3 != null && !card3.isExists) cards0.Add(card3); Card card4 = GetCard(CardMark.hart, card.Number); if(!card4.isExists) cards0.Add(card4); } else if(card.Mark == CardMark.hart) { Card card1 = GetCard(CardMark.spade, card.Number); if(!card1.isExists) cards0.Add(card1); Card card2 = GetCard(CardMark.hart, card.Number - 1); if(card2 != null && !card2.isExists) cards0.Add(card2); Card card3 = GetCard(CardMark.hart, card.Number + 1); if(card3 != null && !card3.isExists) cards0.Add(card3); Card card4 = GetCard(CardMark.dia, card.Number); if(!card4.isExists) cards0.Add(card4); } else if(card.Mark == CardMark.dia) { Card card1 = GetCard(CardMark.hart, card.Number); if(!card1.isExists) cards0.Add(card1); Card card2 = GetCard(CardMark.dia, card.Number - 1); if(card2 != null && !card2.isExists) cards0.Add(card2); Card card3 = GetCard(CardMark.dia, card.Number + 1); if(card3 != null && !card3.isExists) cards0.Add(card3); Card card4 = GetCard(CardMark.club, card.Number); if(!card4.isExists) cards0.Add(card4); } else if(card.Mark == CardMark.club) { Card card1 = GetCard(CardMark.dia, card.Number); if(!card1.isExists) cards0.Add(card1); Card card2 = GetCard(CardMark.club, card.Number - 1); if(card2 != null && !card2.isExists) cards0.Add(card2); Card card3 = GetCard(CardMark.club, card.Number + 1); if(card3 != null && !card3.isExists) cards0.Add(card3); } foreach(Card card5 in cards0) { if(!gotCards.Any(x => x == card5)) { gotCards.Add(card5); GeTenvironmentCard(card5, gotCards); } } } } |
同様に東、西、南についても同じように取得します。
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 |
public partial class Form1 : Form { List<Card> GetEastTenvironmentCard(Card card) { List<Card> gotCardsEast = new List<Card>(); Card eastCard = GetCard(card.Mark, card.Number + 1); if(eastCard != null && !eastCard.isExists) { gotCardsEast.Add(eastCard); GeTenvironmentCard(eastCard, gotCardsEast); } return gotCardsEast; } List<Card> GetWestTenvironmentCard(Card card) { List<Card> gotCardsWest = new List<Card>(); Card westCard = GetCard(card.Mark, card.Number - 1); if(westCard != null && !westCard.isExists) { gotCardsWest.Add(westCard); GeTenvironmentCard(westCard, gotCardsWest); } return gotCardsWest; } List<Card> GetSouthTenvironmentCard(Card card) { List<Card> gotCardsSouth = new List<Card>(); CardMark southCardMark = CardMark.none; if(card.Mark == CardMark.spade) southCardMark = CardMark.hart; if(card.Mark == CardMark.hart) southCardMark = CardMark.dia; if(card.Mark == CardMark.dia) southCardMark = CardMark.club; if(card.Mark == CardMark.club) southCardMark = CardMark.none; if(southCardMark != CardMark.none) { Card southCard = GetCard(southCardMark, card.Number); if(southCard != null && !southCard.isExists) { gotCardsSouth.Add(southCard); GeTenvironmentCard(southCard, gotCardsSouth); } } return gotCardsSouth; } } |
今後の課題
これで隣り合うカード群を取得することができました。あとはこれが矩形になっていれば「カードの死」が確定します。では囲まれたカードが矩形になっているかどうかはどうやって判定すればよいでしょうか?