PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Mon Sep 23, 2019 5:19 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Thu Nov 08, 2012 3:05 pm 
Offline
The Ninja Space Mod
User avatar

Joined: Fri Aug 05, 2005 1:53 pm
Posts: 6424
Location: Paradise, CA
Hello Devnet! It's been a long time! I've taken almost a year break from PHP for various reasons (not least of which was a detour into Ruby/Rails and various other technologies), resulting in my being a tad bit rusty. I'm doing a little personal project just to brush up and make sure I still understand PHP's newest features and its SPL. So, a question I have is, what would be the best SPL interface to use in order to create a "deck of cards"? The deck will consist, basically, of an array of "Card" objects. I want to be able to "deal" cards off the top of the deck in a loop (like array_shift), shuffle it, count() it, So something like:

Syntax: [ Download ] [ Hide ]
$deck = new Cards\Deck;
$deck->shuffle();
$players = Game\Hearts\Factory::buildPlayers(); // I haven't actually created any game/player code yet. this is pseudo-code.
// Deal out 13 cards to each player...
while ($deck->hasCards()) {
    foreach ($players as $player) {
        $card = $deck->deal();
        $player->getHand()->addCard($card);
    }
}


I also need to be able to put cards back on the bottom of the deck (like array_push)
Syntax: [ Download ] [ Hide ]
$deck = new Cards\Deck;

// .. snip

$deck->burn(); // takes a card off the top and places it on the bottom
$flop = $deck->deal(3);

// .. or ..
$turn = $deck->deal();
$deck->accept($players[3]->getHand()); // player 3 folds, so his cards go back on bottom

// .. or ..
$deck->accept($discard); // deck gets a player's discard and puts it on bottom


I want to be able to count and treat the deck as an array
Syntax: [ Download ] [ Hide ]
if (count($deck) != 52) {
    throw new Cards\Exception\InvalidDeck('Deck is short of cards');
}

$lastcard = $deck[51];


I want to be able to cut the deck too (at a specific position)
Syntax: [ Download ] [ Hide ]
$deck = new Cards\Deck;
$deck->shuffle();
$deck->cut(15); // Cuts the deck in half at the 15th card, and places the top half under the bottom half


I also want to be able to simply loop through the deck without "dealing" any cards
Syntax: [ Download ] [ Hide ]
foreach ($deck as $card) {
    // do something with $card but dont take it outta the deck
}


So... basically I need the deck to behave similar to an array, but there are all these SPL interfaces and classes like ArrayObject, Countable, and SeekableIterator and I'm not sure which one(s) are most appropriate for my class. What do y'all think?


Top
 Profile  
 
PostPosted: Thu Nov 08, 2012 3:17 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
SplQueue is pretty close but I'm not sure it'll support cutting or shuffling the deck.

Since you have to write your own class anyways, I'd recommend just sticking with an array. array_push/pop/shift/unshift() let you add and remove from both ends, and you can easily shuffle() it. Countable for count() which just wraps a count() on the inner array, while ArrayAccess probably isn't appropriate since you shouldn't be reaching into the middle of the deck. IteratorAggregate gives you the functionality of foreach but you only have to implement one method, getIterator(), which can just return an ArrayIterator on the underlying array (versus Iterator with five methods you have to write from scratch).


Top
 Profile  
 
PostPosted: Thu Nov 08, 2012 3:26 pm 
Offline
The Ninja Space Mod
User avatar

Joined: Fri Aug 05, 2005 1:53 pm
Posts: 6424
Location: Paradise, CA
You make a good point about ArrayAccess. I can't really think of any reason why I'd need to be able to access some mid-deck card. You know, I think what I'll do is move on to other code for now, and as I have need of certain features in the deck, I'll consider which of the above functionality I actually need. The only time I can think of where one would need to grab a card mid-deck is if they were doing a card trick (pick a card, any card), and LOL I don't think I'll be doing many magic tricks with this particular deck.


Top
 Profile  
 
PostPosted: Thu Nov 08, 2012 3:32 pm 
Offline
The Ninja Space Mod
User avatar

Joined: Fri Aug 05, 2005 1:53 pm
Posts: 6424
Location: Paradise, CA
I should mention, however, that I'll probably be creating a class called "Hand" which will need to have much of the same functionality as "Deck". It will need to be able to have cards added, removed, and I WILL need to be able to access its cards individually for sure. But I think I'll need to be able to do something like $hand['clubs5'] or something. I'm not sure yet. I'm definitely going to need to build the code that uses these classes first so I know how they are to be used...


Top
 Profile  
 
PostPosted: Fri Nov 09, 2012 4:04 pm 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13592
Location: New York, NY, US
Hey Luke good to see you back.

I think ArrayObject is probably what you want. It includes all the array stuff in a single class (i.e., IteratorAggregate, Traversable, ArrayAccess, Serializable, Countable). That will give you a clean OO base for your deck if you don't just want to use an internal $cards property and do the array stuff directly yourself plus Iterator.

_________________
(#10850)


Top
 Profile  
 
PostPosted: Wed Dec 18, 2013 3:27 pm 
Offline
Moderator
User avatar

Joined: Mon Nov 03, 2003 7:13 pm
Posts: 5978
Location: Odessa, Ukraine


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group