Page 1 of 2
Lisp newbie: deck of cards in Lisp
Posted: Wed Feb 10, 2010 11:10 pm
by titanium_geek
Hi everyone, I'm learning Lisp this year. I'm trying to learn it by writing a simple card game ( with the possibility of writing some AI to help me prepare for an AI course next semester.)
So, I'm very new to lisp and really don't have much idea what to do! I come from a java background so think in "things" but I don't want to write java in Lisp.
How do I go about making a deck of cards in lisp?
Thanks!
Re: Lisp newbie: deck of cards in Lisp
Posted: Thu Feb 11, 2010 12:31 am
by ramarren
That is a very general question. Anyway, in case you had any misconceptions, Common Lisp is a multi-paradigm language, which include object oriented programming. It is just perhaps more "verb" centered, but there are classes and objects and things. You should probably read most, if you haven't already, of
Practical Common Lisp before worrying about the particulars of your problem.
That said, the question should be not "how do I make a deck of cards", but what do you want to do with it? Representation of data should be chosen only after the protocol of using that data is chosen, and should be optimized for that use case. Not that there are that many possible representations of a deck of cards... a vector of symbols is the most likely simplest case.
Re: Lisp newbie: deck of cards in Lisp
Posted: Thu Feb 11, 2010 8:39 pm
by nuntius
titanium_geek wrote:How do I go about making a deck of cards in lisp?
In a room of N CL programmers, I would expect to get O(N*(N+1)/2) approaches.
Here's one.
Code: Select all
(defun make-deck ()
(let ((deck (make-array '(52)))
(index 0))
(dolist (suite '(:spades :hearts :diamonds :clubs))
(loop for number from 2 upto 10
do (setf (aref deck index) (cons number suite)
index (1+ index)))
(dolist (face '(:jack :queen :king :ace))
(setf (aref deck index) (cons face suite)
index (1+ index))))
deck))
Re: Lisp newbie: deck of cards in Lisp
Posted: Thu Feb 11, 2010 10:53 pm
by JamesF
titanium_geek wrote:I don't want to write java in Lisp.

Excellent!
Prepare to have your head turned around a bit when you get into CLOS (the Common Lisp Object System), because it's a total inversion from the Java approach.
titanium_geek wrote:How do I go about making a deck of cards in lisp?
Ramarren's question is probably the most apt: what do you want to do with the deck? This isn't a facetious question; it's useful for guiding you to the right implementation. At least, it'll guide you to a good starting implementation; one of the nice things about CL is how easy it is to re-prototype things.
Y'see, you could start by describing the cards as a bunch of lists contained within a list, define a few functions to operate on them, move them to a vector, turn them into objects, turn some of the functions into methods that are specialised on those objects, then move them back to a list because it's easier to shuffle them that way, then...
Personally, I'd probably start by defining them as classes with
suit and
rank slots, then think about what kind of operations I want to perform on them. Or maybe create a 4x13 array, and store state information in the resulting cells.
It's, um, an almost embarrassingly versatile little language you've started playing with, here

Re: Lisp newbie: deck of cards in Lisp
Posted: Fri Feb 12, 2010 3:12 am
by titanium_geek
I guess I'm thinking too real world (like java).
I'm really hesitant about posting the whole problem because I have had a bad experience before where someone wrote the whole code for me, said "here" and killed all the joy in solving the problem. (I haven't learnt to learn well from code.)
So, no one write this for me!
I want to have a deck of cards, then deal out 5 cards to 4 players. You can't see your cards but you can see the other player's cards (the game is called reverse go fish) any pairs in your hand are taken out automatically as they appear. You take turns in asking: "do I have any x card" (you must ask something that you can see, obviously,) and if you do have that card, you get that added to your pairs pile. As you go you make sure you maintain 5 cards in your hands- this would be easy to automate.
The winner is the one with the most pairs at the end of the game. (a scoring system could also be used- correct guess/total guess, or something)
In the future I'd like to mess around with simple computer AI for this game as it's fairly simple, on the most basic level just guess something you can see.
Thanks!
Re: Lisp newbie: deck of cards in Lisp
Posted: Fri Feb 12, 2010 5:43 am
by gugamilare
nuntius wrote:
Code: Select all
(defun make-deck ()
(let ((deck (make-array '(52)))
(index 0))
(dolist (suite '(:spades :hearts :diamonds :clubs))
(loop for number from 2 upto 10
do (setf (aref deck index) (cons number suite)
index (1+ index)))
(dolist (face '(:jack :queen :king :ace))
(setf (aref deck index) (cons face suite)
index (1+ index))))
deck))
Fast hacking? Sounds fun
Code: Select all
(defun shuffle (deck)
(sort (copy-sequence 'vector deck)
#'(lambda (x y)
(declare (ignore x y))
(zerop (random 2)))))
Code: Select all
cl-user> (make-deck)
#((2 . :spades) (3 . :spades) (4 . :spades) (5 . :spades) (6 . :spades)
(7 . :spades) (8 . :spades) (9 . :spades) (10 . :spades)
(:jack . :spades) (:queen . :spades) (:king . :spades) (:ace . :spades)
(2 . :hearts) (3 . :hearts) (4 . :hearts) (5 . :hearts) (6 . :hearts)
(7 . :hearts) (8 . :hearts) (9 . :hearts) (10 . :hearts)
(:jack . :hearts) (:queen . :hearts) (:king . :hearts) (:ace . :hearts)
(2 . :diamonds) (3 . :diamonds) (4 . :diamonds) (5 . :diamonds)
(6 . :diamonds) (7 . :diamonds) (8 . :diamonds) (9 . :diamonds)
(10 . :diamonds) (:jack . :diamonds) (:queen . :diamonds)
(:king . :diamonds) (:ace . :diamonds) (2 . :clubs) (3 . :clubs)
(4 . :clubs) (5 . :clubs) (6 . :clubs) (7 . :clubs) (8 . :clubs)
(9 . :clubs) (10 . :clubs) (:jack . :clubs) (:queen . :clubs)
(:king . :clubs) (:ace . :clubs))
cl-user> (shuffle *)
#((7 . :hearts) (6 . :spades) (8 . :diamonds) (5 . :clubs) (9 . :diamonds)
(10 . :spades) (10 . :diamonds) (4 . :diamonds) (9 . :spades)
(8 . :hearts) (:king . :clubs) (:ace . :diamonds) (5 . :diamonds)
(9 . :hearts) (2 . :clubs) (4 . :clubs) (6 . :hearts) (2 . :hearts)
(10 . :hearts) (:king . :hearts) (5 . :hearts) (10 . :clubs)
(:queen . :hearts) (7 . :diamonds) (:ace . :clubs) (8 . :clubs)
(3 . :diamonds) (3 . :clubs) (:king . :diamonds) (4 . :hearts)
(:queen . :diamonds) (4 . :spades) (3 . :hearts) (:queen . :clubs)
(:jack . :diamonds) (3 . :spades) (6 . :diamonds) (2 . :spades)
(:queen . :spades) (7 . :spades) (:ace . :spades) (:jack . :spades)
(6 . :clubs) (7 . :clubs) (:jack . :hearts) (5 . :spades) (8 . :spades)
(:jack . :clubs) (9 . :clubs) (:king . :spades) (:ace . :hearts)
(2 . :diamonds))
cl-user>
Re: Lisp newbie: deck of cards in Lisp
Posted: Sat Feb 13, 2010 2:54 am
by Paul Donnelly
titanium_geek wrote:I guess I'm thinking too real world (like java).
Probably a mistake in Java too.
I don't think it much matters what representation you choose for this, although you'll probably be happier if you store the rank in a form that can be compared without a lot of fuss. The cons cell representation that Nuntius chose would be simple to work with, although for Go Fish it's not even necessary to store the suit unless you think they add flavor. A game this simple, I would just make the list: '(1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 'jack 'jack 'jack 'jack 'queen 'queen 'queen 'queen 'king 'king 'king 'king 'ace 'ace 'ace 'ace). I would make a function to generate it, although I can't justify that having just typed it here. Then I could just run through the game, writing a function to perform each needed step (shuffle, deal cards, move cards from hand to hand, and so on.
Re: Lisp newbie: deck of cards in Lisp
Posted: Sun Feb 14, 2010 4:46 am
by titanium_geek
Good point about just number comparing being necessary, but I guess I'd like to write a proper gui for this eventually, so starting with a proper deck would be handy.
Thanks everyone, I can now see the next steps!
TG
Re: Lisp newbie: deck of cards in Lisp
Posted: Mon Feb 15, 2010 2:00 am
by Destruct1
Here is a basic framework (/ snippet of code):
http://rosettacode.org/wiki/Playing_cards#Common_Lisp
What I find a neat trick for shuffling is using a sort applicative operator with
a random function as key.
Re: Lisp newbie: deck of cards in Lisp
Posted: Mon Feb 15, 2010 11:00 am
by gugamilare
That is what I did above
