View Single Post
Old 01-07-2007, 09:41 PM   #12 (permalink)
Zippygoose
Math Enthusiast/Badass MC
 
Zippygoose's Avatar
 
Join Date: Jun 2002
Location: Seattle
Posts: 596
-1 Internets
Send a message via AIM to Zippygoose
Apologies for the delay, work was crazy this week.

One thing to note about my solution: My shuffle and cut methods are quite literal. I liked the idea of having a shuffle method that acted like a physical shuffle, meaning the cards become more random as the number of shuffles increase, and vice versa. So before you go blasting me for an inefficient shuffling method, I realize there are much faster computational shuffles

I also opted for an enum of cut types to pass into my cut method rather than overloading the method.

Class is in C#

Code:
using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Security.Cryptography; namespace Cards { public class Deck { private string[] arrSuit = { "Hearts", "Clubs", "Diamonds", "Spades" }; private string[] arrName = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" }; private Stack sDeck = new Stack(); public Deck() { //Reversing the loop would have made this easier, that way I could just have //written tmpCard = arrName, then tmpCard += " of " + iCurrentSuit. This would //have put the cards on the stack in number order. I wanted to get the cards by //suit though, which is how a new deck of cards is ordered (I think) string tmpCard = ""; string tmpSuit = ""; for (int iCurrentSuit = 0; iCurrentSuit < arrSuit.Length; iCurrentSuit++) { tmpSuit = ""; tmpSuit = arrSuit[iCurrentSuit]; for (int iCurrentName = 0; iCurrentName < arrName.Length; iCurrentName++) { tmpCard = arrName[iCurrentName].ToString() + " of " + tmpSuit; //Push this card on the stack sDeck.Push(tmpCard); } } } //Returns the deck as an array //I'm not pushing or popping here because I just want to see the cards //This was for testing only, it populates a listbox in my form (not included) public string[] View() { return sDeck.ToArray(); } //Shuffle the deck literally. This method simulates a standard shuffle: //Cut the cards somewhere around the middle of the deck, //Take the two halves and shuffle them into each other creating a new stack of cards //This is NOT the most efficient computational shuffle by any means, I just wanted //to simulate a real world shuffle, i.e. the more times you shuffle the deck the more //random the cards become. public void LiteralShuffle() { //Turn the stack into a queue. We want to use queues because //a standard shuffle shuffles the bottom cards first and the top cards last string[] arrTmp = sDeck.ToArray(); Queue qDeck = new Queue(); for (int x = arrTmp.Length - 1; x >= 0; x--) { qDeck.Enqueue(arrTmp[x].ToString()); } //Seed Rand Random oRand = new Random(DateTime.Now.Millisecond); //Index of the deck where it is split (added randomness since it isn't constant IRL) int iIndex = oRand.Next(20, 30); //now that we have a queue, cut the deck into 2 queues Queue qHalf = new Queue(); int iNumCount = qDeck.Count - iIndex; for (int j = 0; j < iNumCount; j++) { qHalf.Enqueue(qDeck.Dequeue()); } //Making a "third stack" that will be created from shuffling //the original 2 queues Stack sFinal = new Stack(); int iOddEven = 0; bool bCardsRemain = true; while (bCardsRemain) { //Generating a 0 or a 1 iOddEven = oRand.Next(2); //if 0, put the bottom card on the "left" queue on top of the //shuffled stack if (iOddEven == 0 && qDeck.Count > 0) { sFinal.Push(qDeck.Dequeue()); } //if it isn't 0, put the bottom card in the "right" queue //on top of the stack else if (qHalf.Count > 0) { sFinal.Push(qHalf.Dequeue()); } else if (qDeck.Count == 0 && qHalf.Count == 0) { bCardsRemain = false; } } sDeck = sFinal; } //Type of cut: Totally random, top 20% of deck, middle 20% of deck, bottom 20% of deck public enum CutTypes { Random, Top, Middle, Bottom } public void Cut(CutTypes cType) { //Seed Rand Gen Random oRand = new Random(DateTime.Now.Millisecond); int iIndex = 0; //determine 20% of the deck for cutting purposes //using an int so the decimal is just rounded off int iCutRange = (int)(sDeck.Count * .2); //Determine the user's cutting preference, and generate an appropriate index switch(cType) { case CutTypes.Random: iIndex = oRand.Next(sDeck.Count + 1); break; case CutTypes.Top: iIndex = oRand.Next(0, iCutRange + 1); break; case CutTypes.Middle: iIndex = oRand.Next((sDeck.Count/2) - (iCutRange/2), (sDeck.Count/2) + (iCutRange/2) + 1); break; case CutTypes.Bottom: iIndex = oRand.Next(sDeck.Count - iCutRange, sDeck.Count + 1); break; } string[] arrDeck = sDeck.ToArray(); //Turn the array into a queue Queue qDeck = new Queue(); for (int i = arrDeck.Length - 1; i >= 0; i--) { qDeck.Enqueue(arrDeck[i].ToString()); } //Determine how many cards to move from the bottom of //the deck to the top (this is a cut) int NumCards = (arrDeck.Length - 1) - iIndex; for (int j = 0; j < NumCards; j++) { qDeck.Enqueue(qDeck.Dequeue()); } Stack sFinal = new Stack(); //assign qDeck count to a variable since the count will change in the loop int qCounter = qDeck.Count; for (int y = 0; y < qCounter; y++) { //create the new stack of cards sFinal.Push(qDeck.Dequeue()); } sDeck = sFinal; } public Stack Deal(int iNumCards) { //store the dealt cards to return Stack sDealtCards = new Stack(); for (int i = 0; i < iNumCards; i++) { sDealtCards.Push(sDeck.Pop()); } return sDealtCards; } } }
__________________
Join the FoH stock market game


Last edited by Zippygoose : 01-07-2007 at 09:45 PM.
Zippygoose is offline   Reply With Quote

 
Uberguilds Network