Location: PHPKode > scripts > MageSource's CardDeck > magesources-carddeck/includes/CardDeck.php
<?php
//this class needs a true/false value to instanciate.
/*
	Author: Anthony J Clink (hide@address.com)
	
	Quick rundown of the functions. The current game we are using will not be using even half of the avaiable functions in this class.
	This class can return the value of the card, the image of the card, the suit of the card, the color of the card.
	
	The way the class works:
		To draw a card you simply run the drawcard function in the class. What this does is subtract 1 from the selectedIndex. 
		This will run until you are out of cards. When you are out of cards,  no cards will display. (a return value of 'n-i' which stands for no index.)
		Shuffling the deck will reset the selected index to whatever was set (ie jokers or no jokers) and randomize the cardIndex array.
		The cardIndex array holds the string indexes of the cards themselves. Thus this can be parsed into the approprate cardtype. 
		If your game requires you to know the suit or color, simply run the approprate function and it will return as a string; those values.
		
		On object instansiation you can feed a true or false value. true being with jokers, false being without.
		
	The core of the CardDeck is made up of 3 variables. 
		An array of card text IE: 'Ace of Spades' with a key of the card: 'a-s' ($cardText)
		An array of card image paths '/images/a-s.png' with a key of the card: 'a-s' ($cardImage)
		An array of card keys (the array we manipulate in our object) In an unshuffled deck, key index 0 would = 'a-s' ($cardIndex)
		
		These arrays are associated in a manner to allow the programmer to quickly grab deck information. Yes its a memory ineffiecent way to do it; but it keeps track of information well.

	$member functions:
		integer getSelectedIndex($index)  
			//returns the integer index of the requested card (within the cardIndex array)
		void setSelectedIndex($index) 
			sets the current index of the cards. Used to cut the deck or for troubleshooting purposes. DO NOT USE UNLESS YOU ARE DEBUGGING YOUR CODE
		integer getDeckSize(); 
			//gets the size of the deck. (returns 51 or 53 depending on jacks)
		integer getIntegerIndex(string) 
			returns the index of the index of the card in the cardIndex array. (useful for memory maybe?) I have no use for it.
		string getCurrentCard() 
			requests the current card string. Useful if you have already drawn a card, or want to perform operations on the card after you have drawn it.
		string getCardGraphic($index) 
			returns the path of the card graphic. Accepts any string index of a card. EX: getCardGraphic('a-s') returns 'images/a-s.png' (next class revision is going to make this editable on instansiation)
		string getCardName(string) 
			give a card string index ('a-s') and it returns the full name of the card ('Ace of Spades')
		string getCardColor(string) 
			give a card string index ('a-s') and it returns the color of the card ('Black');
		string getCardSuit(string) 
			give a card a string index('a-s') and it returns the suit of the card ('Spades')
		mixed getCardValue(string) 
			give a card string index('a-s) and it returns the value of the card. ('Ace') give the function a string index of ('10-c') and it returns an integer of 10.
		array getAllCardInformation(string)
			give a card string index('a-s) and it returns an array with all relevent card information. card['a-s']['name'] = 'Ace of Spades';
																    card['a-s']['value'] = 'Ace';
																    card['a-s']['suit'] = 'Spades'
																    card['a-s']['color'] = "Black";
		string drawCard() 
			call this command to draw a single card off the top of the deck. Returns the string index of that card. Or you can use the getCurrentCard to retrieve the information after a card has been drawn.
		void shuffleDeck(bool) 
			call this command to reset the deck, and shuffle it. if a true value is given, the function will preserve the current deck layout, and only shuffle as far as you have drawn. Give no paramater to shuffle the remaining cards.
		
*/
	class CardDeck
	{
		protected $cardText = array(); //array to hold the card text
		protected $cardImage = array(); //array to hold the card image
		protected $cardIndex = array(); //array to hold the string indexes of the cards
		protected $deckIndex; //index to establish deck size (51 or 53 depending if jokers are set) used to rebuild the deck, part of the shuffle deck function.
		protected $selectedIndex; //index to find out what card you are on when drawing cards from the deck.
		protected $currentCard; //holds the string index of the current drawn card.
		
		function __construct($checkJokers = false) //this contrsucts the arrays needed for the object to function: It lists the text and image arrays stored as string indexes. It also sets wether you want 
		                                   //jokers or not; and creates an integer indexed array of arrays... makes sense if you read below all the binary images.
		{
			$cardSuits = array("Spades", "Hearts", "Clubs", "Diamonds"); 
			$cardSuitsAbbriv = array("s", "h", "c", "d");
			$namedRanks = array("j"=>"Jack", "q"=>"Queen", "k"=>"King", "a"=>"Ace");
			$namedRankAbbriv = array("j", "q", "k", "a");
			$cardValue;
			
			// $cardIndexIndex = 0;
			
			for($i = 0; $i < 13; $i++) //you have 13 cards a suit, so run this 13 times; and make 4 of each of this index.
			{
				for($suit = 0; $suit < 4; $suit++) //loop to duplicate single cards. Thus giving you 4 cards of each suit, ran 13 times; giving you 52 cards.
				{
					$stringIndex;
					$cardName;
					$thisCard = $i + 1; //set this card to the approprate card text value (there is no 0 card)
					
					if($thisCard == 1) $thisCard = 14; //get rid of the card 1 and set it to accept ace as a value.
					if($thisCard > 10){ //check for anything higher than a 10 and name it as such
						$thisCard = $thisCard - 11;
						$thisCard = $namedRankAbbriv[$thisCard];
					}
					//build string index.
					$stringIndex = $thisCard . '-' . $cardSuitsAbbriv[$suit];
					//build the card name.
					$cardName = $thisCard;
					if(is_string($thisCard)) $cardName = $namedRanks[$thisCard];
					$this->cardText[$stringIndex] = $cardName . " of " . $cardSuits[$suit];
					//build the image URL
					$this->cardImage[$stringIndex] = "images/" . $stringIndex . ".png";
					//build the array of string indexes.
					$this->cardIndex[] = $stringIndex;
				}		
			}
			if($checkJokers == true){ //if checkjokers is true (meaning you want jokers) create the deck and selcted index (53 is 54 cards (include the zero)) and add the jokers to the array.
				$this->deckIndex = 53;
				$this->selectedIndex = 53;
				$this->cardText["joker-b"] = "Black Joker";
				$this->cardText["joker-r"] = "Red Joker";
				$this->cardImage["joker-b"] = "images/joker-b.png";
				$this->cardImage["joker-r"] = "images/joker-r.png";
				$this->cardIndex[52] = "joker-b";
				$this->cardIndex[53] = "joker-r";
			}
			if($checkJokers == false){ //crete the deck and selected index to the decksize 51 due to the zero index
				$this->deckIndex = 51;
				$this->selectedIndex = 51;
			}
		}
		
		function getSelectedIndex() //I use this to display how many cards are left.
		{
			return $this->selectedIndex;
		}
		function setSelectedIndex($id) //in some situations this is nesseary for debugging purposes; 
		                               //or if you are having a hard time with logic, you can force particular instances. 
									   //I recomend avoiding using this as much as possible.
		{
			$this->selectedIndex = $id;
		}
		function setCurrentCard($id) //see above
		{
			$this->currentCard = $this->cardIndex[$id];
		}
		
		function getDeckSize() //shows how big the deck is.
		{
			return $this->deckIndex;
		}
		
		function getCurrentCard() //this function returns the string index of the current selected card.
		{
			return $this->currentCard;
		}
		function getIntegerIndex($index = NULL) //rewrite this function to return the integer index of placement of a string index within the deck itself. (ie, an unshuffled deck, 'a-s' = 0;)
		{                                       //not sure what functionality you would use this for, but I made it avaiable.
			if($index == NULL) $index = $this->currentCard;
			$integerIndex = array_search($index, $this->cardIndex);
			return $integerIndex;
		}
		function getCardGraphic($index = NULL) //gets the card graphic.
		{
			if($index == NULL) $index = $this->currentCard;
			return $this->cardImage[$index];
		}
	
		function getCardName($index = NULL) //pulls the name out of the cardtext array based on the string index.
		{
			if($index == NULL) $index = $this->currentCard;
			return $this->cardText[$index];
		}
		
		function getCardColor($index = NULL) //this finds out the color of the card. Not useful for my purposes, but you may find it decent for your application.
		{
			if($index == NULL) $index = $this->currentCard;
			$array=split("-", $index); //splits the array index so you can correctly identify the suit; thus idenifying the color.
			$suitID=$array[1];
			$suitColor;
			if($suitID == 's' or $suitID == 'c' or $suitID == 'b'){
				$suitColor = "Black";
			}
			else{
				$suitColor = "Red";
			}
			return $suitColor;
		}
		
		function getCardSuit($index = NULL) //same as above, without trying to figure out what color it is.
		{
			if($index == NULL) $index = $this->currentCard; //if given a pramater use the paramater otherwise don't.
			$array=split("-", $index); //split the array so you can utilize the section of it you want.
			$suitType=$array[1]; //split into cardvalue - suit
			$suitName=""; //variable to hold t
			if($suitType=='s') $suitName="Spades";
			if($suitType=='c') $suitName="Clubs";
			if($suitType=='h') $suitName="Hearts";
			if($suitType=='d') $suitName="Diamonds";
			if($suitType=='r') $suitName="Joker";
			if($suitType=='b') $suitName="Joker";
			return $suitName;
		}
		
		function getCardValue($index = NULL) //this is important for pretty much any application. It returns the approrate value of the card A 1 2 3 4 5 6 7 8 9 10 J Q K or JOker.
		{
			if($index == NULL) $index = $this->currentCard;
			$stringIndexArray=split("-", $index);
			$selectedCard = $stringIndexArray[0];
			$cardValue = "";
			if($selectedCard == 'a') $cardValue="Ace";
			if($selectedCard == 'k') $cardValue="King";
			if($selectedCard == 'q') $cardValue="Queen";
			if($selectedCard == 'j') $cardValue="Jack";
			if($selectedCard =='joker') $cardValue="Joker";
			if($cardValue == "") $cardValue = $selectedCard;
			return $cardValue;
		}
		
		function getAllCardInfo($index = NULL)
		{
			if($index == NULL) $index = $this->currentCard;
			$cardInfo = array();
			$cardInfo[$index]['name'] = $this->getCardName($index);
			$cardInfo[$index]['suit'] = $this->getCardSuit($index);
			$cardInfo[$index]['color'] = $this->getCardColor($index);
			$cardInfo[$index]['value'] =  $this->getCardValue($index);
			
			return $cardInfo;
		}
		
		function drawCard() //sets the current card as the current selected index, and drops the index by one. 
		                    //Thus allowing you to step through the deck until you run out of cards. Notice, you draw from the top of the deck down, just like real life.
		{
				if($this->selectedIndex < 0){ //this control ensures that your client can know when you have ran out of cards.
				$this->currentCard = 'n-i'; //this value is what is returned when you have no cards.
				$this->selectedIndex = -1;
			}
			else{
				$this->currentCard = $this->cardIndex[$this->selectedIndex];
				$this->selectedIndex--;
			}
			return $this->currentCard; //returns the string index of the selected card
		}
		
		function shuffleDeck($preserveDeck = false) //just as it sounds. put all the cards back in the deck (by resetting the selectedIndex) and randomize the array.
		{                                           //if a true value is given, it will preserve the deck as is, and shuffle the remaining cards.
			if($preserveDeck == false){
				$this->selectedIndex = $this->deckIndex; //this takes the selectedindex (used to find out how far through the deck you are)
			                                         //and sets it to the deckindex which was created on construct.
				$i = $this->deckIndex; //sets i to the decksize, so that you can ensure every card gets selected at some point.
			}
			else{
				$i = $this->selectedIndex;
			}
			
			while ($i > -1)
			{ //this randomizes the table. It is possible for the same variables to switch back and fourth... but thats true for an actual deck of cards as well.
				$randomIndex = mt_rand(0, $i);
				$tmpStorage = $this->cardIndex[$i];
				$this->cardIndex[$i] = $this->cardIndex[$randomIndex];
				$this->cardIndex[$randomIndex] = $tmpStorage;
				$i--;
			}
		}
	}

?>



Return current item: MageSource's CardDeck