我有一个名为mainDeck
的数组,它包含一副扑克牌的值。我接下来要做的是将该数组中的卡分发给两个名为playerDeck
和computerDeck
的独立数组,每个数组必须包含一张唯一的卡。
我遇到的问题是分发具有独特价值的卡片 - 每张卡片26张卡片。我尝试了一些不同的方法,评论底部的编码是我在离开课堂之前我想要做的最后一部分,但还没完成。
要注意:我的编程技巧仅限于请解释您的答案,而不是仅仅提供一个解决方案,因为这不会进一步理解。
static void Main(string[] args)
{
// 1 = Ace , 13 = King : 0 = Hearts, 1 = Diamonds, 2 = Clubs, 3 = Spades
int[] mainDeck = new int[52];
FillDeck(mainDeck);
int[] playerDeck = new int[26];
int[] computerDeck = new int[26];
// Check mainDeck elements
foreach (int number in mainDeck)
{
Console.WriteLine(number);
}
}
public static void FillDeck(int [] mainDeck)
{
int cardType = 1;
List<int> deck = new List<int>();
// Add cards to a list
for (int x = 0; x < 13; x++)
for(int y = 0; y < 4; y++)
{
deck.Add(cardType);
if (y == 3)
++cardType;
}
// Insert deck list into a new Array
int[] cards = deck.GetRange(0, 52).ToArray();
// Add cards array to mainDeck
for (int x = 0; x < 52; ++x)
{
mainDeck[x] = cards[x];
}
}
//public static void Distribute()
//{
// RandomNumber number = new RandomNumber();
// int value = number.RandomNum;
// List<int> playerCards = new List<int>();
// for (int x = 0; x < 2; ++x)
// {
// Console.WriteLine(number.RandomNum);
// }
//}
}
//class RandomNumber
//{
// private int randomNum;
// Random ranNumberGenerator;
// public RandomNumber()
// {
// ranNumberGenerator = new Random();
// }
// public int RandomNum
// {
// get
// {
// randomNum = ranNumberGenerator.Next(1, 26);
// return randomNum;
// }
// }
//}
答案 0 :(得分:2)
如果您试图像在典型的纸牌游戏中那样随机分发卡片,这里有一篇关于洗牌的文章。 - http://www.dotnetperls.com/shuffle - 它应该做你想要的。
在你对mainDeck数组进行随机播放之后,你只需循环遍历它就可以像在现实生活中处理卡一样将卡分配给播放器和计算机卡片。
答案 1 :(得分:2)
纸牌游戏卡的常见解决方案
所以代码:)
public enum CardColor
{
Hearts = 0,
Diamonds = 1,
Clubs = 2,
Spades = 3
}
public enum CardValue
{
Ace = 1,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King
}
public class Card
{
public Card(CardValue value, CardColor color)
{
Value = value;
Color = color;
}
public readonly CardValue Value;
public readonly CardColor Color;
}
public class Deck
{
private Queue<Card> deckInternal;
public Deck()
{
var deck = new List<Card>();
for(int index = 0; index < 52; index++)
{
var cardValue = (CardValue)(index % 4) + 1;
var cardColor = (CardColor)index / 4;
dec.Add(new Card(cardValue, cardColor));
}
var rand = new Random();
dec = dec
.OrderBy(c => rand.Next(52))
.ToList();
deckInternal = new Queue<Card>(deck);
}
public Card GetCard()
{
return deckInternal.Dequeue();
}
}
获得套牌并将其拆分,你可以做下一步
var deck = new Deck();
var player = new List<Card>();
var computer = new List<Card>();
for(int index = 0; index < 52; index++)
{
if(index % 2 == 0)
{
player.Add(deck.GetCard());
}
else
{
computer.Add(deck.GetCard());
}
}
答案 2 :(得分:1)
您可以通过两种选项在这里保持甲板中的唯一值。您可以创建一个代表卡片的新类,它具有Rank和Suit的属性,或者如果您想保持简单(从编译器的角度来看,无论如何),您可以使用该值来指示等级和套装,而您'使用1到13来表示排名。
对于后一种解决方案,您可能希望使用数字0到12来表示通过心之王的王牌,13到25来表示通过钻石王的王牌,依此类推。要获得您使用的任何卡片的等级card % 13
并获得您使用的卡片的套装card / 4
。
我更喜欢以前的解决方案,并且会创建一个这样的类(您也可以使用Enums替换int属性以获得更高的可读性):
public class Card
{
public int Rank { get; set; }
public int Suit { get; set; }
}
之后,您可以创建一个循环,直到主甲板为空,并从主甲板上挑选一张随机牌放入另外两个甲板。在伪代码中,它可能看起来像:
while (mainDeck has any elements)
num = random number between 0 and elements in mainDeck - 1, inclusive
deckToAddTo = alternate between playerDeck and computerDeck
remove card num from mainDeck and insert into deckToAddTo
答案 3 :(得分:0)
给玩家前26张牌。
playerDeck = mainDeck.Take(26).ToArray();
跳过玩家的牌并获得接下来的26张牌。
computerDeck = mainDeck.Skip(26).Take(26).ToArray();
答案 4 :(得分:0)
Random rnd = new Random();
// you can Shuffle Array and Take random 26 items using Linq as below
int[] playerDeck = mainDeck.OrderBy(x => rnd.Next()).Take(26).ToArray();
// get rest of the items using Except linq method
int[] computerDeck = mainDeck.Except(playerDeck).ToArray();
答案 5 :(得分:-1)
.......
有很多方法可以做到这一点......
它只使用单个字节作为值,尽管您可以根据其他实现使用int进行操作...
我是在20分钟内为你写的......(稍后会添加一些内容)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CodeProjectHelpProject
{
public class Deck
{
#region Nested Types
//Exceptions
public class DeckException : Exception { public DeckException(string message) : base(message) { } public DeckException(string message, Exception inner) : base(message, inner) { } }
#region CardSuit
//Enumeration of Suits a Card can Obtain, Allows the Developer to change the Card Order.
public struct CardSuit
{
//Exceptions
public class CardSuitException : DeckException { public CardSuitException(string message) : base(message) { } }
#region Statics
internal static byte Spade = 0;
internal static byte Club = 1;
internal static byte Heart = 2;
internal static byte Diamond = 3;
public static CardSuit Spades = new CardSuit(Spade);
public static CardSuit Clubs = new CardSuit(Club);
public static CardSuit Hearts = new CardSuit(Heart);
public static CardSuit Diamonds = new CardSuit(Diamond);
#endregion
#region Properties
public char Symbol
{
get
{
switch (m_Suit)
{
case 0: return '♠';
case 1: return '♣';
case 2: return '♥';
case 3: return '♦';
default: return 'D';
}
}
}
#endregion
#region Fields
internal byte m_Suit;
#endregion
#region Constructor
public CardSuit(byte suit)
{
if (suit < Spade || suit > Diamond) throw new CardSuitException("Invalid Suit");
m_Suit = suit;
}
#endregion
#region CardSuit Overrides
public override string ToString()
{
switch (m_Suit)
{
case 0: return "Spades";
case 1: return "Clubs";
case 2: return "Hearts";
case 3: return "Diamonds";
default: return "Unknown";
}
}
#endregion
#region Operators
public static bool operator >(CardSuit a, CardSuit b){ return a.m_Suit < b.m_Suit;}
public static bool operator <(CardSuit a, CardSuit b){ return a.m_Suit > b.m_Suit;}
public static bool operator >(CardSuit a, int b) { return a.m_Suit > b; }
public static bool operator <(CardSuit a, int b) { return a.m_Suit < b; }
public static implicit operator int(CardSuit a) { return a.m_Suit; }
public static implicit operator CardSuit(int a) { return new CardSuit((byte)a); }
#endregion
}
#endregion
#region Card Structure
public struct Card
{
//Exceptions
public class CardException : DeckException { public CardException(string message) : base(message) { } }
#region Constants
const char CharJoker = default(char);
const char AceValue = unchecked((char)1);
const char JackValue = unchecked((char)11);
const char QueenValue = unchecked((char)12);
const char KingValue = unchecked((char)13);
#endregion
#region Properties
public char Value { get; internal set; }
public Deck.CardSuit Suit { get; internal set; }
public byte Number { get { return (byte)Value; } }
public char Symbol { get { return Name[0]; } }
public string Name { get { return (Value <= 0 ? "Joker" : Value == AceValue ? "Ace" : Value == JackValue ? "Jack" : Value == QueenValue ? "Queen" : Value == KingValue ? "King" : Number.ToString()); } }
#endregion
#region Constructor
public Card(char value, CardSuit suit)
: this()
{
Value = value;
Suit = suit;
}
public Card(int value) : this(unchecked((char)Convert.ToInt32(value / 4)), (Deck.CardSuit)(value % 4)) { }
public Card(int value, CardSuit suite) : this(unchecked((char)value), suite) { }
public Card(byte value, CardSuit suite) : this((char)value, suite) { }
#endregion
#region Card Overrides
public override string ToString()
{
return "Card, " + Name + " Of " + Suit + '(' + Suit.Symbol + ')' + " (" + Symbol + " - " + Number + ')' ;
}
public override bool Equals(object obj)
{
if (obj is Card)
{
Card c = (Card)obj;
return c.Suit == Suit && c.Value == Value;
}
return base.Equals(obj);
}
public override int GetHashCode() { return Value.GetHashCode() ^ Suit.GetHashCode(); }
#endregion
#region Card Operators
public static implicit operator Card(int c) { return new Card(c); }
public static implicit operator int(Card c) { return c.GetHashCode(); }
public static bool operator ==(Card a, Card b) { return a.GetHashCode() == b.GetHashCode(); }
public static bool operator !=(Card a, Card b) { return !(a == b); }
public static bool operator >(Card a, Card b) { return a.Value >= b.Value && a.Suit > b.Suit; }
public static bool operator <(Card a, Card b) { return a.Value <= b.Value && a.Suit < b.Suit; }
#endregion
}
#endregion Card
#endregion
#region Deck Statics
// Override the default order of suits here for other games, see below
public static readonly Deck.CardSuit[] DefaultSuitOrder = new CardSuit[] { CardSuit.Spades, CardSuit.Clubs, CardSuit.Hearts, CardSuit.Diamonds };
public static readonly Card[] Jokers = new Card[] { new Card(0), new Card(1), new Card(2), new Card(3) };
public static bool HasAllCards(Deck d) { foreach (var c in Enumerable.Range(d.HasJokers ? 0 : 4, d.HasJokers ? 56 : 52)) if (!d.Cards.Contains(c)) return false; return true; }
#endregion
#region Deck Properties
public readonly string Manufactuer = "v//";
public List<Card> Cards { get; internal set; }
public bool HasJokers { get; private set; }
public bool Shuffled { get; private set; }
public Card this[int index] { get { return Cards[index]; } private set { Cards[index] = value; } }
public bool this[Card c] { get { return ContainsCard(c); } }
public virtual bool IsLegalDeck { get { return HasJokers ? Cards.Count() == 56 : Cards.Count() == 52 && HasAllCards(); } }
public CardSuit[] SuitOrder { get; private set; }
public int MinValue { get; private set; }
public int MaxValue { get; private set; }
#endregion
#region Constructor
public Deck(bool usesJokers = false, bool shuffle = false, CardSuit[] suitOrder = null, int minValue = 1, int maxValue = 13)
{
try
{
MinValue = minValue;
MaxValue = maxValue;
if (null == suitOrder) SuitOrder = DefaultSuitOrder;
else SuitOrder = suitOrder;
Cards = new List<Card>();
HasJokers = usesJokers;
if (HasJokers) foreach (var c in Enumerable.Range(minValue - 1, MaxValue * SuitOrder.Count() + SuitOrder.Count())) { Card C = c; VerifyCard(C); Cards.Add(C); }
else foreach (Deck.CardSuit s in SuitOrder) { foreach (char c in Enumerable.Range(MinValue, MaxValue)) { Card C = new Card(c, s); VerifyCard(C); Cards.Add(C); } }
if (shuffle) Shuffle(Extensions.Random.Next(Cards.Count % 4), true);
return;
}
catch(Exception e) { throw new DeckException(e.Message, e); }
}
#endregion
#region Deck Methods
internal void VerifyCard(Card C)
{
if (!SuitOrder.Contains(C.Suit)) goto InvalidSuit; if (C.Value < MinValue || C.Value > MaxValue) goto InvalidValue;
return;
InvalidSuit:
throw new CardSuit.CardSuitException("Invalid Suit");
InvalidValue: //Not Yet Implemented
throw new CardSuit.CardSuitException("Invalid Suit");
}
public void Shuffle(int times = 0, bool knuthAlgorithm = false)
{
if (knuthAlgorithm) this.Cards.ShuffleKnuth();
else Extensions.Shuffle(this, times);
Shuffled = true;
}
public List<Card> Take(int amount = 0, bool random = false)
{
var cards = (random ? (Cards.Skip(Extensions.Random.Next(0, Cards.Count() - amount))) : (Cards.Skip(Extensions.Random.Next(0, Cards.Count() - amount))).Take(amount).ToList());
foreach (var c in cards) Cards.Remove(c);
return cards.ToList();
}
public List<Card> TakeRandom(int amount = 0) { return Take(amount, true); }
public virtual bool RemoveCard(Card c) { return Cards.Remove(c); }
public virtual void RemoveCards(bool stopIfNotContained = false, params Card[] s) { foreach (Card c in s) if (!stopIfNotContained && !RemoveCard(c)) break; return; }
public virtual bool ContainsCard(Card c) { return Cards.Contains(c); }
public virtual bool HasAllCards() { return Deck.HasAllCards(this); }
#endregion
#region Deck Overrides
public override string ToString() { return "Deck, " + Cards.Count + " Remaining Cards"; }
public override int GetHashCode() { return Cards.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj is Deck)
{
return ((Deck)obj).GetHashCode() == obj.GetHashCode();
}
return base.Equals(obj);
}
#endregion
#region Deck Operators
public static implicit operator int(Deck d) { return d.GetHashCode(); }
public static bool operator ==(Deck a, Deck b) { return a.GetHashCode() == b.GetHashCode(); }
public static bool operator !=(Deck a, Deck b) { return !(a == b); }
public static Deck operator <<(Deck a, int b) { a.Shuffle(b); return a; }
public static Deck operator >>(Deck a, int b) { a.Shuffle(b, true); return a; }
public static List<Card> operator -(Deck d, int amount) { d.Take(amount, true); return d.Cards; }
public static List<Card> operator +(Deck d, IEnumerable<int> cards) { foreach (int c in cards) d.Cards.Add(c); return d.Cards; }
public static List<Card> operator +(Deck d, int card) { d.Cards.Add(card); return d.Cards; }
public static List<Card> operator +(Deck d, IEnumerable<Card> cards) { d.Cards.AddRange(cards); return d.Cards; }
public static Deck operator -(Deck a, Deck b) { a.Cards.ForEach(c => b.Cards.Remove(c)); return a; }
public static Deck operator +(Deck a, Deck b) { a.Cards.AddRange(b.Cards); return a; }
#endregion
}
public static class Extensions
{
//Cause random leaks
public static readonly Random Random = new Random();
/// <summary>
/// Shuffles a List according to Knuth's Algorithm
/// </summary>
/// <param name="List">The List to shuffle</param>
public static void ShuffleKnuth(this List<CodeProjectHelpProject.Deck.Card> List)
{
for (int i = 1, e = List.Count(); i < e; ++i)
{
int pos = Random.Next(i + 1);
var x = List[i];
List[i] = List[pos];
List[pos] = x;
}
}
public static void Shuffle(this Deck d, int times = 0)
{
do
{
foreach (CodeProjectHelpProject.Deck.CardSuit s in d.SuitOrder)
{
var cards = d.Cards.Where(c => c.Suit != s).ToList();
cards.ForEach(c =>
{
d.Cards.Remove(c);
d.Cards.Insert(c.Value % 4, c);
});
}
} while (--times >= 0);
}
}
}
每个值都可以在派生类(如BlackJackDeck)或每个类(如BlackJackCard)中覆盖......不会比其他类更复杂,就好像不是更优雅和有用......
卡片和卡片组具有唯一的哈希码..
唯一缺少的是让卡片告诉你它原来是否是甲板的一部分:P
您甚至可以在扩展时提供其他值,只需在UnoDeck和UnoCard等情况下进行扩展...您可以将Jokers[(0-3)]
传递给Card构造函数,并且覆盖的值仅适用于您的游戏...
它甚至允许你更改Deck的SuitOrder,这样你来的就可以拥有套装优先权,例如在Bridge vs Preferans中。
像这样使用
var d = new Deck();
Deck.Card c = 0; //Joker Of Spades(0)
c = 1; //Joker Of Clubs (0)
c = 4; //Ace Of Spades (1)
c = 52; //King Of Spades (13)
d.Shuffle();
d.Take(1);
d.TakeRandom(1);
d.Cards.Skip(10).Take(5);