自分の番になったらカードを出す処理が必要です。カードを出すための動作として画面下に並んでいるカードをクリックすることにします。
クリックされたことでどのカードがクリックされたのかわかるようにする必要があります。
自作メソッドのShowMyCardsのなかで自分のカードを表示するまえに種類順と番号順でソートしていますが、このときにplayersCards[0]の中身もソートできるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public partial class Form1 : Form { void ShowMyCards(Graphics g) { if(playersCards[0] == null || playersCards[0].Count == 0) return; List<Card> cards1 = new List<Card>(); cards1.AddRange(playersCards[0].Where(x => x.Mark == CardMark.spade).OrderBy(x => x.Number)); cards1.AddRange(playersCards[0].Where(x => x.Mark == CardMark.hart).OrderBy(x => x.Number)); cards1.AddRange(playersCards[0].Where(x => x.Mark == CardMark.dia).OrderBy(x => x.Number)); cards1.AddRange(playersCards[0].Where(x => x.Mark == CardMark.club).OrderBy(x => x.Number)); playersCards[0] = cards1; // 結果を代入する int i = 20; foreach(var card in cards1) { Point pt = new Point(i, 450); card.CopyDrawCard(g, pt); i += 70; } } } |
それからカードの大きさは静的メンバーにしました。
1 2 3 4 5 6 7 8 9 |
class Card { // カードの大きさ(縦横のサイズ)staticをつけた static Size size = new Size(60, 90); static public Size Size { get { return size; } } } |
GetMyCardRectangleは自分のカードが表示されている矩形を返すメソッドです。カードの持ち数を調べて順番に調べていけばクリックされた場所がカードが表示されている矩形の内部かどうかがわかります。
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 |
public partial class Form1 : Form { Rectangle GetMyCardRectangle(int index) { int i = 20 + index * 70; Point pt = new Point(i, 450); Size size = Card.Size; return new Rectangle(pt, size); } private void Form1_MouseClick(object sender, MouseEventArgs e) { if(playersCards == null) return; var playerCards = playersCards[0]; int cardsCount = playerCards.Count; if(cardsCount == 0) return; for(int i=0; i< cardsCount; i++) { Rectangle rect = GetMyCardRectangle(i); if(rect.Top > e.Y) return; if(rect.Bottom < e.Y) return; if(rect.Left < e.X && e.X < rect.Right) { int num = playerCards[i].Number; string s = playerCards[i].Mark.ToString(); MessageBox.Show(s + num.ToString()); return; } } } } |
実際にクリックしてみると正しく表示されていることがわかります。マウスポインタがキャプチャされていないので画像ではわかりませんが・・・
クリックされているカードがわかったら、本当にそのカードは出せるカードなのか調べます。テーブルのうえに出されているカードのそれぞれの種類について最大値と最小値を調べます。最大値の次の値が13以下、最小値の一つ前の値が1以上のとき、それは出すことができるカードです。
そこで出せるカードを調べて取得するメソッドをつくります。これが返す結果と比較すれば出せるカードなのかわかります。
GetCanTakeoutメソッドは出せるカードを取得するメソッドです。
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 |
public partial class Form1 : Form { List<Card> GetCanTakeout() { List<Card> retCards = new List<Card>(); List<Card> tableCards = cards.Where(x => x.isExists).ToList(); int spadeMax = tableCards.Where(x => x.Mark == CardMark.spade).Max(x => x.Number); if(spadeMax + 1 <= 13) retCards.Add(GetCard(CardMark.spade, spadeMax + 1)); int spadeMin = tableCards.Where(x => x.Mark == CardMark.spade).Min(x => x.Number); if(spadeMin - 1 >= 1) retCards.Add(GetCard(CardMark.spade, spadeMin - 1)); int hartMax = tableCards.Where(x => x.Mark == CardMark.hart).Max(x => x.Number); if(hartMax + 1 <= 13) retCards.Add(GetCard(CardMark.hart, hartMax + 1)); int hartMin = tableCards.Where(x => x.Mark == CardMark.hart).Min(x => x.Number); if(hartMin - 1 >= 1) retCards.Add(GetCard(CardMark.hart, hartMin - 1)); int diaMax = tableCards.Where(x => x.Mark == CardMark.dia).Max(x => x.Number); if(diaMax + 1 <= 13) retCards.Add(GetCard(CardMark.dia, diaMax + 1)); int diaMin = tableCards.Where(x => x.Mark == CardMark.dia).Min(x => x.Number); if(diaMin - 1 >= 1) retCards.Add(GetCard(CardMark.dia, diaMin - 1)); int clubMax = tableCards.Where(x => x.Mark == CardMark.club).Max(x => x.Number); if(clubMax + 1 <= 13) retCards.Add(GetCard(CardMark.club, clubMax + 1)); int clubMin = tableCards.Where(x => x.Mark == CardMark.club).Min(x => x.Number); if(clubMin - 1 >= 1) retCards.Add(GetCard(CardMark.club, clubMin - 1)); return retCards; } Card GetCard(CardMark mark, int number) { return cards.First(x => x.Number == number && x.Mark == mark); } } |
CanTakeoutは指定したカードがGetCanTakeoutメソッドで取得したカードのなかに含まれるかどうか調べるメソッドです。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { bool CanTakeout(CardMark mark, int number) { List<Card> cards = GetCanTakeout(); if(cards.Any(x => x.Mark == mark && x.Number == number)) return true; else return false; } } |
フォームのうえでクリックされたら自分のカードがクリックされたのか、そのカードはなにか、そのカードは出せるカードなのか調べて出せるカードであればテーブルのうえに出して自分の手元のカードから取り除きます。
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 { private void Form1_MouseClick(object sender, MouseEventArgs e) { if(playersCards == null) return; var playerCards = playersCards[0]; int cardsCount = playerCards.Count; if(cardsCount == 0) return; for(int i=0; i< cardsCount; i++) { Rectangle rect = GetMyCardRectangle(i); if(rect.Top > e.Y) return; if(rect.Bottom < e.Y) return; if(rect.Left < e.X && e.X < rect.Right) { int num = playerCards[i].Number; CardMark mark = playerCards[i].Mark; if(!CanTakeout(mark, num)) { MessageBox.Show("このカードは出せません!", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // これを自分のカードから該当するカードを探して取り除く Card card = playerCards.First(x => x.Mark == mark && x.Number == num); playerCards.Remove(card); // テーブルのうえに出されたことにする card.isExists = true; // 全体を再描画する Invalidate(); return; } } } } |
失礼いたします。
GetCanTakeoutメソッド内のGetCardメソッドが存在しないため、エラーになってしまいます。
たしかに書かれていませんね。記事を修正しました。GetCanTakeoutメソッドの下にあります。
adminさん、いつも参考にさせていただいています。
解決いたしました。ありがとうございます。