Playing cards: Difference between revisions
Content added Content deleted
Underscore (talk | contribs) (→{{header|Perl 6}}: "multi prefix:<~>" → "method Str". This change makes it possible to privatize the instance variables, so I did.) |
m (Fixed lang tags.) |
||
Line 4: | Line 4: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Here is the package specification for a deck of playing cards. |
Here is the package specification for a deck of playing cards. |
||
<lang ada> |
<lang ada>package Playing_Cards is |
||
package Playing_Cards is |
|||
pragma Elaborate_Body(Playing_Cards); |
pragma Elaborate_Body(Playing_Cards); |
||
Line 31: | Line 30: | ||
Deck_Offsets : Deck_Reference; |
Deck_Offsets : Deck_Reference; |
||
end record; |
end record; |
||
end Playing_Cards; |
end Playing_Cards;</lang> |
||
</lang> |
|||
Here is the package body for that same playing card package. This implementation stores one array of cards in sorted order. Each deck contains an array of indices into that one array of cards. Shuffling the deck actually results in randomizing the order of those indices into the array of cards. This approach maximizes shuffling efficiency by only exchanging indices. It also maximizes memory efficiency since an array of cards requires more memory than an array of indices. |
Here is the package body for that same playing card package. This implementation stores one array of cards in sorted order. Each deck contains an array of indices into that one array of cards. Shuffling the deck actually results in randomizing the order of those indices into the array of cards. This approach maximizes shuffling efficiency by only exchanging indices. It also maximizes memory efficiency since an array of cards requires more memory than an array of indices. |
||
<lang ada> |
<lang ada>with Ada.Numerics.Discrete_Random; |
||
with Ada.Numerics.Discrete_Random; |
|||
With Ada.Text_IO; |
With Ada.Text_IO; |
||
Line 132: | Line 129: | ||
end loop; |
end loop; |
||
end loop; |
end loop; |
||
end Playing_Cards; |
end Playing_Cards;</lang> |
||
</lang> |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 146: | Line 142: | ||
* [http://www.csail.mit.edu/timeline/timeline.php?query=event&id=93 LOC was essential; Algol 68's REF was a mistake.] |
* [http://www.csail.mit.edu/timeline/timeline.php?query=event&id=93 LOC was essential; Algol 68's REF was a mistake.] |
||
<lang |
<lang algol68>MODE CARD = STRUCT(STRING pip, suit); # instance attributes # |
||
# class members & attributes # |
# class members & attributes # |
||
Line 693: | Line 689: | ||
(sort list #'(lambda (x y) |
(sort list #'(lambda (x y) |
||
(declare (ignore x y)) |
(declare (ignore x y)) |
||
(zerop (random 2))))) |
(zerop (random 2)))))</lang> |
||
</lang> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
Line 906: | Line 901: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
{{works with|GNU Forth}} |
{{works with|GNU Forth}} |
||
<lang forth>require random.fs \ RANDOM ( n -- 0..n-1 ) is called CHOOSE in other Forths |
|||
create pips s" A23456789TJQK" mem, |
|||
create suits s" DHCS" mem, \ diamonds, hearts, clubs, spades |
|||
: .card ( c -- ) |
|||
13 /mod swap |
|||
pips + c@ emit |
|||
suits + c@ emit ; |
|||
create deck 52 allot |
|||
variable dealt |
|||
: new-deck |
|||
52 0 do i deck i + c! loop 0 dealt ! ; |
|||
: .deck |
|||
52 dealt @ ?do deck i + c@ .card space loop cr ; |
|||
: shuffle |
|||
51 0 do |
|||
52 i - random i + ( rand-index ) deck + |
|||
deck i + c@ over c@ |
|||
deck i + c! swap c! |
|||
loop ; |
|||
: cards-left ( -- n ) 52 dealt @ - ; |
|||
: deal-card ( -- c ) |
|||
cards-left 0= abort" Deck empty!" |
|||
deck dealt @ + c@ 1 dealt +! ; |
|||
: .hand ( n -- ) |
|||
0 do deal-card .card space loop cr ; |
|||
new-deck shuffle .deck |
|||
5 .hand |
|||
cards-left . \ 47</lang> |
|||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
<lang fortran> |
<lang fortran>MODULE Cards |
||
IMPLICIT NONE |
|||
TYPE Card |
|||
CHARACTER(5) :: value |
|||
CHARACTER(8) :: suit |
|||
END TYPE Card |
|||
TYPE(Card) :: deck(52), hand(52) |
|||
TYPE(Card) :: temp |
|||
CHARACTER(5) :: pip(13) = (/"Two ", "Three", "Four ", "Five ", "Six ", "Seven", "Eight", "Nine ", "Ten ", & |
|||
"Jack ", "Queen", "King ", "Ace "/) |
|||
CHARACTER(8) :: suits(4) = (/"Clubs ", "Diamonds", "Hearts ", "Spades "/) |
|||
INTEGER :: i, j, n, rand, dealt = 0 |
|||
REAL :: x |
|||
CONTAINS |
|||
SUBROUTINE Init_deck |
|||
IMPLICIT NONE |
|||
! Create deck |
|||
DO i = 1, 4 |
|||
DO j = 1, 13 |
|||
deck((i-1)*13+j) = Card(pip(j), suits(i)) |
|||
END DO |
|||
END DO |
|||
END SUBROUTINE Init_deck |
|||
SUBROUTINE Shuffle_deck |
|||
TYPE Card |
|||
! Shuffle deck using Fisher-Yates algorithm |
|||
CHARACTER(5) :: value |
|||
DO i = 52-dealt, 1, -1 |
|||
CHARACTER(8) :: suit |
|||
CALL RANDOM_NUMBER(x) |
|||
END TYPE Card |
|||
rand = INT(x * i) + 1 |
|||
temp = deck(rand) |
|||
deck(rand) = deck(i) |
|||
deck(i) = temp |
|||
END DO |
|||
END SUBROUTINE Shuffle_deck |
|||
SUBROUTINE Deal_hand(number) |
|||
! Deal from deck to hand |
|||
INTEGER :: number |
|||
DO i = 1, number |
|||
hand(i) = deck(dealt+1) |
|||
dealt = dealt + 1 |
|||
END DO |
|||
END SUBROUTINE |
|||
SUBROUTINE Print_hand |
|||
! Print cards in hand |
|||
DO i = 1, dealt |
|||
WRITE (*, "(3A)") TRIM(deck(i)%value), " of ", TRIM(deck(i)%suit) |
|||
END DO |
|||
WRITE(*,*) |
|||
END SUBROUTINE Print_hand |
|||
SUBROUTINE Print_deck |
|||
TYPE(Card) :: deck(52), hand(52) |
|||
! Print cards in deck |
|||
TYPE(Card) :: temp |
|||
DO i = dealt+1, 52 |
|||
WRITE (*, "(3A)") TRIM(deck(i)%value), " of ", TRIM(deck(i)%suit) |
|||
END DO |
|||
WRITE(*,*) |
|||
END SUBROUTINE Print_deck |
|||
END MODULE Cards</lang> |
|||
Example use: |
|||
<lang fortran>PROGRAM Playing_Cards |
|||
USE Cards |
|||
CHARACTER(5) :: pip(13) = (/"Two ", "Three", "Four ", "Five ", "Six ", "Seven", "Eight", "Nine ", "Ten ", & |
|||
"Jack ", "Queen", "King ", "Ace "/) |
|||
CHARACTER(8) :: suits(4) = (/"Clubs ", "Diamonds", "Hearts ", "Spades "/) |
|||
INTEGER :: i, j, n, rand, dealt = 0 |
|||
REAL :: x |
|||
CALL Init_deck |
|||
CONTAINS |
|||
CALL Shuffle_deck |
|||
CALL Deal_hand(5) |
|||
CALL Print_hand |
|||
CALL Print_deck |
|||
END PROGRAM</lang> |
|||
SUBROUTINE Init_deck |
|||
! Create deck |
|||
DO i = 1, 4 |
|||
DO j = 1, 13 |
|||
deck((i-1)*13+j) = Card(pip(j), suits(i)) |
|||
END DO |
|||
END DO |
|||
END SUBROUTINE Init_deck |
|||
SUBROUTINE Shuffle_deck |
|||
! Shuffle deck using Fisher-Yates algorithm |
|||
DO i = 52-dealt, 1, -1 |
|||
CALL RANDOM_NUMBER(x) |
|||
rand = INT(x * i) + 1 |
|||
temp = deck(rand) |
|||
deck(rand) = deck(i) |
|||
deck(i) = temp |
|||
END DO |
|||
END SUBROUTINE Shuffle_deck |
|||
SUBROUTINE Deal_hand(number) |
|||
! Deal from deck to hand |
|||
INTEGER :: number |
|||
DO i = 1, number |
|||
hand(i) = deck(dealt+1) |
|||
dealt = dealt + 1 |
|||
END DO |
|||
END SUBROUTINE |
|||
SUBROUTINE Print_hand |
|||
! Print cards in hand |
|||
DO i = 1, dealt |
|||
WRITE (*, "(3A)") TRIM(deck(i)%value), " of ", TRIM(deck(i)%suit) |
|||
END DO |
|||
WRITE(*,*) |
|||
END SUBROUTINE Print_hand |
|||
SUBROUTINE Print_deck |
|||
! Print cards in deck |
|||
DO i = dealt+1, 52 |
|||
WRITE (*, "(3A)") TRIM(deck(i)%value), " of ", TRIM(deck(i)%suit) |
|||
END DO |
|||
WRITE(*,*) |
|||
END SUBROUTINE Print_deck |
|||
END MODULE Cards</lang> |
|||
Example use: |
|||
<lang fortran> PROGRAM Playing_Cards |
|||
USE Cards |
|||
CALL Init_deck |
|||
CALL Shuffle_deck |
|||
CALL Deal_hand(5) |
|||
CALL Print_hand |
|||
CALL Print_deck |
|||
END PROGRAM</lang> |
|||
This creates a new deck, shuffles it, deals five cards to hand, prints the cards in hand and then prints the cards remaining in the deck. |
This creates a new deck, shuffles it, deals five cards to hand, prints the cards in hand and then prints the cards remaining in the deck. |
||
Line 1,024: | Line 1,019: | ||
Straightforward implementation with explicit names for pips and suits. A deck is just a list of cards. Dealing consists of splitting off cards from the beginning of the list by the usual pattern matching (not shown). Printing is automatic. Purely functional shuffling is a bit tricky, so here we just do the naive quadratic version. This also works for other than full decks. |
Straightforward implementation with explicit names for pips and suits. A deck is just a list of cards. Dealing consists of splitting off cards from the beginning of the list by the usual pattern matching (not shown). Printing is automatic. Purely functional shuffling is a bit tricky, so here we just do the naive quadratic version. This also works for other than full decks. |
||
<lang haskell>import System.Random |
|||
<pre> |
|||
import System.Random |
|||
data Pip = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | |
data Pip = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | |
||
Line 1,051: | Line 1,045: | ||
shuffle' g [] _ ys = ys |
shuffle' g [] _ ys = ys |
||
shuffle' g (x:xs) n ys = shuffle' g' xs (n+1) (insertAt k x ys) where |
shuffle' g (x:xs) n ys = shuffle' g' xs (n+1) (insertAt k x ys) where |
||
(k,g') = randomR (0,n) g |
(k,g') = randomR (0,n) g</lang> |
||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
<lang j>Note 'playingcards.ijs' |
|||
This is a class script. |
|||
Multiple decks may be used, one for each instance of this class. |
|||
) |
|||
coclass 'rcpc' NB. Rosetta Code playing cards class |
|||
create=: 3 : 0 |
|||
N0=: > ;:'Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King' |
|||
N1=: > ;:'Spades Hearts Diamonds Clubs' |
|||
DeckPrototype=: |. ,/(i.#N0),."1 0 i.#N1 |
|||
sayCards=: ((N0{~{.),' of ',(N1{~{:))"1 |
|||
startNewDeck<nowiki>''</nowiki> |
|||
) |
|||
destroy=: codestroy |
|||
startNewDeck=: 3 : 0 |
|||
1: TheDeck=: DeckPrototype |
|||
) |
|||
shuffle=: 3 : 0 |
|||
1: TheDeck=: TheDeck {~ ?~ # TheDeck |
|||
) |
|||
dealCards=: 3 : 0 |
|||
{. 1 dealCards y |
|||
: |
|||
assert. (# TheDeck) >: ToBeDealt=. x*y |
|||
CardsOffTop=. ToBeDealt {. TheDeck |
|||
TheDeck =: ToBeDealt }. TheDeck |
|||
(1 0 2)|:(y,x)$ CardsOffTop |
|||
) |
|||
Note 'dealCards' |
|||
Left parameter (x) is number of players, with default to one. |
|||
Right parameter (y) is number of cards to be dealt to each player. |
|||
Used monadically, the player-axis is omitted from output. |
|||
) |
|||
pcc=: 3 : 0 NB. "Print" current contents of the deck. |
|||
sayCards TheDeck |
|||
)</lang> |
|||
) |
|||
Example use: |
Example use: |
||
load 'coutil' |
<lang j> load 'coutil' |
||
load 'c:\documents and settings\user_name\j602-user\playingcards.ijs' |
|||
pc=: <nowiki>''</nowiki> conew 'rcpc' |
|||
$TheDeck__pc |
|||
52 2 |
|||
shuffle__pc<nowiki>''</nowiki> |
|||
1 |
|||
sayCards__pc 2 dealCards__pc 5 NB. deal two hands of five cards |
|||
Nine of Hearts |
|||
Three of Clubs |
|||
Seven of Clubs |
|||
Ten of Hearts |
|||
Three of Diamonds |
|||
Seven of Diamonds |
|||
Nine of Spades |
|||
King of Diamonds |
|||
Queen of Hearts |
|||
Six of Clubs |
|||
$TheDeck__pc NB. deck size has been reduced by the ten cards dealt |
|||
42 2 |
|||
destroy__pc <nowiki>''</nowiki> |
|||
1</lang> |
|||
1 |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 1,170: | Line 1,163: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
<lang javascript> |
<lang javascript>function Card(pip, suit) { |
||
function Card(pip, suit) { |
|||
this.pip = pip; |
this.pip = pip; |
||
this.suit = suit; |
this.suit = suit; |
||
Line 1,201: | Line 1,193: | ||
return this.deck.shift(); |
return this.deck.shift(); |
||
}; |
}; |
||
}</lang> |
|||
} |
|||
</lang> |
|||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
{{works with|UCB Logo}} |
{{works with|UCB Logo}} |
||
<lang logo> |
<lang logo>make "suits {Diamonds Hearts Clubs Spades} |
||
make "suits {Diamonds Hearts Clubs Spades} |
|||
make "pips {Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King} |
make "pips {Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King} |
||
Line 1,239: | Line 1,229: | ||
new.deck |
new.deck |
||
shuffle.deck |
shuffle.deck |
||
repeat 5 [deal.card] |
repeat 5 [deal.card]</lang> |
||
</lang> |
|||
=={{header|M4}}== |
=={{header|M4}}== |
||
<lang M4> |
<lang M4>define(`randSeed',141592653)dnl |
||
define(`randSeed',141592653)dnl |
|||
define(`setRand', |
define(`setRand', |
||
`define(`randSeed',ifelse(eval($1<10000),1,`eval(20000-$1)',`$1'))')dnl |
`define(`randSeed',ifelse(eval($1<10000),1,`eval(20000-$1)',`$1'))')dnl |
||
Line 1,283: | Line 1,271: | ||
deal deal(`b') |
deal deal(`b') |
||
deal deal(`b') |
deal deal(`b') |
||
show(`b') |
show(`b')</lang> |
||
</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 1,426: | Line 1,413: | ||
def deal(self): |
def deal(self): |
||
self.shuffle() # Can't tell what is next from self.deck |
self.shuffle() # Can't tell what is next from self.deck |
||
return self.deck.pop(0) |
return self.deck.pop(0)</lang> |
||
</lang> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
<lang R>pips <- c("2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace") |
|||
<lang R> |
|||
pips <- c("2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace") |
|||
suit <- c("Clubs", "Diamonds", "Hearts", "Spades") |
suit <- c("Clubs", "Diamonds", "Hearts", "Spades") |
||
# Create a deck |
# Create a deck |
||
Line 1,455: | Line 1,440: | ||
deck <- deal(deck) |
deck <- deal(deck) |
||
# While no-one is looking, sneakily deal a card from the bottom of the pack |
# While no-one is looking, sneakily deal a card from the bottom of the pack |
||
deck <- deal(deck, FALSE) |
deck <- deal(deck, FALSE)</lang> |
||
</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 1,702: | Line 1,686: | ||
Each users hand is another edit buffer. |
Each users hand is another edit buffer. |
||
There is no need for any routines to display the deck or a hand, since each of them is displayed in an edit window. |
There is no need for any routines to display the deck or a hand, since each of them is displayed in an edit window. |
||
<lang vedit> |
<lang vedit>// Playing Cards, main program |
||
// Playing Cards, main program |
|||
Call("CREATE_DECK") |
Call("CREATE_DECK") |
||
Line 1,785: | Line 1,768: | ||
Buf_Switch(#11) // players hand |
Buf_Switch(#11) // players hand |
||
Reg_ins(9) // insert the cards here |
Reg_ins(9) // insert the cards here |
||
Return |
Return</lang> |
||
</lang> |