Deal cards for FreeCell

From Rosetta Code
Jump to: navigation, search
Task
Deal cards for FreeCell
You are encouraged to solve this task according to the task description, using any language you may know.

Free Cell is the solitaire card game that Paul Alfille introduced to the PLATO system in 1978. Jim Horne, at Microsoft, changed the name to FreeCell and reimplemented the game for DOS, then Windows. This version introduced 32000 numbered deals. (The FreeCell FAQ tells this history.)

As the game became popular, Jim Horne disclosed the algorithm, and other implementations of FreeCell began to reproduce the Microsoft deals. These deals are numbered from 1 to 32000. Newer versions from Microsoft have 1 million deals, numbered from 1 to 1000000; some implementations allow numbers outside that range.

The algorithm uses this linear congruential generator from Microsoft C:

The algorithm follows:

  1. Seed the RNG with the number of the deal.
  2. Create an array of 52 cards: Ace of Clubs, Ace of Diamonds, Ace of Hearts, Ace of Spades, 2 of Clubs, 2 of Diamonds, and so on through the ranks: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King. The array indexes are 0 to 51, with Ace of Clubs at 0, and King of Spades at 51.
  3. Until the array is empty:
    • Choose a random card at indexnext random number (mod array length).
    • Swap this random card with the last card of the array.
    • Remove this random card from the array. (Array length goes down by 1.)
    • Deal this random card.
  4. Deal all 52 cards, face up, across 8 columns. The first 8 cards go in 8 columns, the next 8 cards go on the first 8 cards, and so on.
Order to deal cards Game #1 Game #617
 1  2  3  4  5  6  7  8
 9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
2S KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H
7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

Deals can also be checked against FreeCell solutions to 1000000 games. (Summon a video solution, and it displays the initial deal.)

Write a program to take a deal number and deal cards in the same order as this algorithm. The program may display the cards with ASCII, with Unicode, by drawing graphics, or any other way.

Contents

[edit] Ada

with Ada.Text_IO; use Ada.Text_IO;
procedure FreeCell is
type State is mod 2**31;
type Deck is array (0..51) of String(1..2);
 
package Random is
procedure Init(Seed: State);
function Rand return State;
end Random;
package body Random is
S : State := State'First;
procedure Init(Seed: State) is begin S := Seed; end Init;
function Rand return State is begin
S := S * 214013 + 2531011; return S / 2**16;
end Rand;
end Random;
 
procedure Deal (num : State) is
thedeck : Deck; pick : State;
Chars : constant String := "A23456789TJQKCDHS";
begin
for i in thedeck'Range loop
thedeck(i):= Chars(i/4+1) & Chars(i mod 4 + 14);
end loop;
Random.Init(num);
for i in 0..51 loop
pick := Random.Rand mod State(52-i);
Put(thedeck(Natural(pick))&' ');
if (i+1) mod 8 = 0 then New_Line; end if;
thedeck(Natural(pick)) := thedeck(51-i);
end loop; New_Line;
end Deal;
 
begin
Deal(1);
New_Line;
Deal(617);
end FreeCell;
Output:
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
2S KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H

7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] AutoHotkey

FreeCell(num){
cards := "A23456789TJQK", suits := "♣♦♥♠", card := [], Counter := 0
loop, parse, cards
{
ThisCard := A_LoopField
loop, parse, suits
Card[Counter++] := ThisCard . A_LoopField
}
loop, 52
{
a := MS(num)
num:=a[1]
MyCardNo := mod(a[2],53-A_Index)
MyCard := Card[MyCardNo]
Card[MyCardNo] := Card[52-A_Index]
Card.Remove(52-A_Index)
Res .= MyCard (Mod(A_Index,8)?" ":"`n")
}
return Res
}
MS(Seed) {
Seed := Mod(214013 * Seed + 2531011, 2147483648)
return, [Seed, Seed // 65536]
}

MS() found at http://rosettacode.org/wiki/Linear_congruential_generator#AutoHotkey

Examples:
Gui, font, s12, Courier
Gui, add, edit, w320 r17 -VScroll, % "Game# 1`n" FreeCell(1) "`n`nGame#617`n" FreeCell(617)
Gui, show
return
 
GuiClose:
GuiEscape:
ExitApp
return
Outputs:
Game# 1
J♦  2♦  9♥  J♣  5♦  7♥  7♣  5♥
K♦  K♣  9♠  5♠  A♦  Q♣  K♥  3♥
2♠  K♠  9♦  Q♦  J♠  A♠  A♥  3♣
4♣  5♣  T♠  Q♥  4♥  A♣  4♦  7♠
3♠  T♦  4♠  T♥  8♥  2♣  J♥  7♦
6♦  8♠  8♦  Q♠  6♣  3♦  8♣  T♣
6♠  9♣  2♥  6♥  

Game#617
7♦  A♦  5♣  3♠  5♠  8♣  2♦  A♥
T♦  7♠  Q♦  A♣  6♦  8♥  A♠  K♥
T♥  Q♣  3♥  9♦  6♠  8♦  3♦  T♣
K♦  5♥  9♠  3♣  8♠  7♥  4♦  J♠
4♣  Q♠  9♣  9♥  7♣  6♥  2♣  2♠
4♠  T♠  2♥  5♦  J♣  6♣  J♥  Q♥
J♦  K♠  K♣  4♥  

[edit] BBC BASIC

      *FLOAT 64
 
hand% = 617
 
REM Initialise card library:
SYS "LoadLibrary", "CARDS.DLL" TO cards%
IF cards% = 0 ERROR 100, "No CARDS library"
SYS "GetProcAddress", cards%, "cdtInit" TO cdtInit%
SYS "GetProcAddress", cards%, "cdtDraw" TO cdtDraw%
SYS cdtInit%, ^dx%, ^dy%
VDU 23,22,8*dx%;5*dy%;8,16,16,128
 
REM Initialise deck:
DIM card&(51)
FOR I% = 0 TO 51 : card&(I%) = I% : NEXT
 
REM Shuffle deck:
dummy% = FNrng(hand%)
FOR I% = 51 TO 0 STEP -1
C% = FNrng(-1) MOD (I% + 1)
SWAP card&(C%), card&(I%)
NEXT
 
REM Display deck:
FOR I% = 0 TO 51
C% = card&(51 - I%)
X% = (I% MOD 8) * dx%
Y% = (I% DIV 8) * dy% * 2 / 3
SYS cdtDraw%, @memhdc%, X%, Y%, C%, 0, 0
NEXT
SYS "InvalidateRect", @hwnd%, 0, 0
*GSAVE freecell
END
 
DEF FNrng(seed)
PRIVATE state, M%
IF seed >= 0 THEN
state = seed
ELSE
state = (state * 214013 + 2531011)
FOR M% = 52 TO 31 STEP -1
IF state >= 2^M% state -= 2^M%
NEXT
ENDIF
= state >> 16
Output:

Freecell BBC.gif

[edit] Bracmat

(  ( createArray
= array rank ranks suit suits
. A 2 3 4 5 6 7 8 9 T J Q K:?ranks
& :?array
& whl
' ( !ranks:%?rank ?ranks
& ♣ ♦ ♥ ♠:?suits
& whl
' ( !suits:%?suit ?suits
& !array str$(!rank !suit):?array
)
)
& !array
)
& ( deal
= A B D L Z pick card dealt deck
, i last rand row state
.  !arg:(?deck:? [?L.?state)
& 8:?row
& :?dealt
& ( pick
= sep
. ( -1+!row:>0:?row
& " ":?sep
| \n:?sep&8:?row
)
& !dealt !arg !sep:?dealt
)
& 2^31:?B
& 2^16:?D
& "
'Hard code' the numbers B and D into the rand function using
macro expansion. (Gives a marginally faster execution speed.)
"
&
' (
. mod$(!state*214013+2531011.$B):?state
& div$(!state.$D)
)
 : (=?rand)
& !L+1:?L
& whl
' ( mod$(rand$.!L+-1:?L):?i
& !deck:?A [!i %?card ?Z
& ( !Z:?Z %@?last&!A !last !Z
| !A
)
 : ?deck
& pick$!card
)
& pick$\n
& str$!dealt
)
& createArray$:?deck
& put$("Game #1\n","dealt.txt",NEW)
& put$(deal$(!deck.1),"dealt.txt",APP)
& put$("
 
Game #617
","dealt.txt",APP)
& put$(deal$(!deck.617),"dealt.txt",APP)
&
)

