Skip to content

Instantly share code, notes, and snippets.

@todorok1
Created June 26, 2018 13:59
Show Gist options
  • Save todorok1/4c0f317fda4f3f7d17a0584ef5f24169 to your computer and use it in GitHub Desktop.
Save todorok1/4c0f317fda4f3f7d17a0584ef5f24169 to your computer and use it in GitHub Desktop.
山札から何枚かのカードを手札に加えるサンプル
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