重ならない乱数配列の作成
トランプのシャッフルなど、シャッフルをするのですが重なってはいけないケースの場合を考えてみましょう
C#の基本文法だけでも作成できますが、今回は一足飛びにLINQを使った方法を紹介します
0から9までの10個の整数をシャッフルするコード
元になるコード
int[] randomNumbers = Enumerable.Range(0, 10).OrderBy(_ => Guid.NewGuid()).ToArray();
0から9までの数字をランダムに並び替えた整数型の配列を作成します。
まず、Enumerable.Range(0, 10)
は、0から9までの整数のシーケンスを作成します。
OrderBy(_ => Guid.NewGuid())
は、ランダムなGUID(グローバル一意識別子)を使用して、配列の要素をランダムに並び替えます。
最後に、ToArray()
メソッドを使用して、並び替えられたシーケンスを整数型の配列に変換します。
テスト用コード
int[] randomNumbers = Enumerable.Range(0, 10).OrderBy(_ => Guid.NewGuid()).ToArray();
foreach (var number in randomNumbers)
{
Console.WriteLine(number);
}
結果
0
8
1
2
7
3
9
5
4
6
正数配列を渡して、シャッフルした結果を得るコード
元になるコード
int[] randomNumbers = numbers.OrderBy(_ => Guid.NewGuid()).ToArray();
このコードは、配列numbers
内の要素をランダムな順序で並び替えるために使用されます。
OrderBy
メソッドは、LINQ(Language Integrated Query)によって提供される拡張メソッドの一種であり、IEnumerable<T>型のオブジェクトに対して使用されます。このメソッドは、指定されたキーに基づいてシーケンスの要素を昇順に並べ替えます。この例では、キーとしてランダムなGuidオブジェクトを使用しています。
Guid.NewGuid()
は、ランダムなGUID(Globally Unique Identifier)を生成するための.NET Frameworkのメソッドです。
最後に、ToArray()
メソッドは、結果を新しい配列として返します。randomNumbers
変数は、ランダムに並び替えられたnumbers
の要素が格納された新しい配列を表します。
テスト用コード
int[] numbers = new int[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
int[] randomNumbers = numbers.OrderBy(_ => Guid.NewGuid()).ToArray();
foreach (var number in randomNumbers)
{
Console.WriteLine(number);
}
結果
11
10
18
13
17
15
14
12
16
19
メソッドにしたテスト用コード
int[] numbers = new int[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
int[] randomNumbers = ShuffleRange(numbers);
foreach (var number in randomNumbers)
{
Console.WriteLine(number);
}
/// <summary>
/// 与えれたた正数配列をシャッフルします
/// </summary>
/// <param name="array">シャッフルする正数配列</param>
/// <returns>シャッフルされた正数配列</returns>
int[] ShuffleRange(int[] array) => array.OrderBy(_ => Guid.NewGuid()).ToArray();
結果
15
16
18
19
13
10
17
11
14
12
トランプのカードをシャッフルするサンプル
トランプのカードクラス
class Card
{
public enum SuitEnum
{
Spade,
Heart,
Diamond,
Club,
}
public Card(SuitEnum suit, int number)
{
Suit = suit;
Number = number;
}
public SuitEnum Suit { get; set; }
public int Number { get; set; }
}
カードのインスタンスを作成する
4つのマークで1-13までのカードを作成することとします
Card[] cards = new Card[52];
int counter = 0;
for (int number = 1; number <= 13; number++)
{
for (int suit = 0; suit < 4; suit++)
{
Card.SuitEnum suitEnum = (Card.SuitEnum)suit;
cards[counter++] = new Card(suitEnum, number);
}
}
カードのインスタンス配列をシャッフルするジェネリックメソッド
/// <summary>
/// 与えれたたインスタンス配列をシャッフルします
/// </summary>
/// <param name="array">シャッフルする正数配列</param>
/// <returns>シャッフルされたインスタンス配列</returns>
T[] ShuffleRange<T>(T[] array) => array.OrderBy(_ => Guid.NewGuid()).ToArray();
インスタンスを作成したカードのインスタンス(山札)をシャッフルするためのメソッド呼び出し
Card[] shuffleCards = ShuffleRange(cards);
テスト用コード
foreach (var card in shuffleCards)
{
Console.WriteLine($"{card.Suit} {card.Number}");
}
結果
Club 5
Club 6
Spade 7
Heart 4
Diamond 3
Heart 8
Spade 11
Club 11
Diamond 9
Heart 6
Diamond 5
Diamond 1
Diamond 8
Club 3
Diamond 4
Spade 12
Spade 4
Heart 2
Club 9
Heart 3
Club 13
Club 8
Diamond 6
Diamond 2
Spade 13
Club 10
Spade 10
Spade 9
Heart 10
Heart 7
Heart 5
Heart 1
Club 2
Spade 5
Heart 11
Diamond 12
Heart 12
Heart 13
Club 1
Club 12
Diamond 10
Spade 8
Spade 2
Diamond 7
Club 4
Heart 9
Diamond 13
Club 7
Diamond 11
Spade 3
Spade 1
Spade 6
トランプのシャッフルコード(Listバージョン)
List<Card> cards = new List<Card>();
int counter = 0;
for (int number = 1; number <= 13; number++)
{
for (int suit = 0; suit < 4; suit++)
{
Card.SuitEnum suitEnum = (Card.SuitEnum)Enum.ToObject(typeof(Card.SuitEnum), suit);
cards.Add(new Card(suitEnum, number));
}
}
List<Card> shuffleCars = ShuffleRange(cards);
/// <summary>
/// 与えれたたインスタンス配列をシャッフルします
/// </summary>
/// <param name="array">シャッフルする正数配列</param>
/// <returns>シャッフルされたインスタンス配列</returns>
List<T> ShuffleRange<T>(List<T> array) => array.OrderBy(_ => Guid.NewGuid()).ToList();
foreach (var card in shuffleCars)
{
Console.WriteLine($"{card.Suit} {card.Number}");
}
class Card
{
public enum SuitEnum
{
Spade,
Heart,
Diamond,
Club,
}
public Card(SuitEnum suit, int number)
{
Suit = suit;
Number = number;
}
public SuitEnum Suit { get; set; }
public int Number { get; set; }
}
ディスカッション
コメント一覧
まだ、コメントがありません