only want 2 numbers

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

Ok, Thank you again for your help. Do you mind if I use that code you posted up as kind of a learning point and possibly in my final product. Not like this is going to be for any purpose other than my own learning, just wanted to make sure you are ok with it. You've been a great help man, I really appreciate it.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

Sure - go nuts. It's nothing groundbreaking, but thanks for asking.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

ok so here's the new version, somewhat OOP... but I get this error saying
Fatal error: Call to undefined function deal() in C:\WEB_ROOT\maybe.php on line 64
yet the function is clearly defined, why would I get that error? oh btw here's the code... that might help eh?

Code: Select all

<?php
class Deck
{
		private $original = array('1D', '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', '10D', 'JD', 'QD', 'KD', '1H', '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', '10H', 'JH', 'QH', 'KH', '1C', '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', '10C', 'JC', 'QC', 'KC', '1S', '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', '10S', 'JS', 'QS', 'KS');
		private $working = array();
		
		public function __construct()
		{
				$this->working = $this->original;
		}
		
		public function deal($number)
		{
				$fcards = array_rand($working, $number);
				foreach($fcards as $card) {
					switch($card)
					{
						case JD:
						echo "Jack of Diamonds <br />";
						break;
						case QD:
						echo "Queen of Diamonds <br />";
						break;
						case KD:
						echo "King of Diamonds <br />";
						break;
						case JH:
						echo "Jack of Hearts <br />";
						break;
						case QH:
						echo "Queen of Hearts <br />";
						break;
						case KH:
						echo "King of Hearts <br />";
						break;
						case JC:
						echo "Jack of Clubs <br />";
						break;
						case QC:
						echo "Queen of Clubs <br />";
						break;
						case KC:
						echo "King of Clubs <br />";
						break;
						case JS:
						echo "Jack of Spades <br />";
						break;
						case QS:
						echo "Queen of Spades <br />";
						break;
						case KS:
						echo "King of Spades <br />";
						break;
						default:
						echo $card;
						break;
					}
					
			}
	}
}
			
?>
<html><head></head><body><h1>You have:</h1><p><?php deal(2); ?></p></body></html>
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

deal() isn't defined. At least in the context in which you call it. You call the function in the global, or top context. The function exists inside a class though, so you need to create an object, then reference the function in that object's context.

Code: Select all

<html><head></head><body><h1>You have:</h1><p><?php $Deck = new Deck; $Deck->deal(2); ?></p></body></html>
Though, if you're going to be deal()ing multiple times, I'd instantiate the new $Deck object at the very beginning, before you start to generate output.

Also, another way to shorten that switch statement:

Code: Select all

