この動画は前回作成した神経衰弱です。
カードを作成したあとシャッフルをするのですが、最初は以下のような方法を考えていました。
主要な部分だけなので前回作成したクラスとは違います。カードの画像は表示されません。
神経衰弱で必要なのは数字です。以下のクラスでは数字と表示する座標だけをあつかっています。
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 |
public class Card { public Font Font = new Font("MS ゴシック", 12, FontStyle.Bold); public Card(int number) { Number = number; } public int Number { private set; get; } public int Row { set; private get; } public int Colum { set; private get; } public Point Point { get { return new Point(Colum * 30 + 20, Row * 50 + 20); } } } |
これを継承して以下のようなクラスを作成します。なにをしたいのかというとOrderにランダムに生成した値をセットしたあとこの値でソートすれば簡単にシャッフルと同じ効果が得られるかもしれないと考えているのです。
1 2 3 4 5 6 7 8 9 10 |
public class CardEx : Card { public CardEx(int number):base(number) { } public int Order { set; get; } } |
あとは以下のようにすればカードの番号だけがシャッフルされた状態で表示されるはずです。
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 70 71 72 73 74 |
public partial class Form1 : Form { List<CardEx> Cards = new List<CardEx>(); public Form1() { InitializeComponent(); ResetCards(); } void ResetCards() { Cards = CreateCards(); SetCards(Cards); Invalidate(); } List<CardEx> CreateCards() { List<CardEx> cards = new List<CardEx>(); for (int i = 1; i <= 13; i++) { for (int j = 0; j < 4; j++) cards.Add(new CardEx(i)); } return cards; } void SetCards(List<CardEx> cards) { int columMax = 10; int rowMax = 6; for (int row = 0; row < rowMax; row++) { for (int col = 0; col < columMax; col++) { int index = row * columMax + col; if (index < cards.Count) { cards[index].Colum = col; cards[index].Row = row; } } } } protected override void OnPaint(PaintEventArgs e) { foreach (Card card in Cards) e.Graphics.DrawString(card.Number.ToString("00"), card.Font, new SolidBrush(Color.Black), card.Point ); base.OnPaint(e); } List<CardEx> ShuffleCards(List<CardEx> cards) { Random random = new Random(); foreach (CardEx card in cards) { int rand = random.Next(1000); card.Order = rand; } return cards.OrderBy(x => x.Order).ToList(); } private void button1_Click(object sender, EventArgs e) { Cards = ShuffleCards(Cards); SetCards(Cards); Invalidate(); } } |
これが実行結果です。上がシャッフルされるまえの状態、下がシャッフルされた状態です。
どうでしょうか? 隣が同じ数になっている場所が3箇所もあり、それ以外にも連続する数が隣にある場所が多くないでしょうか?
何回かやってみました。またrandom.Next(1000)の1000の部分も変えて実験してみたところ、以下のような結果になりました。独自の方法と書いている部分は前回の方法でシャッフルした場合の結果です。
シャッフルした結果をさらに連続でシャッフルしたらどうなるかも調べてみました([シャッフル]ボタンを連打すればよい)。
どうでしょうか? random.Nextの引数を大きくしたり小さくすることでとくに大きな変化はみられないように思えます。また連続でシャッフルの処理をしてもあまりかわらないようです。とりあえずシャッフルしてみて隣が同じ数とか連続する数が隣にある部分が多すぎる場合はもう一度処理をやり直すということで良さそうな気がします。