Content of dealt.txt:

Game #1
J♦ 2♦ 9♥ J♣ 5♦ 7♥ 7♣ 5♥
K♦ K♣ 9♠ 5♠ A♦ Q♣ K♥ 3♥
2♠ K♠ 9♦ Q♦ J♠ A♠ A♥ 3♣
4♣ 5♣ T♠ Q♥ 4♥ A♣ 4♦ 7♠
3♠ T♦ 4♠ T♥ 8♥ 2♣ J♥ 7♦
6♦ 8♠ 8♦ Q♠ 6♣ 3♦ 8♣ T♣
6♠ 9♣ 2♥ 6♥ 
 

Game #617
7♦ A♦ 5♣ 3♠ 5♠ 8♣ 2♦ A♥
T♦ 7♠ Q♦ A♣ 6♦ 8♥ A♠ K♥
T♥ Q♣ 3♥ 9♦ 6♠ 8♦ 3♦ T♣
K♦ 5♥ 9♠ 3♣ 8♠ 7♥ 4♦ J♠
4♣ Q♠ 9♣ 9♥ 7♣ 6♥ 2♣ 2♠
4♠ T♠ 2♥ 5♦ J♣ 6♣ J♥ Q♥
J♦ K♠ K♣ 4♥ 

[edit] C

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
 
wchar_t s_suits[] = L"♣♦♥♠", s_nums[] = L"A23456789TJQK";
 
#define RMAX32 ((1U << 31) - 1)
static int seed = 1;
int rnd(void) { return (seed = (seed * 214013 + 2531011) & RMAX32) >> 16; }
void srnd(int x) { seed = x; }
 
void show(const int *c)
{
int i;
for (i = 0; i < 52; c++) {
printf(" \033[%dm%lc\033[m%lc", 32 - (1 + *c) % 4 / 2,
s_suits[*c % 4], s_nums[*c / 4]);
if (!(++i % 8) || i == 52) putchar('\n');
}
}
 
void deal(int s, int *t)
{
int i, j;
srnd(s);
 
for (i = 0; i < 52; i++) t[i] = 51 - i;
for (i = 0; i < 51; i++) {
j = 51 - rnd() % (52 - i);
s = t[i], t[i] = t[j], t[j] = s;
}
}
 
int main(int c, char **v)
{
int s, card[52];
if (c < 2 || (s = atoi(v[1])) <= 0) s = 11982;
 
setlocale(LC_ALL, "");
 
deal(s, card);
printf("Hand %d\n", s);
show(card);
 
return 0;
}

[edit] C++

 
#include <windows.h>
#include <iostream>
 
//--------------------------------------------------------------------------------------------------
using namespace std;
 
//--------------------------------------------------------------------------------------------------
class fc_dealer
{
public:
void deal( int game )
{
_gn = game;
fillDeck();
shuffle();
display();
}
 
private:
void fillDeck()
{
int p = 0;
for( int c = 0; c < 13; c++ )
for( int s = 0; s < 4; s++ )
_cards[p++] = c | s << 4;
}
 
void shuffle()
{
srand( _gn );
int cc = 52, nc, lc;
while( cc )
{
nc = rand() % cc;
lc = _cards[--cc];
_cards[cc] = _cards[nc];
_cards[nc] = lc;
}
}
 
void display()
{
char* suit = "CDHS";
char* symb = "A23456789TJQK";
int z = 0;
cout << "GAME #" << _gn << endl << "=======================" << endl;
for( int c = 51; c >= 0; c-- )
{
cout << symb[_cards[c] & 15] << suit[_cards[c] >> 4] << " ";
if( ++z >= 8 )
{
cout << endl;
z = 0;
}
}
}
 
int _cards[52], _gn;
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
fc_dealer dealer;
int gn;
while( true )
{
cout << endl << "Game number please ( 0 to QUIT ): "; cin >> gn;
if( !gn ) break;
 
system( "cls" );
dealer.deal( gn );
cout << endl << endl;
}
return 0;
}
//--------------------------------------------------------------------------------------------------
 

Output:

GAME #1
=======================
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
2S KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H

GAME #617
=======================
7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] OOP version

This is written using a more object-oriented approach than the version above.

#include <string>       // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
#include <vector> // std::vector
 
using namespace std;
 
//------------------------------------------------------------------------------
 
class Random {
public:
void init(uint32_t seed) { _seed = seed; }
int roll() { return (_seed = (_seed * MULT + INCR) & MASK) >> 16; }
private:
int _seed;
enum { MULT = 214013, INCR = 2531011, MASK = (1U << 31) - 1 };
};
 
//------------------------------------------------------------------------------
 
class Card {
public:
Card(int value) : _value(value) { }
int suit() const { return _value % 4; }
int rank() const { return _value / 4; }
string str() const {
stringstream s; s << _ranks[rank()] << _suits[suit()]; return s.str();
}
private:
int _value;
const char* _suits = "CDHS";
const char* _ranks = "A23456789TJQK";
};
 
//------------------------------------------------------------------------------
 
class Deck {
public:
Deck(int seed) {
_random.init(seed);
for (int i = 0; i < 52; i++)
_cards.push_back(Card(51 - i));
for (int i = 0; i < 51; i++) {
int j = 51 - _random.roll() % (52 - i);
swap(_cards[i], _cards[j]);
}
}
string str() const {
stringstream s;
for (int i = 0; i < _cards.size(); i++)
s << _cards[i].str() << (i % 8 == 7 || i == 51 ? "\n" : " ");
return s.str();
}
private:
vector<Card> _cards;
Random _random;
};
 
//------------------------------------------------------------------------------
 
int main(int argc, const char * argv[])
{
{
Deck deck(1);
cout << "Deck 1" << endl << deck.str() << endl;
}
{
Deck deck(617);
cout << "Deck 617" << endl << deck.str() << endl;
}
return 0;
}
 
Output:
Deck 1
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
2S KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H

Deck 617
7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] Common Lisp

(defun make-rng (seed)
#'(lambda ()
(ash (setf seed (mod (+ (* 214013 seed) 2531011) (expt 2 31))) -16)))
 
(defun split (s) (map 'list #'string s))
 
(defun make-deck (seed)
(let ((hand (make-array 52 :fill-pointer 0))
(rng (make-rng seed)))
(dolist (d (split "A23456789TJQK"))
(dolist (s (split "♣♦♥♠"))
(vector-push (concatenate 'string d s) hand)))
(dotimes (i 52)
(rotatef (aref hand (- 51 i))
(aref hand (mod (funcall rng) (- 52 i)))))
(nreverse hand)))
 
(defun show-deck (seed)
(let ((hand (make-deck seed)))
(format t "~%Hand ~d~%" seed)
(dotimes (i 52)
(format t "~A " (aref hand i))
(if (= (mod i 8) 7) (write-line "")))))
 
(show-deck 1)
(show-deck 617)

[edit] C#

Longer than it absolutely needs to be because I split out several independently useful classes.

using System;
using System.Collections.Generic;
using System.Text;
 
namespace FreeCellDeals
{
public class RNG
{
private int _state;
 
public RNG()
{
_state = (int)DateTime.Now.Ticks;
}
 
public RNG(int n)
{
_state = n;
}
public int Next()
{
return ((_state = 214013 * _state + 2531011) & int.MaxValue) >> 16;
}
}
 
public enum Rank
{
Ace,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King
}
 
public enum Suit
{
Clubs,
Diamonds,
Hearts,
Spades
}
 
public class Card
{
private const string Ranks = "A23456789TJQK";
private const string Suits = "CDHS";
 
private Rank _rank;
public Rank Rank
{
get
{
return _rank;
}
set
{
if ((int)value < 0 || (int)value > 12)
{
throw new InvalidOperationException("Setting card rank out of range");
}
_rank = value;
}
}
 
private Suit _suit;
public Suit Suit
{
get
{
return _suit;
}
set
{
if ((int)value < 0 || (int)value > 3)
{
throw new InvalidOperationException("Setting card rank out of range");
}
_suit = value;
}
}
 
public Card(Rank rank, Suit suit)
{
Rank = rank;
Suit = suit;
}
 
public int NRank()
{
return (int) Rank;
}
 
public int NSuit()
{
return (int) Suit;
}
 
public override string ToString()
{
return new string(new[] {Ranks[NRank()], Suits[NSuit()]});
}
}
 
public class FreeCellDeal
{
public List<Card> Deck { get; private set; }
 
public FreeCellDeal(int iDeal)
{
RNG rng = new RNG(iDeal);
 
List<Card> rDeck = new List<Card>();
Deck = new List<Card>();
 
for (int rank = 0; rank < 13; rank++)
{
for (int suit = 0; suit < 4; suit++)
{
rDeck.Add(new Card((Rank)rank, (Suit)suit));
}
}
 
// Normally we deal from the front of a deck. The algorithm "deals" from the back so we reverse the
// deck here to more conventionally deal from the front/start of the array.
for (int iCard = 51; iCard >= 0; iCard--)
{
int iSwap = rng.Next() % (iCard + 1);
Deck.Add(rDeck[iSwap]);
rDeck[iSwap] = rDeck[iCard];
}
}
 
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int iRow = 0; iRow < 6; iRow++ )
{
for (int iCol = 0; iCol < 8; iCol++)
{
sb.AppendFormat("{0} ", Deck[iRow * 8 + iCol]);
}
sb.Append("\n");
}
for (int iCard = 48; iCard < 52; iCard++)
{
sb.AppendFormat("{0} ", Deck[iCard]);
}
return sb.ToString();
}
}
 
class Program
{
static void Main()
{
Console.WriteLine(new FreeCellDeal(1));
Console.WriteLine();
Console.WriteLine(new FreeCellDeal(617));
}
}
}
Output:
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
2S KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H

7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] C# (shorter)

Shorter than the previous version. Adds a few classes, but stays closer to the gist of the C version.

 
using System;
using System.Text;
 
namespace FreeCellConsole
{
public class Rand {
long _seed;
public Rand(int seed=1) {
_seed = seed;
}
public int Next() {
return (int) ((_seed = (_seed * 214013 + 2531011) & int.MaxValue) >> 16);
}
}
 
public class Card {
private static readonly string kSuits = "♣♦♥♠";
private static readonly string kValues = "A23456789TJQK";
public int Value { get; set; }
public int Suit { get; set; }
public Card(int rawvalue=0) : this(rawvalue / 4, rawvalue % 4) {
}
public Card(int value, int suit) {
Value = value; Suit = suit;
}
public override string ToString() {
return string.Format("{0}{1}", kValues[Value], kSuits[Suit]);
}
}
 
public class Deck {
public Card[] Cards;
public Deck(int seed) {
var r = new Rand(seed);
Cards = new Card[52];
for (int i=0; i < 52; i++)
Cards[i] = new Card(51 - i);
for (int i=0; i < 51; i++) {
int j = 51 - r.Next() % (52 - i);
Card tmp = Cards[i]; Cards[i] = Cards[j]; Cards[j] = tmp;
}
}
public override string ToString() {
var sb = new StringBuilder();
for (int i=0; i < Cards.Length; i++) {
sb.Append(Cards[i].ToString());
sb.Append(i % 8 == 7 ? "\n" : " ");
}
return sb.ToString();
}
}
 
class Program {
public static void Main(string[] args) {
Console.WriteLine("Deck 1\n{0}\n", new Deck(1));
Console.WriteLine("Deck 617\n{0}\n", new Deck(617));
}
}
}
 
Output:
Deck 1
J♦ 2♦ 9♥ J♣ 5♦ 7♥ 7♣ 5♥
K♦ K♣ 9♠ 5♠ A♦ Q♣ K♥ 3♥
2♠ K♠ 9♦ Q♦ J♠ A♠ A♥ 3♣
4♣ 5♣ T♠ Q♥ 4♥ A♣ 4♦ 7♠
3♠ T♦ 4♠ T♥ 8♥ 2♣ J♥ 7♦
6♦ 8♠ 8♦ Q♠ 6♣ 3♦ 8♣ T♣
6♠ 9♣ 2♥ 6♥ 

Deck 617
7♦ A♦ 5♣ 3♠ 5♠ 8♣ 2♦ A♥
T♦ 7♠ Q♦ A♣ 6♦ 8♥ A♠ K♥
T♥ Q♣ 3♥ 9♦ 6♠ 8♦ 3♦ T♣
K♦ 5♥ 9♠ 3♣ 8♠ 7♥ 4♦ J♠
4♣ Q♠ 9♣ 9♥ 7♣ 6♥ 2♣ 2♠
4♠ T♠ 2♥ 5♦ J♣ 6♣ J♥ Q♥
J♦ K♠ K♣ 4♥ 

[edit] D

Translation of: C
import std.stdio, std.conv, std.algorithm, std.range;
 
struct RandomGenerator {
uint seed = 1;
 
@property uint next() pure nothrow @nogc {
seed = (seed * 214_013 + 2_531_011) & int.max;
return seed >> 16;
}
}
 
struct Deck {
int[52] cards;
 
void deal(in uint seed) pure /*nothrow*/ {
enum int nc = cards.length; // Must be signed for iota.
iota(nc - 1, -1, -1).copy(cards[]); // iota isn't nothrow.
 
auto rnd = RandomGenerator(seed);
foreach (immutable i, ref c; cards)
c.swap(cards[(nc - 1) - rnd.next % (nc - i)]);
}
 
void show() const {
writefln("%(%-( %s%)\n%)",
cards[]
.chunks(8)
.map!(row => row.map!(c => ["A23456789TJQK"[c / 4]] ~
"CDHS"[c % 4])));
}
}
 
void main(in string[] args) {
immutable seed = (args.length == 2) ? args[1].to!uint : 11_982;
writeln("Hand ", seed);
Deck cards;
cards.deal(seed);
cards.show;
}
Hand 11982
 AH AS 4H AC 2D 6S TS JS
 3D 3H QS QC 8S 7H AD KS
 KD 6H 5S 4D 9H JH 9S 3C
 JC 5D 5C 8C 9D TD KH 7C
 6C 2C TH QH 6D TC 4S 7S
 JD 7D 8H 9C 2H QD 4C 5H
 KC 8D 2S 3S

[edit] Go

Translation of: C
package main
 
import (
"fmt"
"math"
"math/rand"
"os"
"strconv"
"time"
)
 
const sSuits = "CDHS"
const sNums = "A23456789TJQK"
const rMax32 = math.MaxInt32
 
var seed = 1
 
func rnd() int {
seed = (seed*214013 + 2531011) & rMax32
return seed >> 16
}
 
func deal(s int) []int {
seed = s
t := make([]int, 52)
for i := 0; i < 52; i++ {
t[i] = 51 - i
}
for i := 0; i < 51; i++ {
j := 51 - rnd()%(52-i)
t[i], t[j] = t[j], t[i]
}
return t
}
 
func show(cs []int) {
for i, c := range cs {
fmt.Printf(" %c%c", sNums[c/4], sSuits[c%4])
if (i+1)%8 == 0 || i+1 == len(cs) {
fmt.Println()
}
}
}
 
func main() {
var game int
switch len(os.Args) {
case 1:
rand.Seed(time.Now().UnixNano())
game = 1 + rand.Intn(32000)
case 2:
var err error
game, err = strconv.Atoi(os.Args[1])
if err == nil && game >= 1 && game <= 32000 {
break
}
fallthrough
default:
fmt.Println("usage: deal [game]")
fmt.Println(" where game is a number in the range 1 to 32000")
return
}
fmt.Printf("\nGame #%d\n", game)
show(deal(game))
}
Output:
Game #1
 JD 2D 9H JC 5D 7H 7C 5H
 KD KC 9S 5S AD QC KH 3H
 2S KS 9D QD JS AS AH 3C
 4C 5C TS QH 4H AC 4D 7S
 3S TD 4S TH 8H 2C JH 7D
 6D 8S 8D QS 6C 3D 8C TC
 6S 9C 2H 6H

Game #617
 7D AD 5C 3S 5S 8C 2D AH
 TD 7S QD AC 6D 8H AS KH
 TH QC 3H 9D 6S 8D 3D TC
 KD 5H 9S 3C 8S 7H 4D JS
 4C QS 9C 9H 7C 6H 2C 2S
 4S TS 2H 5D JC 6C JH QH
 JD KS KC 4H

[edit] Haskell

Translation of: C
import Data.Int
import Data.Bits
import Data.List
import Data.Array.ST
import Control.Monad
import Control.Monad.ST
import System.Environment
 
srnd :: Int32 -> [Int]
srnd = map (fromIntegral . flip shiftR 16) .
tail . iterate (\x -> (x * 214013 + 2531011) .&. maxBound)
 
deal :: Int32 -> [String]
deal s = runST (do
ar <- newListArray (0,51) $ sequence ["A23456789TJQK", "CDHS"]
:: ST s (STArray s Int String)
forM (zip [52,51..1] rnd) $ \(n, r) -> do
let j = r `mod` n
vj <- readArray ar j
vn <- readArray ar (n - 1)
writeArray ar j vn
return vj)
where rnd = srnd s
 
showCards :: [String] -> IO ()
showCards = mapM_ (putStrLn . unwords) .
takeWhile (not . null) .
unfoldr (Just . splitAt 8)
 
main :: IO ()
main = do
args <- getArgs
let s = read (head args) :: Int32
putStrLn $ "Deal " ++ show s ++ ":"
let cards = deal s
showCards cards

Execution:

$ runghc freecell.hs 617
Deal 617:
7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] Icon and Unicon

