Lisp newbie: deck of cards in Lisp

Discussion of Common Lisp
titanium_geek
Posts: 7
Joined: Mon Feb 01, 2010 7:48 pm

Lisp newbie: deck of cards in Lisp

Post by titanium_geek » Wed Feb 10, 2010 11:10 pm

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!

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Lisp newbie: deck of cards in Lisp

Post by ramarren » Thu Feb 11, 2010 12:31 am

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.

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: Lisp newbie: deck of cards in Lisp

Post by nuntius » Thu Feb 11, 2010 8:39 pm

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))

JamesF
Posts: 98
Joined: Thu Jul 10, 2008 7:14 pm

Re: Lisp newbie: deck of cards in Lisp

Post by JamesF » Thu Feb 11, 2010 10:53 pm

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 :)

titanium_geek
Posts: 7
Joined: Mon Feb 01, 2010 7:48 pm

Re: Lisp newbie: deck of cards in Lisp

Post by titanium_geek » Fri Feb 12, 2010 3:12 am

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!

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Lisp newbie: deck of cards in Lisp

Post by gugamilare » Fri Feb 12, 2010 5:43 am

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 :D

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> 

Paul Donnelly
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: Lisp newbie: deck of cards in Lisp

Post by Paul Donnelly » Sat Feb 13, 2010 2:54 am

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.

titanium_geek
Posts: 7
Joined: Mon Feb 01, 2010 7:48 pm

Re: Lisp newbie: deck of cards in Lisp

Post by titanium_geek » Sun Feb 14, 2010 4:46 am

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

Destruct1
Posts: 20
Joined: Wed Jan 20, 2010 1:40 am

Re: Lisp newbie: deck of cards in Lisp

Post by Destruct1 » Mon Feb 15, 2010 2:00 am

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.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Lisp newbie: deck of cards in Lisp

Post by gugamilare » Mon Feb 15, 2010 11:00 am

Destruct1 wrote: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.
That is what I did above :)

Post Reply