foreach($fcards as $card)
{
  $number = substr($card,0,1);
  $suit = substr($card,1,1);

switch($number)
{
  case 'J':
    echo 'Jack of';
    break;
  ...etc
}

switch($suit)
{
   case 'D':
    echo 'Diamonds';
    break;
    ...etc
}
I will caution you against echo()ing from that function though. If you're interested in strictly separating display logic from business logic, the deal() function should only generate the strings, and the code that outputs the page should output those pages. This isn't a tremendous problem for what you've got here, but it's an excellent habit to get into.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

Wonderful idea on the shortening up of the switch statement, thank you for that, I love it!! how would I go about "instantiating" the new $deck at the beginning? kind of like...

Code: Select all

<?php
class Deck
{
		private $original = array('1D', '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', '10D', 'JD', 'QD', 'KD', '1H', '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', '10H', 'JH', 'QH', 'KH', '1C', '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', '10C', 'JC', 'QC', 'KC', '1S', '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', '10S', 'JS', 'QS', 'KS');
		private $working = array();
		
		public function __construct()
		{
				$this->working = $this->original;
		}
		
		public function deal($number)
		{
				$fcards = array_rand($working, $number);
				foreach($fcards as $card) {
					switch($card)
					{
						case JD:
						echo "Jack of Diamonds <br />";
						break;
						case QD:
						echo "Queen of Diamonds <br />";
						break;
						case KD:
						echo "King of Diamonds <br />";
						break;
						case JH:
						echo "Jack of Hearts <br />";
						break;
						case QH:
						echo "Queen of Hearts <br />";
						break;
						case KH:
						echo "King of Hearts <br />";
						break;
						case JC:
						echo "Jack of Clubs <br />";
						break;
						case QC:
						echo "Queen of Clubs <br />";
						break;
						case KC:
						echo "King of Clubs <br />";
						break;
						case JS:
						echo "Jack of Spades <br />";
						break;
						case QS:
						echo "Queen of Spades <br />";
						break;
						case KS:
						echo "King of Spades <br />";
						break;
						default:
						echo $card;
						break;
					}
					
			}
	}
}
$deck = new Deck;			
?>
<html><head></head><body><h1>You have:</h1><p><?php $deck->deal(2); ?></p></body></html>
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

Ya - exactly.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

What's really wierd, that I can't figure out is, when I run that script I do get some errors, which I'll look into but I'm getting full numbers. I.e. if I say $deck->deal(3); i will get... 245033, yet none of those numbers are in the array, how is that possible?
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

First - a couple problems with your deal() function. $working isn't defined. The $working variable has been defined nowhere in the deal() function. If you want to refer to the $working variable in the object scope, you need $this->working. Also, all the cases in your switch() statement need to be quoted or you'll get E_NOTICE errors that the constants are undefined.

Now, as to your problem - array_rand returns keys, not values. Since you're working with guaranteed unique values, you could all array_flip() on $this->working to swap the keys for the values. array_rand() would then return '1D' or '7C' or 'QS', etc.

Also, your echo statement doesn't output any spacing, so all your cards are going to be right against each other like: 1D3CQueen of Diamonds
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

So I would use array_flip($this->working, $number) instead of array_rand($this->working, $number)? or would I run the $fcards = array_rand($this->working, $number) then run array_flip($fcards)? Sorry, but thank you so much man.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

Code: Select all

$myArray = array('blue'=>43,'red'=>22);
$choice = array_rand($myArray,1);
//$choice would be 'blue' or 'red';

$myArray = array_flip($myArray);
//$myArray is now array(43=>'blue',22=>'red');
$choice = array_rand($myArray,1);
//$choice is now '43' or '22'
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

I get it, the array is reading as 0 is 1D so when I'm calling the array it's returning 0 not my stored value of 1D, so then...

Code: Select all

class Deck
{
		private $original = array('1D', '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', '10D', 'JD', 'QD', 'KD', '1H', '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', '10H', 'JH', 'QH', 'KH', '1C', '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', '10C', 'JC', 'QC', 'KC', '1S', '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', '10S', 'JS', 'QS', 'KS');
		private $working = array();
		
		public function __construct()
		{
				$this->working = $this->original;
		}
		
		public function deal($number)
		{
                                                                $fcards = array_flip($this->working);
				$fcard = array_rand($fcards, $number);
				foreach($fcards as $card) {
					switch($card)
					{
						case JD:
						echo "Jack of Diamonds <br />";
						break;
						case QD:
						echo "Queen of Diamonds <br />";
						break;
						case KD:
						echo "King of Diamonds <br />";
						break;
						case JH:
						echo "Jack of Hearts <br />";
						break;
						case QH:
						echo "Queen of Hearts <br />";
						break;
						case KH:
						echo "King of Hearts <br />";
						break;
						case JC:
						echo "Jack of Clubs <br />";
						break;
						case QC:
						echo "Queen of Clubs <br />";
						break;
						case KC:
						echo "King of Clubs <br />";
						break;
						case JS:
						echo "Jack of Spades <br />";
						break;
						case QS:
						echo "Queen of Spades <br />";
						break;
						case KS:
						echo "King of Spades <br />";
						break;
						default:
						echo $card;
						break;
					}
					
			}
	}
}
$Deck = new Deck; 			
?>
<html><head></head><body><h1>You have:</h1><p><?php $Deck->deal(3); ?></p></body></html>
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

Yep
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

ok, here is another attempt, again not sure why it's saying this...
Notice: Undefined variable: face in C:\WEB_ROOT\maybe.php on line 83
and
Notice: Undefined variable: suit in C:\WEB_ROOT\maybe.php on line 83
Here's the script...

Code: Select all

<?php
class Deck
{
		private $original = array('1D', '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', '10D', 'JD', 'QD', 'KD', '1H', '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', '10H', 'JH', 'QH', 'KH', '1C', '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', '10C', 'JC', 'QC', 'KC', '1S', '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', '10S', 'JS', 'QS', 'KS');
		private $working = array();
		
		public function __construct()
		{
				$this->working = $this->original;
		}
		
		public function deal($number)
		{
				$fcard = array_flip($this->working);
				$fcards = array_rand($fcard, $number);
				foreach($fcards as $card) {
						$face = substr($card,0,1);
						$suit = substr($card,1,1);
					switch($face)
					{
						case '1':
							$face = "One of ";
							break;
						case '2':
							$face = "Two of ";
							break;
						case '3':
							$face = "Three of ";
							break;
						case '4':
							$face = "Four of ";
							break;
						case '5':
							$face = "Five of ";
							break;
						case '6':
							$face = "Six of ";
							break;
						case '7':
							$face = "Seven of ";
							break;
						case '8':
							$face = "Eight of ";
							break;
						case '9':
							$face = "Nine of ";
							break;
						case '10':
							$face = "Ten of ";
							break;
						case 'J':
							$face = "Jack of ";
							break;
						case 'Q':
							$face = "Queen of ";
							break;
						case 'K':
							$face = "King of ";
							break;
						}
					switch($suit)
					{
						case 'D':
							$suit = "Diamonds";
							break;
						case 'H':
							$suit = "Hearts";
							break;
						case 'C':
							$suit = "Clubs";
							break;
						case 'S':
							$suit = "Spades";
							break;
						}
			}
	}
}
$Deck = new Deck; 
$yfcards = $Deck->deal(2);
echo "<h1><u>You Have:</u></h1>";
	
echo "<br />" . $yfcards[$face] . " " . $yfcards[$suit];	
?>
I have tried just saying "echo "<br />" . $face . " " . $suit; also but it gives the same error. man I feel retarded, but thank you so much for helping me understand all this. You have the patience of ghandi.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: only want 2 numbers

Post by pickle »

You've had a number of questions about "variable scope" - it would probably help you a bit to do some research on that term.

In this case, $face and $suit are variables local to the scope of the deal() function, and you're trying to reference them from the global scope.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
danwguy
Forum Contributor
Posts: 256
Joined: Wed Nov 17, 2010 1:09 pm
Location: San Diego, CA

Re: only want 2 numbers

Post by danwguy »

So after reading a little, it seems like I could say "global $face, $suit;" then I should be able to echo those two anywhere else on the page or in any included pages right? Or would I have to define them as global each time, like " case 'J': global $face = "Jack of "; break;" and so on.

Ok, so I used global $face, $suit; at the beginning of the function and it works, but it only outputs one card now, regardless of the number I put in to the deal() function, which makes sense because I am defining variables as something now, but how would I go about allowing $face and $suit be different? I have no idea how I would make them an array inside the array, or anything like that. Maybe I should just leave it as echo-ing the values rather than storing them as variables, though that does make it harder to push them across pages. sorry, kind of an outloud though cloud. anyway, any ideas on how to define $face and $suit in the switch statement, yet allow them to be different? I hope that makes sense, I can post the whole script so you can see it and run it and maybe understand a little better if you want.
Last edited by danwguy on Tue Feb 15, 2011 4:23 pm, edited 1 time in total.
Post Reply