procedure main(A)          # freecelldealer
freecelldealer(\A[1] | &null) # seed from command line
end
 
procedure newDeck() #: return a new unshuffled deck
every D := list(52) & i := 0 & r := !"A23456789TJQK" & s := !"CDHS" do
D[i +:= 1] := r || s # initial deck AC AD ... KS
return D
end
 
procedure freecelldealer(gamenum) #: deal a freecell hand
/gamenum := 11982
return showHand(freecellshuffle(newDeck(),gamenum))
end
 
procedure showHand(D) #: show a freecell hand
write("Hand:\n")
every writes(" ",(1 to 8) | "\n")
every writes(" ",D[i := 1 to *D]) do
if i%8 = 0 then write()
write("\n")
return D
end
 
procedure freecellshuffle(D,gamenum) #: freecell shuffle
 
srand_freecell(gamenum) # seed random number generator
D2 := []
until *D = 0 do { # repeat until all dealt
D[r := rand_freecell() % *D + 1] :=: D[*D] # swap random & last cards
put(D2,pull(D)) # remove dealt card from list
}
return D2
end
 
procedure srand_freecell(x) #: seed random
static seed
return seed := \x | \seed | 0 # parm or seed or zero if none
end
 
procedure rand_freecell() #: lcrng
return ishift(srand_freecell((214013 * srand_freecell() + 2531011) % 2147483648),-16)
end
Sample output for game 1:
Hand:

  1  2  3  4  5  6  7  8
 JD 2D 9H JC 5D 7H 7C 5H
 KD KC 9S 5S AD QC KH 3H
 2S KS 9D QD JS AS AH 3C
 4C 5C TS QH 4H AC 4D 7S
 3S TD 4S TH 8H 2C JH 7D
 6D 8S 8D QS 6C 3D 8C TC
 6S 9C 2H 6H

[edit] J

Paraphrase of C:

deck=: ,/ 'A23456789TJQK' ,"0/ 7 u: '♣♦♥♠'
 
srnd=: 3 :'SEED=:{.y,11982'
srnd ''
seed=: do bind 'SEED'
rnd=: (2^16) <.@%~ (2^31) srnd@| 2531011 + 214013 * seed
 
pairs=: <@<@~.@(<: , (| rnd))@>:@i.@-@# NB. indices to swap, for shuffle
swaps=: [: > C.&.>/@|.@; NB. implement the specified shuffle
deal=: |.@(swaps pairs) bind deck
 
show=: (,"2)@:(_8 ]\ ' '&,.)
Example use:
   show deal srnd 1
J♦ 29♥ J♣ 5775
K♦ K♣ 95♠ A♦ Q♣ K♥ 3
2♠ K♠ 9♦ Q♦ J♠ A♠ A♥ 3
45♣ T♠ Q♥ 4♥ A♣ 47
3♠ T♦ 4♠ T♥ 82♣ J♥ 7
688♦ Q♠ 638♣ T♣
6926
show deal srnd 617
7♦ A♦ 53582♦ A♥
T♦ 7♠ Q♦ A♣ 68♥ A♠ K♥
T♥ Q♣ 39683♦ T♣
K♦ 593874♦ J♠
4♣ Q♠ 997622
4♠ T♠ 25♦ J♣ 6♣ J♥ Q♥
J♦ K♠ K♣ 4

[edit] Java

 
import java.util.Arrays;
 
public class Shuffler {
 
private int seed;
 
private String[] deck = {
"AC", "AD", "AH", "AS",
"2C", "2D", "2H", "AS",
"3C", "3D", "3H", "3S",
"4C", "4D", "4H", "4S",
"5C", "5D", "5H", "5S",
"6C", "6D", "6H", "6S",
"7C", "7D", "7H", "7S",
"8C", "8D", "8H", "8S",
"9C", "9D", "9H", "9S",
"TC", "TD", "TH", "TS",
"JC", "JD", "JH", "JS",
"QC", "QD", "QH", "QS",
"KC", "KD", "KH", "KS",
};
 
private int random() {
seed = (214013 * seed + 2531011) & Integer.MAX_VALUE;
return seed >> 16;
}
 
//shuffled cards go to the end
private String[] getShuffledDeck() {
String[] deck = Arrays.copyOf(this.deck, this.deck.length);
for(int i = deck.length - 1; i > 0; i--) {
int r = random() % (i + 1);
String card = deck[r];
deck[r] = deck[i];
deck[i] = card;
}
return deck;
}
 
//deal from end first
public void dealGame(int seed) {
this.seed = seed;
String[] shuffledDeck = getShuffledDeck();
for(int count = 1, i = shuffledDeck.length - 1; i >= 0; count++, i--) {
System.out.print(shuffledDeck[i]);
if(count % 8 == 0) {
System.out.println();
} else {
System.out.print(" ");
}
}
System.out.println();
}
 
public static void main(String[] args) {
Shuffler s = new Shuffler();
s.dealGame(1);
System.out.println();
s.dealGame(617);
}
 
}
 
Output:
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
AS KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H 

7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C AS
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H 

[edit] JavaScript

"use strict";
/*
* Microsoft C Run-time-Library-compatible Random Number Generator
* Copyright by Shlomi Fish, 2011.
* Released under the MIT/X11 License
* ( http://en.wikipedia.org/wiki/MIT_License ).
* */

/* This uses Joose 2.x-or-above, an object system for JavaScript - http://code.google.com/p/joose-js/ . */
 
Class('MSRand', {
has: {
seed: { is: rw, },
},
methods: {
rand: function() {
this.setSeed((this.getSeed() * 214013 + 2531011) & 0x7FFFFFFF);
return ((this.getSeed() >> 16) & 0x7fff);
},
max_rand: function(mymax) {
return this.rand() % mymax;
},
shuffle: function(deck) {
if (deck.length) {
var i = deck.length;
while (--i) {
var j = this.max_rand(i+1);
var tmp = deck[i];
deck[i] = deck[j];
deck[j] = tmp;
}
}
return deck;
},
},
});
 
/*
* Microsoft Windows Freecell / Freecell Pro boards generation.
*
* See:
*
* - http://rosettacode.org/wiki/Deal_cards_for_FreeCell
*
* - http://www.solitairelaboratory.com/mshuffle.txt
*
* Under MIT/X11 Licence.
*
* */

 
function deal_ms_fc_board(seed) {
var randomizer = new MSRand({ seed: seed });
var num_cols = 8;
 
var _perl_range = function(start, end) {
var ret = [];
 
for (var i = start; i <= end; i++) {
ret.push(i);
}
 
return ret;
};
 
var columns = _perl_range(0, num_cols-1).map(function () { return []; });
var deck = _perl_range(0, 4*13-1);
 
randomizer.shuffle(deck);
 
deck = deck.reverse()
 
for (var i = 0; i < 52; i++) {
columns[i % num_cols].push(deck[i]);
}
 
var render_card = function (card) {
var suit = (card % 4);
var rank = Math.floor(card / 4);
 
return "A23456789TJQK".charAt(rank) + "CDHS".charAt(suit);
}
 
var render_column = function(col) {
return ": " + col.map(render_card).join(" ") + "\n";
}
 
return columns.map(render_column).join("");
}
 

[edit] Lua

Uses bit32 library added in Lua 5.2.

deck = {}
rank = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"}
suit = {"C", "D", "H", "S"}
two31, state = bit32.lshift(1, 31), 0
 
function rng()
state = (214013 * state + 2531011) % two31
return bit32.rshift(state, 16)
end
 
function initdeck()
for i, r in ipairs(rank) do
for j, s in ipairs(suit) do
table.insert(deck, r .. s)
end
end
end
 
function deal(num)
initdeck()
state = num
print("Game #" .. num)
repeat
choice = rng(num) % #deck + 1
deck[choice], deck[#deck] = deck[#deck], deck[choice]
io.write(" " .. deck[#deck])
if (#deck % 8 == 5) then
print()
end
deck[#deck] = nil
until #deck == 0
print()
end
 
deal(1)
deal(617)
Output:
Game #1
 JD 2D 9H JC 5D 7H 7C 5H
 KD KC 9S 5S AD QC KH 3H
 2S KS 9D QD JS AS AH 3C
 4C 5C TS QH 4H AC 4D 7S
 3S TD 4S TH 8H 2C JH 7D
 6D 8S 8D QS 6C 3D 8C TC
 6S 9C 2H 6H
Game #617
 7D AD 5C 3S 5S 8C 2D AH
 TD 7S QD AC 6D 8H AS KH
 TH QC 3H 9D 6S 8D 3D TC
 KD 5H 9S 3C 8S 7H 4D JS
 4C QS 9C 9H 7C 6H 2C 2S
 4S TS 2H 5D JC 6C JH QH
 JD KS KC 4H

[edit] Nimrod

Translation of: Python
import sequtils, strutils, os
 
proc randomGenerator(seed: int): iterator: int =
var seed = seed
return iterator: int =
while true:
seed = (seed.int64 * 214013 + 2531011) and int32.high
yield seed shr 16
 
proc deal(seed): seq[int] =
const nc = 52
result = toSeq countdown(nc - 1, 0)
var rnd = randomGenerator seed
for i in 0 .. <nc:
let r = rnd()
let j = (nc - 1) - r mod (nc - i)
swap result[i], result[j]
 
proc show(cards) =
var l = newSeq[string]()
for c in cards:
l.add "A23456789TJQK"[c div 4] & "CDHS"[c mod 4]
for i in countup(0, cards.high, 8):
echo " ", l[i..min(i+7, l.high)].join(" ")
 
let seed = if paramCount() == 1: paramStr(1).parseInt else: 11982
echo "Hand ", seed
let deck = deal seed
show deck

Output:

Hand 11982
 AH AS 4H AC 2D 6S TS JS
 3D 3H QS QC 8S 7H AD KS
 KD 6H 5S 4D 9H JH 9S 3C
 JC 5D 5C 8C 9D TD KH 7C
 6C 2C TH QH 6D TC 4S 7S
 JD 7D 8H 9C 2H QD 4C 5H
 KC 8D 2S 3S

[edit] Objective-C

Based on the shorter C# version. Objective-C can use the C code as-is, but this example uses some NS foundation classes. The latest clang compiler is assumed with ARC enabled. For the sake of clarity & simplicity, method prototypes have been omitted from @interface sections: they are not necessary if everything is in one file.

#define RMAX32 ((1U << 31) - 1)
 
//--------------------------------------------------------------------
 
@interface Rand : NSObject
-(instancetype) initWithSeed: (int)seed;
-(int) next;
@property (nonatomic) long seed;
@end
 
@implementation Rand
-(instancetype) initWithSeed: (int)seed {
if ((self = [super init])) {
self.seed = seed;
}
return self;
}
-(int) next {
return (int) ((_seed = (_seed * 214013 + 2531011) & RMAX32) >> 16);
}
@end
 
//--------------------------------------------------------------------
 
@interface Card : NSObject
-(instancetype) initWithSequence: (int)n;
-(instancetype) initWithValue: (int)v suit: (int)s;
@property (nonatomic) int value;
@property (nonatomic) int suit;
@end
 
@implementation Card
-(instancetype) initWithSequence: (int)n {
return [self initWithValue:n/4 suit:n%4];
}
-(instancetype) initWithValue: (int)v suit: (int)s {
if ((self = [super init])) {
_value = v; _suit = s;
}
return self;
}
-(NSString *) description {
static NSString * const kSuits = @"♣♦♥♠";
static NSString * const kValues = @"A23456789TJQK";
return [NSString stringWithFormat:@"%C%C",
[kValues characterAtIndex:_value],
[kSuits characterAtIndex:_suit]];
}
@end
 
//--------------------------------------------------------------------
 
@interface Deck : NSObject
-(instancetype) initWithSeed: (int)seed;
@property (nonatomic, strong) NSMutableArray *cards;
@end
 
@implementation Deck
-(instancetype) initWithSeed: (int)seed {
if ((self = [super init])) {
Rand *r = [[Rand alloc] initWithSeed:seed];
_cards = [NSMutableArray array];
for (int i = 0; i < 52; i++)
[_cards addObject:[[Card alloc] initWithSequence:51 - i]];
for (int i = 0; i < 51; i++)
[_cards exchangeObjectAtIndex:i withObjectAtIndex:51 - [r next] % (52 - i)];
}
return self;
}
-(NSString *) description {
NSMutableString *s = [NSMutableString string];
for (int i = 0; i < [_cards count]; i++) {
[s appendString:[_cards[i] description]];
[s appendString:i%8==7 ? @"\n" : @" "];
}
return s;
}
@end
 
//--------------------------------------------------------------------
 
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"Deck 1\n%@\n", [[Deck alloc] initWithSeed:1]);
NSLog(@"Deck 617\n%@\n", [[Deck alloc] initWithSeed:617]);
}
return 0;
}
Output:
Deck 1
J♦ 2♦ 9♥ J♣ 5♦ 7♥ 7♣ 5♥
K♦ K♣ 9♠ 5♠ A♦ Q♣ K♥ 3♥
2♠ K♠ 9♦ Q♦ J♠ A♠ A♥ 3♣
4♣ 5♣ T♠ Q♥ 4♥ A♣ 4♦ 7♠
3♠ T♦ 4♠ T♥ 8♥ 2♣ J♥ 7♦
6♦ 8♠ 8♦ Q♠ 6♣ 3♦ 8♣ T♣
6♠ 9♣ 2♥ 6♥ 

Deck 617
7♦ A♦ 5♣ 3♠ 5♠ 8♣ 2♦ A♥
T♦ 7♠ Q♦ A♣ 6♦ 8♥ A♠ K♥
T♥ Q♣ 3♥ 9♦ 6♠ 8♦ 3♦ T♣
K♦ 5♥ 9♠ 3♣ 8♠ 7♥ 4♦ J♠
4♣ Q♠ 9♣ 9♥ 7♣ 6♥ 2♣ 2♠
4♠ T♠ 2♥ 5♦ J♣ 6♣ J♥ Q♥
J♦ K♠ K♣ 4♥ 

[edit] OCaml

Translation of: C
let srnd x =
(* since OCaml's built-in int type is at least 31 (note: not 32) bits wide,
and this problem takes mod 2^31, it is just enough if we treat it as
an unsigned integer, which means taking the logical right shift *)

let seed = ref x in
fun () ->
seed := (!seed * 214013 + 2531011) land 0x7fffffff;
!seed lsr 16
 
let deal s =
let rnd = srnd s in
let t = Array.init 52 (fun i -> i) in
let cards =
Array.init 52 (fun j ->
let n = 52 - j in
let i = rnd() mod n in
let this = t.(i) in
t.(i) <- t.(pred n);
this)
in
(cards)
 
let show cards =
let suits = "CDHS"
and nums = "A23456789TJQK" in
Array.iteri (fun i card ->
Printf.printf "%c%c%c"
nums.[card / 4]
suits.[card mod 4]
(if (i mod 8) = 7 then '\n' else ' ')
) cards;
print_newline()
 
let () =
let s =
try int_of_string Sys.argv.(1)
with _ -> 11982
in
Printf.printf "Deal %d:\n" s;
let cards = deal s in
show cards
Execution:
$ ocaml freecell.ml 617
Deal 617:
7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] PARI/GP

The use of local is critical here, so that nextrand() has access to the current state unaffected by whatever the user may have stored in the variable 'state.

card(n)=concat(["A","2","3","4","5","6","7","8","9","T","J","Q","K"][n\4+1],["C","D","H","S"][n%4+1]);
nextrand()={
(state=(214013*state+2531011)%2^31)>>16
};
deal(seed)={
my(deck=vector(52,n,n-1),t);
local(state=seed);
forstep(last=52,1,-1,
t=nextrand()%last+1;
print1(card(deck[t]),if(last%8==5,"\n"," "));
deck[t]=deck[last]
)
};

[edit] Perl

#!/usr/bin/perl
 
use strict;
use warnings;
 
use utf8;
 
sub deal {
my $s = shift;
 
my $rnd = sub {
return (($s = ($s * 214013 + 2531011) & 0x7fffffff) >> 16 );
};
 
my @d;
for my $b (split "", "A23456789TJQK") {
push @d, map("$_$b", qw/♣ ♦ ♥ ♠/);
}
 
for my $idx (reverse 0 .. $#d) {
my $r = $rnd->() % ($idx + 1);
@d[$r, $idx] = @d[$idx, $r];
}
 
return [reverse @d];
}
 
my $hand_idx = shift(@ARGV) // 11_982;
 
my $cards = deal($hand_idx);
 
my $num_cards_in_height = 8;
my $string = '';
 
while (@$cards)
{
$string .= join(' ', splice(@$cards, 0, 8)) . "\n";
}
 
binmode STDOUT, ':encoding(utf-8)';
print "Hand $hand_idx\n";
print $string;

[edit] Perl 6

Works with: rakudo version 2013-04-18
sub dealgame ($game-number = 1) {
sub ms-lcg-method($seed = $game-number) { ( 214013 * $seed + 2531011 ) % 2**31 }
 
# lazy list of the random sequence
my @ms-lcg := (&ms-lcg-method ... *).map: * +> 16;
 
constant CardBlock = '🂠'.ord;
my @deck = gather for 1..11,13,14 X+ (48,32...0) -> $off {
take chr CardBlock + $off;
}
 
my @game = gather while @deck {
@deck[@ms-lcg.shift % @deck, @deck-1] .= reverse;
take @deck.pop;
}
 
say "Game #$game-number";
say @game.splice(0, 8 min +@game) while @game;
}
 
dealgame;
dealgame 617;
Output:
Game #1
🃋 🃂 🂹 🃛 🃅 🂷 🃗 🂵
🃎 🃞 🂩 🂥 🃁 🃝 🂾 🂳
🂢 🂮 🃉 🃍 🂫 🂡 🂱 🃓
🃔 🃕 🂪 🂽 🂴 🃑 🃄 🂧
🂣 🃊 🂤 🂺 🂸 🃒 🂻 🃇
🃆 🂨 🃈 🂭 🃖 🃃 🃘 🃚
🂦 🃙 🂲 🂶
Game #617
🃇 🃁 🃕 🂣 🂥 🃘 🃂 🂱
🃊 🂧 🃍 🃑 🃆 🂸 🂡 🂾
🂺 🃝 🂳 🃉 🂦 🃈 🃃 🃚
🃎 🂵 🂩 🃓 🂨 🂷 🃄 🂫
🃔 🂭 🃙 🂹 🃗 🂶 🃒 🂢
🂤 🂪 🂲 🃅 🃛 🃖 🂻 🂽
🃋 🂮 🃞 🂴

[edit] PicoLisp

Using the random generator from Linear congruential generator#PicoLisp:

(setq *MsSeed 11982)
 
(de msRand ()
(>> 16
(setq *MsSeed
(& (+ 2531011 (* 214013 *MsSeed)) `(dec (** 2 31))) ) ) )
 
(let L
(make
(for Num (range 13 1)
(for Suit '((32 . "♠") (31 . "♥") (31 . "♦") (32 . "♣"))
(link (cons (get '`(chop "A23456789TJQK") Num) Suit)) ) ) )
(for I 51
(xchg
(nth L I)
(nth L (- 52 (% (msRand) (- 53 I)))) ) )
(for C L
(prin " ^[[" (cadr C) "m" (cddr C) "^[[m" (car C))
(at (0 . 8) (prinl)) )
(prinl) )

[edit] PureBasic

#MaxCardNum = 51 ;zero-based count of cards in a deck
Global deckSize
Global Dim cards(#MaxCardNum) ;card with highest index is at the top of deck
 
Procedure RNG(seed.q = -1)
Static state.q
If seed >= 0
state = seed
Else
state = (state * 214013 + 2531011) % (1 << 31)
ProcedureReturn state >> 16
EndIf
EndProcedure
 
Procedure makeDeck(hand)
Protected i, c
For i = 0 To #MaxCardNum: cards(i) = i: Next
 
RNG(hand) ;set seed value
deckSize = #MaxCardNum
While deckSize
c = RNG() % (deckSize + 1)
Swap cards(c), cards(deckSize)
deckSize - 1
Wend
deckSize = #MaxCardNum
EndProcedure
 
Procedure showDeck(hand)
Protected i, c
PrintN("Hand #" + Str(hand))
makeDeck(hand)
For i = 0 To #MaxCardNum
c = cards(#MaxCardNum - i)
Print(" " + Mid("A23456789TJQK", (c / 4) + 1, 1) + Mid("CDHS",(c % 4) + 1, 1))
If (i + 1) % 8 = 0 Or i = #MaxCardNum: PrintN(""): EndIf
Next
EndProcedure
 
If OpenConsole()
showDeck(1)
showDeck(617)
showDeck(11982)
 
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf
Sample output:
Hand #1
 JD 2D 9H JC 5D 7H 7C 5H
 KD KC 9S 5S AD QC KH 3H
 2S KS 9D QD JS AS AH 3C
 4C 5C TS QH 4H AC 4D 7S
 3S TD 4S TH 8H 2C JH 7D
 6D 8S 8D QS 6C 3D 8C TC
 6S 9C 2H 6H
Hand #617
 7D AD 5C 3S 5S 8C 2D AH
 TD 7S QD AC 6D 8H AS KH
 TH QC 3H 9D 6S 8D 3D TC
 KD 5H 9S 3C 8S 7H 4D JS
 4C QS 9C 9H 7C 6H 2C 2S
 4S TS 2H 5D JC 6C JH QH
 JD KS KC 4H
Hand #11982
 AH AS 4H AC 2D 6S TS JS
 3D 3H QS QC 8S 7H AD KS
 KD 6H 5S 4D 9H JH 9S 3C
 JC 5D 5C 8C 9D TD KH 7C
 6C 2C TH QH 6D TC 4S 7S
 JD 7D 8H 9C 2H QD 4C 5H
 KC 8D 2S 3S

[edit] Python

Translation of: D
from sys import argv
 
def randomGenerator(seed=1):
max_int32 = (1 << 31) - 1
seed = seed & max_int32
 
while True:
seed = (seed * 214013 + 2531011) & max_int32
yield seed >> 16
 
def deal(seed):
nc = 52
cards = range(nc - 1, -1, -1)
rnd = randomGenerator(seed)
for i, r in zip(range(nc), rnd):
j = (nc - 1) - r % (nc - i)
cards[i], cards[j] = cards[j], cards[i]
return cards
 
def show(cards):
l = ["A23456789TJQK"[c / 4] + "CDHS"[c % 4] for c in cards]
for i in range(0, len(cards), 8):
print " ", " ".join(l[i : i+8])
 
if __name__ == '__main__':
seed = int(argv[1]) if len(argv) == 2 else 11982
print "Hand", seed
deck = deal(seed)
show(deck)
Output:
Hand 11982
  AH AS 4H AC 2D 6S TS JS
  3D 3H QS QC 8S 7H AD KS
  KD 6H 5S 4D 9H JH 9S 3C
  JC 5D 5C 8C 9D TD KH 7C
  6C 2C TH QH 6D TC 4S 7S
  JD 7D 8H 9C 2H QD 4C 5H
  KC 8D 2S 3S

[edit] Racket

#lang racket
 
(module Linear_congruential_generator racket
 ;; taken from http://rosettacode.org/wiki/Linear_congruential_generator#Racket
 ;; w/o BSD generator
(require racket/generator)
(provide ms-rand)
(define (ms-update state_n)
(modulo (+ (* 214013 state_n) 2531011)
(expt 2 31)))
(define ((rand update ->rand) seed)
(generator () (let loop ([state_n seed])
(define state_n+1 (update state_n))
(yield (->rand state_n+1))
(loop state_n+1))))
(define ms-rand (rand ms-update (lambda (x) (quotient x (expt 2 16))))))
 
(require (submod "." Linear_congruential_generator))
 
;; Personally I prefer CDHS to the unicode characters (on an aesthetic basis,
;; rather than anything else. Plus it helps match with the examples given at the
;; head of the task.
(define suits "CDHS")
(define (initial-deck)
(for*/vector #:length 52
((face "A23456789TJQK")
(suit suits))
(cons face suit)))
 
;; srfi/43 has one of these, but is quick enough to reimplement!
(define (vector-swap! v i j)
(let ((t (vector-ref v i)))
(vector-set! v i (vector-ref v j))
(vector-set! v j t)))
 
(define (deal hand)
(define pack (initial-deck))
(define rnd (ms-rand hand))
(define (deal-nth-card pack-sz card-no deal)
(vector-swap! pack card-no (sub1 pack-sz))
(cons (vector-ref pack (sub1 pack-sz)) deal))
 
(let inner-deal ((pack-sz (vector-length pack)) (deal null))
(if (zero? pack-sz) (reverse deal) ;; we accumulated this backwards!
(inner-deal (sub1 pack-sz)
(deal-nth-card pack-sz (modulo (rnd) pack-sz) deal)))))
 
(define (present-deal hand)
(printf "Game #~a~%" hand)
(let inner-present-deal ((pile 0) (deck (deal hand)))
(unless (null? deck)
(printf "~a~a~a" (caar deck) (cdar deck)
(if (or (null? (cdr deck)) (= 7 (modulo pile 8))) "\n" " "))
(inner-present-deal (add1 pile) (cdr deck)))))
 
;; Run it so we get some output:
(present-deal 1)
(newline)
(present-deal 617)
Output:
Game #1
JD 2D 9H JC 5D 7H 7C 5H
KD KC 9S 5S AD QC KH 3H
2S KS 9D QD JS AS AH 3C
4C 5C TS QH 4H AC 4D 7S
3S TD 4S TH 8H 2C JH 7D
6D 8S 8D QS 6C 3D 8C TC
6S 9C 2H 6H

Game #617
7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H

[edit] Ruby

# Deal cards for FreeCell.
# http://rosettacode.org/wiki/Deal_cards_for_FreeCell
 
require 'optparse'
 
# Parse command-line arguments.
# games = ARGV converted to Integer
# No arguments? Pick any of first 32000 games.
games = nil
OptionParser.new do |o|
begin
o.banner = "Usage: #{o.program_name} number..."
o.parse!
games = ARGV.map {|s| Integer(s)}
games.empty? and games = [rand(32000)]
rescue => e
$stderr.puts e, o
abort
end
end
 
# Define methods for old Ruby versions.
# Enumerable#each_slice appeared in Ruby 1.8.7.
# Enumerable#flat_map appeared in Ruby 1.9.2.
module Enumerable
unless method_defined? :each_slice
def each_slice(count)
block_given? or return enum_for(:each_slice, count)
ary = []
each {|e|
ary << e
ary.length == count and (yield ary.dup; ary.clear)}
ary.empty? or yield ary.dup
nil
end
end
 
unless method_defined? :flat_map
def flat_map
block_given? or return enum_for(:flat_map)
ary = []
each {|e|
y = yield e
ary.concat(y) rescue ary.push(y)}
ary
end
end
end
 
# Create original deck of 52 cards, not yet shuffled.
orig_deck = %w{A 2 3 4 5 6 7 8 9 T J Q K
}.flat_map {|rank| %w{C D H S}.map {|suit| "#{rank}#{suit}"}}
 
games.each do |seed|
deck = orig_deck.dup
 
# Shuffle deck with random index from linear congruential
# generator like Microsoft.
state = seed
52.downto(2) do |len|
state = ((214013 * state) + 2531011) & 0x7fff_ffff
index = (state >> 16) % len
last = len - 1
deck[index], deck[last] = deck[last], deck[index]
end
 
deck.reverse! # Shuffle did reverse deck. Do reverse again.
 
# Deal cards.
puts "Game ##{seed}"
deck.each_slice(8) {|row| puts " " + row.join(" ")}
end
Output:
$ ruby freecell.rb 11982 
Game #11982
 AH AS 4H AC 2D 6S TS JS
 3D 3H QS QC 8S 7H AD KS
 KD 6H 5S 4D 9H JH 9S 3C
 JC 5D 5C 8C 9D TD KH 7C
 6C 2C TH QH 6D TC 4S 7S
 JD 7D 8H 9C 2H QD 4C 5H
 KC 8D 2S 3S

[edit] Run BASIC

projectDir$	= "a_project"                                            ' project directory
imageDir$ = DefaultDir$ + "\projects\" + projectDir$ + "\image\" ' directory of deck images
imagePath$ = "../";projectDir$;"/image/" ' path of deck images
 
suite$ = "C,D,H,S" ' Club,Diamond,Hart,Spaces
card$ = "A,2,3,4,5,6,7,8,9,T,J,Q,K" ' Cards Ace to King
 
dim n(55) ' make ordered deck
for i = 1 to 52 ' of 52 cards
n(i) = i
next i
 
for i = 1 to 52 * 3 ' shuffle deck 3 times
i1 = int(rnd(1)*52) + 1
i2 = int(rnd(1)*52) + 1
h2 = n(i1)
n(i1) = n(i2)
n(i2) = h2
next i
 
for yy = 1 to 8 ' display 7 across and 8 down
for xx = 1 to 7
card = card + 1
s = (n(card) mod 4) + 1 ' determine suite
c = (n(card) mod 13) + 1 ' determine card
cardId$ = word$(card$,c,",");word$(suite$,s,",");".gif"
html "<div style='position: relative; left:";(xx -1) * 80;"px; top:";(yy -1) * 20;"px; height:0px; width:0px;>"
html "<div style='width:100px; height:100px; border:solid 0px #000;'>"
html "<img src=";imagePath$;cardId$;" width=70px >"
html "</div></div>"
if card = 52 then end ' out of cards
next xx
next yy

FreeCell.png

[edit] Rust

Based on JavaScript.

/*
* Microsoft C Run-time-Library-compatible Random Number Generator
* Copyright by Shlomi Fish, 2011.
* Released under the MIT/X11 License
* ( http://en.wikipedia.org/wiki/MIT_License ).
* */
 
struct MSVC_Rand_Gen {
seed: i32
}
 
impl MSVC_Rand_Gen {
fn rand(&mut self) -> i32 {
self.seed = ((self.seed * 214013 + 2531011) & 0x7FFFFFFF);
return ((self.seed >> 16) & 0x7FFF);
}
fn max_rand(&mut self, mymax: i32) -> i32 {
return self.rand() % mymax;
}
fn shuffle<T>(&mut self, deck: &mut [T]) {
if deck.len() > 0 {
let mut i = (deck.len() as i32) - 1;
while i > 0 {
let j = self.max_rand(i+1);
vec::swap(deck, i as uint, j as uint);
i = i-1;
}
}
}
}
 
/*
* Microsoft Windows Freecell / Freecell Pro boards generation.
*
* See:
*
* - http://rosettacode.org/wiki/Deal_cards_for_FreeCell
*
* - http://www.solitairelaboratory.com/mshuffle.txt
*
* Under MIT/X11 Licence.
*
* */
 
 
fn deal_ms_fc_board(seed: i32) -> ~str {
let mut randomizer = MSVC_Rand_Gen { seed: seed, };
let num_cols = 8;
 
let mut columns = vec::from_elem(num_cols, ~[]);
let mut deck = vec::from_fn(4*13, |i| i);
 
let rank_strings = str::to_chars("A23456789TJQK");
let suit_strings = str::to_chars("CDHS");
 
randomizer.shuffle(deck);
 
vec::reverse(deck);
 
for uint::range(0, 52) |i| {
columns[i % num_cols].push(deck[i]);
};
 
let render_card = |card: &uint| {
let suit = card % 4;
let rank = card / 4;
 
fmt!("%c%c",rank_strings[rank], suit_strings[suit])
};
 
let render_column = |col: &~[uint]| {
fmt!(": %s\n", str::connect((col.map(render_card)), " "))
};
 
return str::concat(columns.map(render_column));
}
 
fn main() {
let args: ~[~str] = os::args();
 
match uint::from_str(args[1]) {
Some(x) => print(deal_ms_fc_board(x as i32)),
None => println("I need a real number"),
}
}
 

[edit] Seed7

$ include "seed7_05.s7i";
include "console.s7i";
 
const string: suits is "♣♦♥♠";
const string: nums is "A23456789TJQK";
 
var integer: randomSeed is 1;
 
const func integer: random is func
result
var integer: rand is 1;
begin
randomSeed := (randomSeed * 214013 + 2531011) mod 2 ** 31;
rand := randomSeed >> 16;
end func;
 
const proc: show (in array integer: cards) is func
local
var integer: index is 0;
begin
for index range 1 to 52 do
write(" " <& suits[succ(cards[index] rem 4)] <& nums[succ(cards[index] div 4)]);
if index rem 8 = 0 or index = 52 then
writeln;
end if;
end for;
end func;
 
const func array integer: deal (in integer: gameNum) is func
result
var array integer: cards is 52 times 0;
local
var integer: i is 0;
var integer: j is 0;
var integer: s is 0;
begin
randomSeed := gameNum;
for i range 1 to 52 do
cards[i] := 52 - i;
end for;
for i range 1 to 51 do
j := 52 - random mod (53 - i);
s := cards[i];
cards[i] := cards[j];
cards[j] := s;
end for;
end func;
 
const proc: main is func
local
var integer: gameNum is 11982;
var array integer: cards is 0 times 0;
begin
OUT := STD_CONSOLE;
if length(argv(PROGRAM)) >= 1 then
block
gameNum := integer parse (argv(PROGRAM)[1]);
exception
catch RANGE_ERROR: noop;
end block;
end if;
cards := deal(gameNum);
writeln("Hand " <& gameNum);
show(cards);
end func;
Output:
Hand 1
  ♦J  ♦2  ♥9  ♣J  ♦5  ♥7  ♣7  ♥5
  ♦K  ♣K  ♠9  ♠5  ♦A  ♣Q  ♥K  ♥3
  ♠2  ♠K  ♦9  ♦Q  ♠J  ♠A  ♥A  ♣3
  ♣4  ♣5  ♠T  ♥Q  ♥4  ♣A  ♦4  ♠7
  ♠3  ♦T  ♠4  ♥T  ♥8  ♣2  ♥J  ♦7
  ♦6  ♠8  ♦8  ♠Q  ♣6  ♦3  ♣8  ♣T
  ♠6  ♣9  ♥2  ♥6
Hand 617
  ♦7  ♦A  ♣5  ♠3  ♠5  ♣8  ♦2  ♥A
  ♦T  ♠7  ♦Q  ♣A  ♦6  ♥8  ♠A  ♥K
  ♥T  ♣Q  ♥3  ♦9  ♠6  ♦8  ♦3  ♣T
  ♦K  ♥5  ♠9  ♣3  ♠8  ♥7  ♦4  ♠J
  ♣4  ♠Q  ♣9  ♥9  ♣7  ♥6  ♣2  ♠2
  ♠4  ♠T  ♥2  ♦5  ♣J  ♣6  ♥J  ♥Q
  ♦J  ♠K  ♣K  ♥4

[edit] Tcl

Translation of: C
proc rnd {{*r seed}} {
upvar 1 ${*r} r
expr {[set r [expr {($r * 214013 + 2531011) & 0x7fffffff}]] >> 16}
}
proc show cards {
set suits {\u2663 \u2666 \u2665 \u2660}
set values {A 2 3 4 5 6 7 8 9 T J Q K}
for {set i 0} {$i < 52} {incr i} {
set c [lindex $cards $i]
puts -nonewline [format " \033\[%dm%s\033\[m%s" [expr {32-(1+$c)%4/2}] \
[lindex $suits [expr {$c % 4}]] [lindex $values [expr {$c / 4}]]]
if {($i&7)==7 || $i==51} {puts ""}
}
}
proc deal {seed} {
for {set i 0} {$i < 52} {incr i} {lappend cards [expr {51 - $i}]}
for {set i 0} {$i < 51} {incr i} {
set j [expr {51 - [rnd]%(52-$i)}]
set tmp [lindex $cards $i]
lset cards $i [lindex $cards $j]
lset cards $j $tmp
}
return $cards
}
 
if {![scan =[lindex $argv 0]= =%d= s] || $s <= 0} {
set s 11982
}
set cards [deal $s]
puts "Hand $s"
show $cards

[edit] UNIX Shell

Works with: zsh
test $# -gt 0 || set -- $((RANDOM % 32000))
for seed; do
print Game $seed:
 
# Shuffle deck.
deck=({A,{2..9},T,J,Q,K}{C,D,H,S})
for i in {52..1}; do
((seed = (214013 * seed + 2531011) & 0x7fffffff))
((j = (seed >> 16) % i + 1))
t=$deck[$i]
deck[$i]=$deck[$j]
deck[$j]=$t
done
 
# Deal cards.
print -n ' '
for i in {52..1}; do
print -n ' '$deck[$i]
((i % 8 == 5)) && print -n $'\n '
done
print
done
Output:
$ zsh freecell.sh 80388
Game 80388:
  QC 5H AS 7H 8S 4S 4H 3H
  QD 3S 2C 2S 7D AH 6D 3D
  QS TH QH 3C 2H JS 5D 5C
  AD TD 6H JD 5S 7S 4D 7C
  9S KC TC KH 8C 9D 8D JH
  KS AC KD 9C 9H 6C JC 2D
  4C 8H TS 6S

[edit] XPL0

include c:\cxpl\codes;                  \intrinsic 'code' declarations
string 0; \use zero-terminated string convention
int RandState;
 
func Rand; \Random number in range 0 to 32767
[RandState:= (214013*RandState + 2531011) & $7FFF_FFFF;
return RandState >> 16;
];
 
int Card, Deck(52), Size;
char Suit, Rank;
[RandState:= IntIn(8); \seed RNG with number from command line
for Card:= 0 to 52-1 do Deck(Card):= Card; \create array of 52 cards
Rank:= "A23456789TJQK";
Suit:= "CDHS";
Size:= 52;
repeat Card:= rem(Rand/Size); \choose a random card
ChOut(0, Rank(Deck(Card)/4)); \deal it by showing it
ChOut(0, Suit(rem(0)));
if rem(Size/8)=5 then CrLf(0) else ChOut(0, ^ );
Size:= Size-1; \one less card in deck
Deck(Card):= Deck(Size); \replace dealt card with last card
until Size = 0; \all cards have been dealt
]

Output:

7D AD 5C 3S 5S 8C 2D AH
TD 7S QD AC 6D 8H AS KH
TH QC 3H 9D 6S 8D 3D TC
KD 5H 9S 3C 8S 7H 4D JS
4C QS 9C 9H 7C 6H 2C 2S
4S TS 2H 5D JC 6C JH QH
JD KS KC 4H 

[edit] zkl

var suits=T(0x1F0D1,0x1F0C1,0x1F0B1,0x1F0A1); //unicode 🃑,🃁,🂱,🂡
 
var seed=1; const RMAX32=(1).shiftLeft(31) - 1;
fcn rnd{ (seed=((seed * 214013 + 2531011).bitAnd(RMAX32))).shiftRight(16) }
 
fcn game(n){
seed = n;
deck:=(0).pump(52,List,'wrap(n){ if(n>=44) n+=4; // I want JQK, not JCQ
Compiler.Tokenizer.intToUTF8(suits[n%4]+n/4)}).copy();
[52..1,-1].pump(Void,'wrap(len){ deck.swap(len-1,rnd()%len); });
deck.reverse();
println("Game #",n);
foreach n in ([0..51,8]){ deck[n,8].concat(" ").println(); }
}
 
game(1);
game(617);
 
Output:
Game #1
🃋 🃂 🂹 🃛 🃅 🂷 🃗 🂵
🃎 🃞 🂩 🂥 🃁 🃝 🂾 🂳
🂢 🂮 🃉 🃍 🂫 🂡 🂱 🃓
🃔 🃕 🂪 🂽 🂴 🃑 🃄 🂧
🂣 🃊 🂤 🂺 🂸 🃒 🂻 🃇
🃆 🂨 🃈 🂭 🃖 🃃 🃘 🃚
🂦 🃙 🂲 🂶
Game #617
🃇 🃁 🃕 🂣 🂥 🃘 🃂 🂱
🃊 🂧 🃍 🃑 🃆 🂸 🂡 🂾
🂺 🃝 🂳 🃉 🂦 🃈 🃃 🃚
🃎 🂵 🂩 🃓 🂨 🂷 🃄 🂫
🃔 🂭 🃙 🂹 🃗 🂶 🃒 🂢
🂤 🂪 🂲 🃅 🃛 🃖 🂻 🂽
🃋 🂮 🃞 🂴
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox