Created
June 26, 2018 13:59
-
-
Save todorok1/4c0f317fda4f3f7d17a0584ef5f24169 to your computer and use it in GitHub Desktop.
山札から何枚かのカードを手札に加えるサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class RandomShuffleTest : MonoBehaviour { | |
// カードを保持するリスト | |
List<Card> cardList; | |
// プレイヤーのリスト | |
List<Card> playerCardList; | |
// 各マーク(スート)での枚数を設定 | |
const int numbersInSuit = 13; | |
// 各マーク(スート)のIDを決める | |
const int Spade = 0; | |
const int Club = 1; | |
const int Heart = 2; | |
const int Diamond = 3; | |
List<int> suits = new List<int>(){Spade, Club, Heart, Diamond}; | |
void Start(){ | |
InitializeCardList(); | |
ShuffleCards(); | |
Debug.Log("***** 配布前の山札 *****"); | |
ShowCardsName(cardList); | |
// DistributeCard(8); | |
DistributeFromDeckHead(8); | |
Debug.Log("***** 配布後の山札 *****"); | |
ShowCardsName(cardList); | |
Debug.Log("***** 手札 *****"); | |
ShowCardsName(playerCardList); | |
CheckDuplication(playerCardList); | |
} | |
void InitializeCardList(){ | |
// 山札を初期化する | |
cardList = new List<Card>(); | |
// 各マーク(スート)ごとにカードを生成 | |
foreach (int suit in suits){ | |
for (int i = 1; i <= numbersInSuit; i++){ | |
Card card = new Card(suit, i, false); | |
cardList.Add(card); | |
} | |
} | |
// ジョーカーを追加 | |
Card joker = new Card(0, 0, true); | |
cardList.Add(joker); | |
} | |
void ShowCardsName(List<Card> showCardList){ | |
// コンソールに出力する文字列を生成 | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
string separator = ", "; | |
foreach(Card card in showCardList){ | |
if (card.isJoker){ | |
sb.Append("JOKER").Append(separator); | |
} else { | |
sb.Append(GetSuitMark(card.suit)).Append(GetSpecialNumber(card.number)).Append(separator); | |
} | |
} | |
string cardText = sb.ToString(); | |
// 1行あたり15枚のカードを表示する | |
int cardInLine = 15; | |
int cardCount = 0; | |
// 区切り文字を使って、カードを1枚ごとの配列に格納する | |
string[] separatorChar = {separator}; | |
string[] cards = cardText.Split(separatorChar, System.StringSplitOptions.RemoveEmptyEntries); | |
sb = new System.Text.StringBuilder(); | |
for (int i = 0; i < cards.Length; i++){ | |
sb.Append(cards[i]).Append(separator); | |
cardCount++; | |
// 表示枚数に達したらコンソールに表示 | |
if (cardCount < cardInLine){ | |
continue; | |
} | |
string line = sb.ToString(); | |
if (i == cards.Length - 1){ | |
line = RemoveLastSeparator(line, separator); | |
} | |
Debug.Log(line); | |
sb = new System.Text.StringBuilder(); | |
cardCount = 0; | |
} | |
// 最後のカンマだけ削除する | |
string lastLine = sb.ToString(); | |
if (lastLine.Length > 0){ | |
lastLine = RemoveLastSeparator(lastLine, separator); | |
Debug.Log(lastLine); | |
} | |
} | |
string RemoveLastSeparator(string line, string separator){ | |
int index = line.LastIndexOf(separator); | |
if (index != -1){ | |
line = line.Remove(index); | |
} | |
return line; | |
} | |
string GetSuitMark(int suit){ | |
// マーク(スート)のIDに応じた文字を返す | |
string suitMark; | |
switch (suit){ | |
case Spade: | |
suitMark = "♠︎"; | |
break; | |
case Club: | |
suitMark = "♣︎"; | |
break; | |
case Heart: | |
suitMark = "❤︎"; | |
break; | |
case Diamond: | |
suitMark = "♦︎"; | |
break; | |
default: | |
suitMark = "JOKER"; | |
break; | |
} | |
return suitMark; | |
} | |
string GetSpecialNumber(int number){ | |
if (number < 11){ | |
return number.ToString(); | |
} | |
string special = "None"; | |
switch (number){ | |
case 11: | |
special = "J"; | |
break; | |
case 12: | |
special = "Q"; | |
break; | |
case 13: | |
special = "K"; | |
break; | |
} | |
return special; | |
} | |
void ShuffleCards(){ | |
// カードをシャッフルする | |
for (int i = 0; i < cardList.Count; i++){ | |
Card temp = cardList[i]; | |
int randomIndex = Random.Range(0, cardList.Count); | |
cardList[i] = cardList[randomIndex]; | |
cardList[randomIndex] = temp; | |
} | |
} | |
void DistributeCard(int numRequired){ | |
// 指定された枚数の手札を山札から配布する | |
playerCardList = new List<Card>(); | |
// 残ったカードを格納するリスト | |
List<Card> leftCardList = new List<Card>(); | |
int numToChoose = numRequired; | |
for (int i = 0; i < cardList.Count; i++){ | |
if (numToChoose <= 0){ | |
// 残ったカードをそのまま残りリストに追加して次のカードへ移動 | |
leftCardList.Add(cardList[i]); | |
continue; | |
} | |
int numLeft = cardList.Count - i; | |
float prob = (float)numToChoose / (float)numLeft; | |
if (Random.value <= prob){ | |
numToChoose--; | |
playerCardList.Add(cardList[i]); | |
} else { | |
leftCardList.Add(cardList[i]); | |
} | |
} | |
// 残ったカードを山札とする | |
cardList = leftCardList; | |
} | |
void CheckDuplication(List<Card> cards){ | |
// 手札にあるカードが山札に無いことを確認する | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
string duplicateText; | |
string separator = ", "; | |
for (int i = 0; i < cards.Count; i++){ | |
if (cardList.Exists(x => x.Equals(cards[i]))){ | |
duplicateText = "が重複"; | |
} else { | |
duplicateText = "は重複せず"; | |
} | |
if (cards[i].isJoker){ | |
sb.Append("JOKER"); | |
} else { | |
sb.Append(GetSuitMark(cards[i].suit)).Append(GetSpecialNumber(cards[i].number)); | |
} | |
sb.Append(duplicateText).Append(separator); | |
} | |
string line = sb.ToString(); | |
line = RemoveLastSeparator(line, separator); | |
Debug.Log(line); | |
} | |
void DistributeFromDeckHead(int numRequired){ | |
// シャッフルされた山札の先頭からカードを配布する | |
playerCardList = new List<Card>(); | |
for (int i = 0; i < numRequired; i++){ | |
playerCardList.Add(cardList[i]); | |
} | |
// プレイヤーに配布したカードをリストから削除 | |
cardList.RemoveRange(0, numRequired); | |
} | |
} | |
public struct Card{ | |
// カードのマーク(スート)を保持 | |
public int suit; | |
// カードの数字 | |
public int number; | |
// ジョーカーかどうか | |
public bool isJoker; | |
public Card(int suit, int number, bool isJoker){ | |
this.suit = suit; | |
this.number = number; | |
this.isJoker = isJoker; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment