Deal cards for FreeCell

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

Task
Deal cards for FreeCell
You are encouraged to solve this task according to the task description, using any language you may know.

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:

  • is in range 0 to 32767.
  • Rosetta Code has another task, linear congruential generator, with code for this RNG in several languages.


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.

Related tasks:


11l

Translation of: Python
F randomGenerator(=seed, n)
   [Int] r
   -V max_int32 = 7FFF'FFFF
   seed = seed [&] max_int32

   L r.len < n
      seed = (seed * 214013 + 2531011) [&] max_int32
      r [+]= seed >> 16

   R r

F deal(seed)
   V nc = 52
   V cards = Array((nc - 1 .< -1).step(-1))
   V rnd = randomGenerator(seed, nc)
   L(r) rnd
      V j = (nc - 1) - r % (nc - L.index)
      swap(&cards[L.index], &cards[j])
   R cards

F show(cards)
   V l = cards.map(c -> ‘A23456789TJQK’[Int(c / 4)]‘’‘CDHS’[c % 4])
   L(i) (0 .< cards.len).step(8)
      print((l[i .< i + 8]).join(‘ ’))

:start:
V seed = I :argv.len == 2 {Int(:argv[1])} E 11982
print(‘Hand #.’.format(seed))
V 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

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

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♥  

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:

 

Befunge

vutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDC
>4$0" :rebmun emaG">:#,_$&>55+,>"O?+"**2+*"C4'' "**v
>8%!492*+*48*\-,1-:11p0g\0p11g#^_@A23456789TJQKCDHS*
^+3:g11,g2+"/"%4,g2+g14/4:-\"v"g0:%g11+*-/2-10-1*<>+
>8#8*#4*#::#%*#*/#*:#*0#:\#*`#:8#::#*:#8*#8:#2*#+^#<
Output:
Game number: 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

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♥ 

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;
}

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

Shorter version

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♥ 

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

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

Ceylon

shared void freeCellDeal() {

	//a function that returns a random number generating function
	function createRNG(variable Integer state) => 
			() => (state = (214_013 * state + 2_531_011) % 2^31) / 2^16;
	
	void deal(Integer num) {
		// create an array with a list comprehension
		variable value deck = Array {
			for(rank in "A23456789TJQK")
			for(suit in "CDHS")
			"``rank````suit``"
		};
		value rng = createRNG(num);
		for(i in 1..52) {
			value index = rng() % deck.size;
			assert(exists lastIndex = deck.lastIndex);
			//swap the random card with the last one
			deck.swap(index, lastIndex);
			//print the last one
			process.write("``deck.last else "missing card"`` " );
			if(i % 8 == 0) {
				print("");
			}
			//and shrink the array to remove the last card
			deck = deck[...lastIndex - 1];
		}
	}
	
	deal(1);
	print("\n");
	deal(617);
}

Clojure

(def deck (into [] (for [rank "A23456789TJQK" suit "CDHS"] (str rank suit))))

(defn lcg [seed] 
  (map #(bit-shift-right % 16) 
    (rest (iterate #(mod (+ (* % 214013) 2531011) (bit-shift-left 1 31)) seed))))

(defn gen [seed]
  (map (fn [rnd rng] (into [] [(mod rnd rng) (dec rng)]))
    (lcg seed) (range 52 0 -1)))

(defn xchg [v [src dst]] (assoc v dst (v src) src (v dst)))

(defn show [seed] (map #(println %) (partition 8 8 "" 
  (reverse (reduce xchg deck (gen seed))))))

(show 1)

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)

D

Translation of: C
import std.stdio, std.conv, std.algorithm, std.range;

struct RandomGenerator {
    uint seed = 1;

    @property uint next() pure nothrow @safe @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 @safe @nogc {
        enum int nc = cards.length; // Must be signed for iota.
        nc.iota.retro.copy(cards[]);

        auto rnd = RandomGenerator(seed);
        foreach (immutable i, ref c; cards)
            c.swap(cards[(nc - 1) - rnd.next % (nc - i)]);
    }

    void show() const @safe {
        writefln("%(%-( %s%)\n%)",
                 cards[]
                 .chunks(8)
                 .map!(row => row.map!(c => only("A23456789TJQK"[c / 4],
                                                 "CDHS"[c % 4]))));
    }
}

void main(in string[] args) @safe {
    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

Delphi

Translation of: C#
program Deal_cards_for_FreeCell;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TRandom = record
    Seed: Int64;
    function Next: Integer;
  end;

  TCard = record
    const
      kSuits = '♣♦♥♠';
      kValues = 'A23456789TJQK';
    var
      Value: Integer;
      Suit: Integer;
    procedure Create(rawvalue: Integer); overload;
    procedure Create(value, suit: Integer); overload;
    procedure Assign(other: TCard);
    function ToString: string;
  end;

  TDeck = record
    Cards: TArray<TCard>;
    procedure Create(Seed: Integer);
    function ToString: string;
  end;

{ TRandom }

function TRandom.Next: Integer;
begin
  Seed := ((Seed * 214013 + 2531011) and Integer.MaxValue);
  Result := Seed shr 16;
end;

{ TCard }

procedure TCard.Create(rawvalue: Integer);
begin
  Create(rawvalue div 4, rawvalue mod 4);
end;

procedure TCard.Assign(other: TCard);
begin
  Create(other.Value, other.Suit);
end;

procedure TCard.Create(value, suit: Integer);
begin
  self.Value := value;
  self.Suit := suit;
end;

function TCard.ToString: string;
begin
  result := format('%s%s', [kValues[value + 1], kSuits[suit + 1]]);
end;

{ TDeck }

procedure TDeck.Create(Seed: Integer);
var
  r: TRandom;
  i, j: integer;
  tmp: Tcard;
begin
  r.Seed := Seed;
  SetLength(Cards, 52);
  for i := 0 to 51 do
    Cards[i].Create(51 - i);
  for i := 0 to 50 do
  begin
    j := 51 - (r.Next mod (52 - i));
    tmp.Assign(Cards[i]);
    Cards[i].Assign(Cards[j]);
    Cards[j].Assign(tmp);
  end;
end;

function TDeck.ToString: string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to length(Cards) - 1 do
  begin
    Result := Result + Cards[i].ToString;
    if i mod 8 = 7 then
      Result := Result + #10
    else
      Result := Result + ' ';
  end;
end;

var
  Deck: TDeck;

begin
  Deck.Create(1);
  Writeln('Deck 1'#10, Deck.ToString, #10);
  Deck.Create(617);
  Writeln('Deck 617'#10, Deck.ToString);
  readln;
end.
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♥

EasyLang

Translation of: Phix
global seed .
func xrnd .
   seed = (seed * 214013 + 2531011) mod 0x80000000
   return seed div 0x10000
.
len cards[] 52
proc deal game_num . .
   print "hand " & game_num
   seed = game_num
   for i = 1 to 52
      cards[i] = 52 - i
   .
   for i = 1 to 51
      j = 52 - xrnd mod (53 - i)
      swap cards[i] cards[j]
   .
.
suits$[] = strchars "CDHS"
ranks$[] = strchars "A23456789TJQK"
# 
proc show . .
   for idx = 1 to 52
      rank = cards[idx] div 4 + 1
      suit = cards[idx] mod 4 + 1
      write ranks$[rank] & suits$[suit] & " "
      if idx mod1 13 = 13
         print ""
      .
   .
   print ""
.
deal 1 ; show
deal 617 ; show

Elixir

Translation of: Ruby
defmodule FreeCell do
  import Bitwise
  
  @suits ~w( C D H S )
  @pips ~w( A 2 3 4 5 6 7 8 9 T J Q K )
  @orig_deck for pip <- @pips, suit <- @suits, do: pip <> suit
  
  def deal(games) do
    games = if length(games) == 0, do: [Enum.random(1..32000)], else: games
    Enum.each(games, fn seed ->
      IO.puts "Game ##{seed}"
      Enum.reduce(52..2, {seed,@orig_deck}, fn len,{state,deck} ->
        state = ((214013 * state) + 2531011) &&& 0x7fff_ffff
        index = rem(state >>> 16, len)
        last = len - 1
        {a, b} = {Enum.at(deck, index), Enum.at(deck, last)}
        {state, deck |> List.replace_at(index, b) |> List.replace_at(last, a)}
      end)
      |> elem(1)
      |> Enum.reverse
      |> Enum.chunk(8,8,[])
      |> Enum.each(fn row -> Enum.join(row, " ") |> IO.puts end)
      IO.puts ""
    end)
  end
end

System.argv |> Enum.map(&String.to_integer/1)
|> FreeCell.deal
Output:
C:\Elixir>elixir freecell.exs 1 617
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

ERRE

PROGRAM FREECELL

!$DOUBLE

DIM CARDS%[52]

PROCEDURE XRANDOM(SEED->XRND)
    POW31=2^31
    POW16=2^16
    SEED=SEED*214013+2531011
    SEED=SEED-POW31*INT(SEED/POW31)
    XRND=INT(SEED/POW16)
END PROCEDURE

PROCEDURE DEAL(CARDS%[],GAME_NUM)
    LOCAL I%,J%,S%
    SEED=GAME_NUM
    FOR I%=1 TO 52 DO
      CARDS%[I%]=52-I%
    END FOR
    FOR I%=1 TO 51 DO
      XRANDOM(SEED->XRND)
      J%=52-XRND MOD (53-I%)
      S%=CARDS%[I%]
      CARDS%[I%]=CARDS%[J%]
      CARDS%[J%]=S%
    END FOR
END PROCEDURE

PROCEDURE SHOW(CARDS%[])
    LOCAL INDEX%
    FOR INDEX%=1 TO 52 DO
      PRINT(MID$(SUITS$,CARDS%[INDEX%] MOD 4+1,1);MID$(NUMS$,CARDS%[INDEX%] DIV 4+1,1);" ";)
      IF INDEX% MOD 8=0 OR INDEX%=52 THEN
        PRINT
      END IF
    END FOR
END PROCEDURE

BEGIN
    PRINT(CHR$(12);)
    SUITS$="♣♦♥♠"
    NUMS$="A23456789TJQK"
    GAME_NUM=1982  ! if missing command line
    IF CMDLINE$<>"" THEN GAME_NUM=VAL(CMDLINE$) END IF
    SEED=1
    DEAL(CARDS%[],GAME_NUM)
    PRINT("Hand ";GAME_NUM)
    SHOW(CARDS%[])
END PROGRAM
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

F#

The deal for this one is a little arduous, as we're using a list and maintain an immutable state. Of course, an array could be used, but what's the fun in that?

let msKindaRand seed =
  let state = ref seed
  (fun (_:unit) ->
      state := (214013 * !state + 2531011) &&& System.Int32.MaxValue
      !state / (1<<<16))

let unshuffledDeck = [0..51] |> List.map(fun n->sprintf "%c%c" "A23456789TJQK".[n / 4] "CDHS".[n % 4])

let deal boot idx =
  let (last,rest) = boot |> List.rev |> fun xs->(List.head xs),(xs |> List.tail |> List.rev)
  if idx=((List.length boot) - 1) then last, rest
  else
    rest
    |> List.mapi (fun i x -> i,x)
    |> List.partition (fst >> ((>) idx))
    |> fun (xs,ys) -> (List.map snd xs),(List.map snd ys)
    |> fun (xs,ys) -> (List.head ys),(xs @ last::(List.tail ys))

let game gameNo =
  let rnd = msKindaRand gameNo
  [52..-1..1]
  |> List.map (fun i->rnd() % i)
  |> List.fold (fun (dealt, boot) idx->deal boot idx |> fun (x,xs) -> (x::dealt, xs)) ([],unshuffledDeck)
  |> fst |> List.rev
  |> List.chunkBySize 8
  |> List.map (String.concat " ")
  |> String.concat "\n"
  |> printfn "Game #%d\n%s\n" gameNo


[1; 617] |> List.iter 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

Factor

USING: formatting grouping io kernel literals make math
math.functions namespaces qw sequences sequences.extras ;
IN: rosetta-code.freecell

CONSTANT: max-rand-ms $[ 1 15 shift 1 - ]
CONSTANT: suits qw{ C D H S }
CONSTANT: ranks qw{ A 2 3 4 5 6 7 8 9 T J Q K }
SYMBOL: seed

: (random) ( n1 n2 -- n3 ) seed get * + dup seed set ;

: rand-ms ( -- n )
    max-rand-ms 2531011 214013 (random) -16 shift bitand ;

: init-deck ( -- seq )
    ranks suits [ append ] cartesian-map concat V{ } like ;

: swap-cards ( seq -- seq' )
    rand-ms over length [ mod ] [ 1 - ] bi pick exchange ;

: (deal) ( seq -- seq' )
    [ [ swap-cards dup pop , ] until-empty ] { } make ;

: deal ( game# -- seq ) seed set init-deck (deal) ;

: .cards ( seq -- ) 8 group [ [ write bl ] each nl ] each nl ;

: .game ( game# -- ) dup "Game #%d\n" printf deal .cards ;

: freecell ( -- ) 1 617 [ .game ] bi@ ;

MAIN: freecell
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 

Fortran

Works with: Fortran version 95 and later

Using the lcgs module from Linear congruential generator#Fortran:

module Freecell
  use lcgs
  implicit none

  character(4)  :: suit = "CDHS"
  character(13) :: rank = "A23456789TJQK"
  character(2) :: deck(0:51)

contains

subroutine Createdeck()
  integer :: i, j, n

  n = 0
  do i = 1, 13
    do j = 1, 4
      deck(n) = rank(i:i) // suit(j:j)
      n = n + 1
    end do
  end do

end subroutine
 
subroutine Freecelldeal(game)
  integer, intent(in) :: game
  integer(i64) :: rnum
  integer :: i, n
  character(2) :: tmp

  call Createdeck()
  rnum = msrand(game)

  do i = 51, 1, -1
    n = mod(rnum, i+1)
    tmp = deck(n)
    deck(n) = deck(i)
    deck(i) = tmp
    rnum = msrand()
  end do

  write(*, "(a, i0)") "Game #", game
  write(*, "(8(a, tr1))") deck(51:0:-1)
  write(*,*)

end subroutine  
end module Freecell

program Freecell_test
  use Freecell
  implicit none

  call Freecelldeal(1)
  call Freecelldeal(617)
   
end program
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

FreeBASIC

' version 04-11-2016
' compile with: fbc -s console

' to seed ms_lcg(seed > -1)
' to get random number ms_lcg(-1) or ms_lcg() or just ms_lcg
Function ms_lcg(seed As Integer = -1) As UInteger

    Static As UInteger ms_state

    If seed <> -1 Then
        ms_state = seed Mod 2 ^ 31
    Else
        ms_state = (214013 * ms_state + 2531011) Mod 2 ^ 31
    End If

    Return ms_state Shr 16

End Function

' ------=< MAIN >=------

Dim As UByte card(51)
Dim As String suit = "CDHS", value = "A23456789TJQK"
Dim As Long i, c, s, v, game = 1
Dim As ULong game_nr(1 To 2) = { 1, 617}

Do

    ms_lcg(game_nr(game))       ' seed generator
    Print "game #"; game_nr(game)
    game = game + 1

    For i = 0 To 51             ' set up the cards
        card(i) = i
    Next

    For i = 51 To 0 Step -1     ' shuffle
        c = ms_lcg Mod (i +1)
        Swap card(i), card(c)
    Next

    c = 0
    Do
        For i = 0 To 7
            s = card(51 - c) Mod 4
            v = card(51 - c) \ 4
            Print Chr(value[v]); Chr(suit[s]); " ";
            c = c +1
            If c > 51 Then Exit Do
        Next
        Print
    Loop
    Print : Print

Loop Until game > UBound(game_nr)


' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
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

Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website.

In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.

Solution

There is no need to remove from a deal to be added to another one, it can be performed on a single array. It is and iteration from 52 to 1 indicating the end of the first array, and therefore the start of a second one after each swap. The only inconvenience is that second array contains the information in reversed order, but when it is shown it is also read in reversed order.

The number 127,185 is the decimal number of the 🃑 Unicode character.

In the Unicode playing cards characters, there is the Knight, between the Jack and Queen suits, which is not used, so it is skipped in the order.

 

Test case. The —only— impossible deal #11982 in the original version of FreeCell for windows:

 

 

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

Groovy

class FreeCell{
    int seed
    
    List<String> createDeck(){
        List<String> suits = ['♣','♦','♥','♠']
        List<String> values = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']
        return [suits,values].combinations{suit,value -> "$suit$value"}
    }
    
    int random() {
        seed = (214013 * seed + 2531011) & Integer.MAX_VALUE
        return seed >> 16
    }
    
    List<String> shuffledDeck(List<String> cards) {
        List<String> deck = cards.clone()
        
       (deck.size() - 1..1).each{index ->
            int r = random() % (index + 1)
            deck.swap(r, index)
        }
        
        return deck
    }
    
    List<String> dealGame(int seed = 1){
        this.seed= seed
        List<String> cards = shuffledDeck(createDeck())
        
        (1..cards.size()).each{ number->
            print "${cards.pop()}\t"
            if(number % 8 == 0) println('')
        }
        
        println('\n')
    }
}

def freecell = new FreeCell()
freecell.dealGame()
freecell.dealGame(617)
Output:
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	♠10	♥Q	♥4	♣A	♦4	♠7	
♠3	♦10	♠4	♥10	♥8	♣2	♥J	♦7	
♦6	♠8	♦8	♠Q	♣6	♦3	♣8	♣10	
♠6	♣9	♥2	♥6		

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

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

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

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 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
   show deal srnd 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

Java

import java.util.Arrays;

public class Shuffler {
	
	private int seed;
	
	private String[] deck = {
			"AC", "AD", "AH", "AS",
			"2C", "2D", "2H", "2S",
			"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
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 

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("");
}

Julia

Translation of: Lua
const rank  = split("A23456789TJQK", "")
const suit  = split("♣♦♥♠", "")
const deck  = Vector{String}()

const mslcg = [0]
rng() = (mslcg[1] = ((mslcg[1] * 214013 + 2531011) & 0x7fffffff)) >> 16

initdeck() = for r in rank, s in suit push!(deck, "$r$s") end

function deal(num = rand(UInt,1)[1] % 32000 + 1)
    initdeck()
    mslcg[1] = num
    println("\nGame # ", num)
    while length(deck) > 0
        choice = rng() % length(deck) + 1
        deck[choice], deck[end] = deck[end], deck[choice]
        print(" ", pop!(deck), length(deck) % 8 == 4 ? "\n" : "")
    end
end

deal(1)
deal(617)
deal()
Output:

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♥

Game # 20065

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

Kotlin

// version 1.1.3

class Lcg(val a: Long, val c: Long, val m: Long, val d: Long, val s: Long) {
    private var state = s
    
    fun nextInt(): Long {
        state = (a * state + c) % m
        return state / d
    }
}

const val CARDS  = "A23456789TJQK"
const val SUITS  = "♣♦♥♠"

fun deal(): Array<String?> {
    val cards = arrayOfNulls<String>(52)
    for (i in 0 until 52) {      
       val card = CARDS[i / 4]
       val suit = SUITS[i % 4]
       cards[i] = "$card$suit"
    }
    return cards
}

fun game(n: Int) {
    require(n > 0)
    println("Game #$n:") 
    val msc = Lcg(214013, 2531011, 1 shl 31, 1 shl 16, n.toLong())
    val cards = deal()
    for (m in 52 downTo 1) {
        val index = (msc.nextInt() % m).toInt()
        val temp = cards[index]
        cards[index] = cards[m - 1]
        print("$temp  ")
        if ((53 - m) % 8 == 0) println()
    }     
    println("\n")       
}

fun main(args: Array<String>) {
    game(1)
    game(617)
}
Output:
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♥  

; Linear congruential random number generator
make "_lcg_state 0

to seed_lcg :seed
  make "_lcg_state :seed
end

to sample_lcg
  make "_lcg_state modulo sum product 214013 :_lcg_state 2531011 2147483648
  output int quotient :_lcg_state 65536
end

; FreeCell
to card_from_number :number
  output word item sum 1 int quotient :number 4 "A23456789TJQK item sum 1 modulo :number 4 "CDHS 
end

to generate_deal :number
  (local "deck "size "index "deal)
  seed_lcg :number
  make "deck []
  repeat 52 [
    make "deck lput difference # 1 :deck
  ]
  make "deck listtoarray :deck
  make "deal []
  repeat 52 [
    make "size difference 53 #
    make "index sum 1 modulo sample_lcg :size
    make "deal lput item :index :deck :deal
    setitem :index :deck item :size :deck
  ]
  output :deal
end

to print_deal :number
  (local "deal "i "j "index)
  make "deal generate_deal :number
  repeat 7 [
    make "i difference # 1
    repeat (ifelse [equal? :i 6] 4 8) [
      make "j difference # 1
      make "index (sum 1 product :i 8 :j)
      type (word (card_from_number item :index :deal) "| |)
    ]
    print "||
  ]
end

print [Game #1]
print_deal 1
print "||
print [Game #617]
print_deal 617
print "||
bye
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

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

Mathematica / Wolfram Language

next[last_] := Mod[214013 last + 2531011, 2^31];
deal[n_] := 
  Module[{last = n, idx, 
    deck = StringJoin /@ 
      Tuples[{{"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", 
         "Q", "K"}, {"C", "D", "H", "S"}}], res = {}}, 
   While[deck != {}, last = next[last]; 
    idx = Mod[BitShiftRight[last, 16], Length[deck]] + 1; 
    deck = ReplacePart[deck, {idx -> deck[[-1]], -1 -> deck[[idx]]}]; 
    AppendTo[res, deck[[-1]]]; deck = deck[[;; -2]]]; res];
format[deal_] := Grid[Partition[deal, 8, 8, {1, 4}, Null]];
Print[format[deal[1]]];
Print[format[deal[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

Nim

Translation of: Python
import sequtils, strutils, os
 
proc randomGenerator(seed: int): iterator: int =
  var state = seed
  return iterator: int =
    while true:
      state = (state * 214013 + 2531011) and int32.high
      yield state shr 16
 
proc deal(seed: int): 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: seq[int]) =
  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

Objeck

Translation of: C#
class FreeCell {
  function : Main(args : String[]) ~ Nil {
    Deal(1)->PrintLine();
    Deal(617)->PrintLine();
  }
  
  function : Deal(seed : Int) ~ String {
    deck := Deck->New(seed)->ToString();
    return "Game #{$seed}:\n{$deck}\n";
  }
}

class Deck {
  @cards : Card[];
  
  New(seed : Int) {
    r := Random->New(seed);
    
    @cards := Card->New[52];
    for(i := 0; i < 52; i+= 1;) {
      @cards[i] := Card->New(51 - i);
    };
    
    for(i := 0; i < 51; i += 1;) {
      j := 51 - r->Next() % (52 - i);
      tmp := @cards[i]; @cards[i] := @cards[j]; @cards[j] := tmp;
    };
  }
  
  method : public : ToString() ~ String {
    buffer := "";
    
    each(i : @cards) {
      buffer += @cards[i]->ToString();
      buffer += (i % 8 = 7 ? "\n" : " ");
    };
    
    return buffer;
  }
  
  
}

class Random {
  @seed : Int;
  
  New(seed : Int) {
    @seed := seed;
  }
  
  method : public : Next() ~ Int {
    @seed := (@seed * 214013 + 2531011) and Int->MaxSize();
    return @seed >> 16;
  }
}

class Card {
  @value : Int;
  @suit : Int;
  
  New(value : Int) {
    @value := value / 4; @suit := value % 4;
  }
  
  method : public : ToString() ~ String {
    suits := "♣♦♥♠"; values := "A23456789TJQK";    
    value := values->Get(@value); suit := suits->Get(@suit);    
    return "{$value}{$suit}";
  }
}

Output:

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♥

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♥ 

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

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]
  )
};

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;

Phix

Translation of: ERRE
with javascript_semantics
atom seed
 
function xrnd()
    seed = and_bits(seed*214013+2531011,#7FFFFFFF)
    return floor(seed/power(2,16))
end function
 
sequence cards = repeat(0,52)
 
procedure deal(integer game_num)
    seed = game_num
    for i=1 to 52 do
        cards[i] = 52-i
    end for
    for i=1 to 51 do
        integer j = 52-mod(xrnd(),53-i)
        integer s = cards[i]
        cards[i] = cards[j]
        cards[j] = s
    end for
end procedure
 
constant suits = "CDHS",
         ranks = "A23456789TJQK"
 
procedure show()
    for idx=1 to 52 do
        integer rank = floor(cards[idx]/4)+1
        integer suit = mod(cards[idx],4)+1
        integer eol = remainder(idx-1,13)=12
        printf(1,"%c%c%s",{ranks[rank],suits[suit],iff(eol?"\n":" ")})
    end for
end procedure
 
integer game_num = 1
--integer game_num=617
deal(game_num)
printf(1,"hand %d\n",{game_num})
show()
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

PHP

class FreeCell_Deal {

    protected $deck = array( 
        'AC', 'AD', 'AH', 'AS', '2C', '2D', '2H', '2S', '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'
    );
    
    protected $game;        // Freecell Game Number
    protected $state;       // Current state of the LCG

    public $deal = array(); // Generated card sequence to deal

    function __construct( $game ) {

        $this->game = max( min( $game, 32000 ), 1 );

        // seed RNG with game number
        $this->state = $this->game;

        while ( ! empty( $this->deck ) ) {

            // choose random card
            $i = $this->lcg_rnd() % count( $this->deck );

            // move random card to game deal pile
            $this->deal[] = $this->deck[ $i ];

            // move last card to random card spot
            $this->deck[ $i ] = end( $this->deck );

            // remove last card from deck
            array_pop( $this->deck );

        }

    }

    protected function lcg_rnd() {
        return ( $this->state = ( $this->state * 214013 + 2531011 ) % 2147483648 ) >> 16;
    }

    function print( $cols = 8 ) {
        echo str_pad( " Game " . $this->game . " ", $cols * 3 - 1, '=', STR_PAD_BOTH ), PHP_EOL;
        foreach ( array_chunk( $this->deal, $cols ) as $row ) {
            echo implode( " ", $row ), PHP_EOL;
        }
        echo PHP_EOL;
    }

}

$tests = array( 1, 617, 11982 );

foreach ( $tests as $game_num ) {
    $deal = new FreeCell_Deal( $game_num ); 
    $deal->print();
}
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

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

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

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

Python

Translation of: D
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 = list(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"[int(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__':
    from sys import argv
    seed = int(argv[1]) if len(argv) == 2 else 11982
    print("Hand {}".format(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

Quackery

MCR-seed and MCR-rand are defined at Linear congruential generator#Quackery.

  [ [ [] 52 times
      [ i^ join ] ]
    constant ]             is newpack  (     --> n )

  [ 2dup peek
    dip [ over -1 peek ]
    swap 2swap poke
    -1 poke ]              is to-end   ( [ n --> [ )

  [ [] swap
    52 times
      [ MCR-rand
        over size mod
        to-end
        -1 split
        swap dip join ]
     drop ]                is mixem    (   [ --> [ )

  [ 4 /mod
    $ "A23456789TJQK"
    rot peek emit
    $ "CDHS"
    swap peek emit ]       is echocard (   n -->   )

  [ witheach
      [ echocard
        i^ 8 mod 7 =
        iff cr else sp ] ] is echopack (   [ -->   )

  [ MCR-seed replace
    newpack
    mixem
    echopack ]             is deal     (   n -->   )

  ' [ 1 617 11982 ]
  witheach
    [ say "Deal #"
      dup echo cr
      deal cr cr ]
Output:
Deal #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 

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 

Deal #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 

R

## Linear congruential generator code not original - 
## copied from 
## http://www.rosettacode.org/wiki/Linear_congruential_generator#R
## altered to allow seed as an argument

library(gmp) # for big integers

rand_MS <- function(n = 1, seed = 1) {
  a <- as.bigz(214013)
  c <- as.bigz(2531011)
  m <- as.bigz(2^31)
  x <- rep(as.bigz(0), n)
  x[1] <- (a * as.bigz(seed) + c) %% m
  i <- 1
  while (i < n) {
    x[i+1] <- (a * x[i] + c) %% m
    i <- i + 1
  }
  as.integer(x / 2^16)
}

## =============================
## New code follows:
## =============================

dealFreeCell <- function(seedNum) {
  deck <- paste(rep(c("A",2,3,4,5,6,7,8,9,10,"J","Q","K"), each = 4), c("C","D","H","S"), sep = "")
  cards = rand_MS(52,seedNum)
  
  for (i in 52:1) {
    cardToPick <- (cards[53-i]%% i)+1 # R indexes from 1, not 0
    deck[c(cardToPick,i)] <- deck[c(i, cardToPick)]
  }

  deck <- rev(deck) # flip the deck to deal
  deal = matrix(c(deck,NA,NA,NA,NA),ncol = 8, byrow = TRUE)
  # using a matrix for simple printing, but requires filling with NA
  # if implementing as a game, a list for each pile would make more sense
  print(paste("Hand numer:",seedNum), quote = FALSE)
  print(deal, quote = FALSE, na.print = "")
}
Output:
> dealFreeCell(1)
[1] Hand numer: 1
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] JD   2D   9H   JC   5D   7H   7C   5H  
[2,] KD   KC   9S   5S   AD   QC   KH   3H  
[3,] 2S   KS   9D   QD   JS   AS   AH   3C  
[4,] 4C   5C   10S  QH   4H   AC   4D   7S  
[5,] 3S   10D  4S   10H  8H   2C   JH   7D  
[6,] 6D   8S   8D   QS   6C   3D   8C   10C 
[7,] 6S   9C   2H   6H                      
> dealFreeCell(617)
[1] Hand numer: 617
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 7D   AD   5C   3S   5S   8C   2D   AH  
[2,] 10D  7S   QD   AC   6D   8H   AS   KH  
[3,] 10H  QC   3H   9D   6S   8D   3D   10C 
[4,] KD   5H   9S   3C   8S   7H   4D   JS  
[5,] 4C   QS   9C   9H   7C   6H   2C   2S  
[6,] 4S   10S  2H   5D   JC   6C   JH   QH  
[7,] JD   KS   KC   4H 

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

Raku

(formerly Perl 6)

Works with: rakudo version 2016.05
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 flat(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
🃇 🃁 🃕 🂣 🂥 🃘 🃂 🂱
🃊 🂧 🃍 🃑 🃆 🂸 🂡 🂾
🂺 🃝 🂳 🃉 🂦 🃈 🃃 🃚
🃎 🂵 🂩 🃓 🂨 🂷 🃄 🂫
🃔 🂭 🃙 🂹 🃗 🂶 🃒 🂢
🂤 🂪 🂲 🃅 🃛 🃖 🂻 🂽
🃋 🂮 🃞 🂴

REXX

This REXX version supports EBCDIC and ASCII symbols (used for the cards).

It also supports any number for the number of columns   (default is 8).

See the   discussion   page for support for   game = ─1   and   game= ─2       (minus one and minus two).

/*REXX program deals cards for a specific  FreeCell solitaire  card game  (0 ──► 32767).*/
numeric digits 15                                /*ensure enough digits for the random #*/
parse arg game cols .                            /*obtain optional arguments from the CL*/
if game=='' | game==","  then game=1             /*No game specified?  Then use default.*/
if cols=='' | cols==","  then cols=8             /* " cols     "         "   "     "    */
state=game                                       /*seed random # generator with game num*/
if 8=='f8'x  then suit= "cdhs"                   /*EBCDIC?   Then use letters for suits.*/
             else suit= "♣♦♥♠"                   /* ASCII?     "   "  symbols  "    "   */
rank= 'A23456789tJQK'                            /*t  in the rank represents a ten (10).*/
pad=left('', 13)                                 /*used for indentation for the tableau.*/
say center('tableau for FreeCell game' game, 50, "─")   /*show title for FreeCell game #*/
say                                              /* [↓]  @  is an array of all 52 cards.*/
#=-1;  do   r=1  for length(rank)                /*build the deck  first   by the rank. */
         do s=1  for length(suit);       #=#+1   /*  "    "    "  secondly  "  "  suit. */
         @.#=substr(rank, r,1)substr(suit, s,1)  /*build the $ array one card at at time*/
         end   /*s*/                             /* [↑]  first card is number  0 (zero).*/
       end     /*r*/                             /* [↑]  build deck per FreeCell rules. */
$=pad                                            /*@: cards to be dealt, eight at a time*/
       do cards=51  by -1  for 52                /* [↓]  deal the cards for the tableau.*/
       ?=rand() // (cards+1)                     /*get next rand#;  card # is remainder.*/
       $=$ @.?;                 @.?=@.cards      /*swap two cards:  use random and last.*/
       if words($)==cols  then do;  say $; $=pad /*deal FreeCell cards for the tableau. */
                               end
       end   /*cards*/                           /*normally, 8 cards are dealt to a row.*/
                                                 /* [↓]  residual cards may exist.      */
if $\=''  then say $                             /*Any residual cards in the tableau ?  */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
rand:  state=(214013*state + 2531011) // 2**31;  return state % 2**16   /*FreeCell rand#*/

output   when using the default game number:   1

───────────tableau for FreeCell 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♥

output   when using the game number:   617

──────────tableau for FreeCell 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♥

RPL

Works with: RPL version HP-48R
« R→B { }
  1 13 FOR v 
     "A23456789TJQK" v DUP SUB
     1 4 FOR c 
        SWAP OVER "CDHS" c DUP SUB + + SWAP
     NEXT DROP
  NEXT 
  52 2 FOR j
     DUP j GET 
     SWAP ROT 214013 * 2531011 + # 7FFFFFFFh AND 
     DUP 4 ROLLD SRB SRB B→R
     j MOD 1 + GET
     LASTARG 4 ROLL PUT j ROT PUT
  -1 STEP
  REVLIST SWAP DROP
» 'DEAL' STO    @ ( game → { "card" .. "card" } ) 
1 DEAL
617 DEAL
Output:
2: { "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" }
1: { "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" }

RPL output device is limited to 22 characters per line, which prevents to display the deck as required.

Ruby

#   games = ARGV converted to Integer
#   No arguments? Pick any of first 32000 games.
begin
  games = ARGV.map {|s| Integer(s)}
rescue => err
  $stderr.puts err.inspect
  $stderr.puts "Usage: #{__FILE__} number..."
  abort
end
games.empty? and games = [rand(32000)]

# 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}.product(%w{C D H S}).map(&:join)

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(" ")}
  puts
end
Output:
$ ruby freecell.rb 1 165 
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 #165
 2D 2C 2H 5D 3C 6S JC 7S
 7H QD 6D KC 3D 9H 8H QC
 TS 5H JD 7D 6H 7C KH 4D
 QS 8S QH 9S 8D 3H JS AH
 AD KS TC KD 9D 4S 2S 3S
 TH 4C 9C 6C TD 4H 8C AC
 5C 5S JH AS

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,Heart,Spades
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

 

Rust

Based on JavaScript.

// Code available at https://rosettacode.org/wiki/Linear_congruential_generator#Rust
extern crate linear_congruential_generator;

use linear_congruential_generator::{MsLcg, Rng, SeedableRng};

// We can't use `rand::Rng::shuffle` because it uses the more uniform `rand::Rng::gen_range`
// (`% range` is subject to modulo bias).  If an exact match of the old dealer is not needed,
// `rand::Rng::shuffle` should be used.
fn shuffle<T>(rng: &mut MsLcg, deck: &mut [T]) {
    let len = deck.len() as u32;
    for i in (1..len).rev() {
        let j = rng.next_u32() % (i + 1);
        deck.swap(i as usize, j as usize);
    }
}

fn gen_deck() -> Vec<String> {
    const RANKS: [char; 13] = ['A','2','3','4','5','6','7','8','9','T','J','Q','K'];
    const SUITS: [char; 4] = ['C', 'D', 'H', 'S'];

    let render_card = |card: usize| {
        let (suit, rank) = (card % 4, card / 4);
        format!("{}{}", RANKS[rank], SUITS[suit])
    };

    (0..52).map(render_card).collect()
}

fn deal_ms_fc_board(seed: u32) -> Vec<String> {
    let mut rng = MsLcg::from_seed(seed);
    let mut deck = gen_deck();

    shuffle(&mut rng, &mut deck);
    deck.reverse();

    deck.chunks(8).map(|row| row.join(" ")).collect::<Vec<_>>()
}

fn main() {
    let seed = std::env::args()
        .nth(1)
        .and_then(|n| n.parse().ok())
        .expect("A 32-bit seed is required");

    for row in deal_ms_fc_board(seed) {
        println!(": {}", row);
    }
}

Scala

object Shuffler extends App {

  private val suits = Array("C", "D", "H", "S")
  private val values = Array("A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K")
  private val deck = values.flatMap(v => suits.map(s => s"$v$s"))

  private var seed: Int = _

  private def random() = {
    seed = (214013 * seed + 2531011) & Integer.MAX_VALUE
    seed >> 16
  }

  private def getShuffledDeck = {
    val d = deck.map(c => c)
    for(i <- deck.length - 1 until 0 by -1) {
      val r = random() % (i + 1)
      val card = d(r)
      d(r) = d(i)
      d(i) = card
    }
    d.reverse
  }

  def deal(seed: Int): Unit = {
    this.seed = seed
    getShuffledDeck.grouped(8).foreach(e => println(e.mkString(" ")))
  }

  deal(1)
  println
  deal(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

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

Swift

Swift 4.2. Largely based on the Objective-C example.

enum Suit : String, CustomStringConvertible, CaseIterable {
    case clubs = "C", diamonds = "D", hearts = "H", spades = "S"
    var description: String {
        return self.rawValue
    }
}
enum Rank : Int, CustomStringConvertible, CaseIterable {
    case ace=1, two, three, four, five, six, seven
    case eight, nine, ten, jack, queen, king
    var description: String {
        let d : [Rank:String] = [.ace:"A", .king:"K", .queen:"Q", .jack:"J", .ten:"T"]
        return d[self] ?? String(self.rawValue)
    }
}
struct Card : CustomStringConvertible {
    let rank : Rank, suit : Suit
    var description : String {
        return String(describing:self.rank) + String(describing:self.suit)
    }
    init(rank:Rank, suit:Suit) {
        self.rank = rank; self.suit = suit
    }
    init(sequence n:Int) {
        self.init(rank:Rank.allCases[n/4], suit:Suit.allCases[n%4])
    }
}
struct Deck : CustomStringConvertible {
    var cards = [Card]()
    init(seed:Int) {
        for i in (0..<52).reversed() {
            self.cards.append(Card(sequence:i))
        }
        struct MicrosoftLinearCongruentialGenerator {
            var seed : Int
            mutating func next() -> Int {
                self.seed = (self.seed * 214013 + 2531011) % (Int(Int32.max)+1)
                return self.seed >> 16
            }
        }
        var r = MicrosoftLinearCongruentialGenerator(seed: seed)
        for i in 0..<51 {
            self.cards.swapAt(i, 51-r.next()%(52-i))
        }
    }
    var description : String {
        var s = ""
        for (ix,c) in self.cards.enumerated() {
            s.write(String(describing:c))
            s.write(ix % 8 == 7 ? "\n" : " ")
        }
        return s
    }
}
let d1 = Deck(seed: 1)
print(d1)
let d617 = Deck(seed: 617)
print(d617)
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 

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

TypeScript

/* TypeScript code for dealing Microsoft FreeCell / FreeCell Pro deals.
 * Copyright by Shlomi Fish, 2011.
 * Released under the MIT/Expat License
 * ( http://en.wikipedia.org/wiki/MIT_License ).
 */
function perl_range(start: number, end: number): number[] {
    const ret: number[] = [];

    for (let i = start; i <= end; ++i) {
        ret.push(i);
    }

    return ret;
}

// 33 bit
const MAX_SEED: bigint = (BigInt(1) << BigInt(31 + 2)) - BigInt(1);
const X = BigInt(1) << BigInt(32);

/*
 * Microsoft C Run-time-Library-compatible Random Number Generator
 * */
class MSRand {
    private gamenumber: string;
    private _seed: bigint;
    private _seedx: bigint;
    constructor(args) {
        const that = this;
        that.gamenumber = args.gamenumber;
        const _seed = BigInt(that.gamenumber);
        that._seed = _seed;
        that._seedx = _seed < X ? _seed : _seed - X;
        return;
    }
    public getSeed(): bigint {
        const that = this;
        return that._seed;
    }
    private setSeed(seed: bigint): void {
        const that = this;
        that._seed = seed;
        return;
    }

    private _rando(): bigint {
        const that = this;
        that._seedx =
            (that._seedx * BigInt(214013) + BigInt(2531011)) & MAX_SEED;
        return (that._seedx >> BigInt(16)) & BigInt(0x7fff);
    }
    private _randp(): bigint {
        const that = this;
        that._seedx =
            (that._seedx * BigInt(214013) + BigInt(2531011)) & MAX_SEED;
        return (that._seedx >> BigInt(16)) & BigInt(0xffff);
    }
    public raw_rand(): bigint {
        const that = this;

        if (that._seed < X) {
            const ret = that._rando();
            return that._seed < BigInt(0x8) << BigInt(28)
                ? ret
                : ret | BigInt(0x8000);
        } else {
            return that._randp() + BigInt(1);
        }
    }
    public max_rand(mymax: bigint): bigint {
        const that = this;
        return that.raw_rand() % mymax;
    }
    public shuffle(deck: Array<any>): Array<any> {
        const that = this;
        if (deck.length) {
            let i = deck.length;
            while (--i) {
                const j = Number(that.max_rand(BigInt(i + 1)));
                const 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/Expat Licence.
 *
 * */

export function deal_ms_fc_board(gamenumber: string): string {
    const randomizer = new MSRand({
        gamenumber: gamenumber,
    });
    const num_cols: number = 8;

    const columns: Array<Array<number>> = perl_range(0, num_cols - 1).map(
        () => {
            return [];
        },
    );
    let deck: Array<number> = perl_range(0, 4 * 13 - 1);

    randomizer.shuffle(deck);

    deck = deck.reverse();

    for (let i = 0; i < 52; ++i) {
        columns[i % num_cols].push(deck[i]);
    }

    function render_card(card: number): String {
        const suit = card % 4;
        const rank = Math.floor(card / 4);

        return "A23456789TJQK".charAt(rank) + "CDHS".charAt(suit);
    }

    function render_column(col: Array<number>): String {
        return ": " + col.map(render_card).join(" ") + "\n";
    }

    return columns.map(render_column).join("");
}

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

VBA

Option Explicit
Private stateMS As Variant

Private Function ms() As Integer
    Dim temp1 As Variant, temp2 As Variant, temp3 As Variant
    temp1 = CDec(214013 * stateMS + 2531011)
    temp2 = temp1 / 2 ^ 31
    temp3 = CDec(WorksheetFunction.Floor_Precise(temp2))
    stateMS = temp1 - (2 ^ 31) * temp3
    ms = stateMS \ 2 ^ 16
End Function

Public Sub main()
    Dim i As Integer, j As Integer, k As Integer, s As Integer, v As Integer, no As Integer
    Dim tmpArr(0 To 51) As Integer
    Dim suit As String, value As String, row As String
    Dim gameNumbers As Variant
    
    suit = "CDHS"
    value = "A23456789TJQK"
    
    gameNumbers = Array(1, 617)
    
    For i = 0 To UBound(gameNumbers)
        
        stateMS = CDec(gameNumbers(i))
        
        For j = 0 To 51
            tmpArr(j) = j
        Next j
                
        For j = 51 To 0 Step -1
            no = ms Mod (j + 1)
            Call changePosition(tmpArr(), j, no)
        Next j
        
        Debug.Print "Game " & gameNumbers(i) & ":"
        k = 0
        Do While k < 52
            For j = 0 To 7
                s = 1 + tmpArr(51 - k) Mod 4
                v = 1 + tmpArr(51 - k) \ 4
                row = row & Mid(value, v, 1) & Mid(suit, s, 1) & IIf(j < 7 and k < 51, " ", "")
                k = k + 1
                If k > 51 Then Exit For
            Next j
            Debug.Print row
            row = ""
        Loop
        Debug.Print
        
    Next i
    
End Sub

Private Sub changePosition(ByRef arr() As Integer, pos1 As Integer, pos2 As Integer)
    Dim tempPos As String
    tempPos = arr(pos1)
    arr(pos1) = arr(pos2)
    arr(pos2) = tempPos
End Sub
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

Wren

Translation of: Kotlin
class Lcg {
    construct new(a, c, m, d, s) {
        _a = a
        _c = c
        _m = m
        _d = d
        _s = s
    }

    nextInt() {
        _s = (_a * _s + _c) % _m
        return _s / _d
    }
}

var CARDS = "A23456789TJQK"
var SUITS = "♣♦♥♠".toList

var deal = Fn.new {
    var cards = List.filled(52, null)
    for (i in 0...52) {
        var card = CARDS[(i/4).floor]
        var suit = SUITS[i%4]
        cards[i] = card + suit
    }
    return cards
}

var game = Fn.new { |n|
    if (n.type != Num || !n.isInteger || n <= 0) {
        Fiber.abort("Game number must be a positive integer.")
    }
    System.print("Game #%(n):")
    var msc = Lcg.new(214013, 2531011, 1<<31, 1<<16, n)
    var cards = deal.call()
    for (m in 52..1) {
        var index = (msc.nextInt() % m).floor
        var temp = cards[index]
        cards[index] = cards[m - 1]
        System.write("%(temp) ")
        if ((53 - m) % 8 == 0) System.print()
    }
    System.print("\n")
}

game.call(1)
game.call(617)
Output:
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♥ 

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 

Zig

const std = @import("std");

const Card = struct {
    value: u6 = 0,

    pub fn print(card: Card) void {
        const n: u8 = switch (card.value >> 2) {
            0 => 'A',
            1 => '2',
            2 => '3',
            3 => '4',
            4 => '5',
            5 => '6',
            6 => '7',
            7 => '8',
            8 => '9',
            9 => 'T',
            10 => 'J',
            11 => 'Q',
            12 => 'K',
            else => unreachable,
        };
        const s: u21 = switch (card.value & 0x3) {
            0 => '\u{2663}', // Club
            1 => '\u{2666}', // Diamond
            2 => '\u{2665}', // Heart
            3 => '\u{2660}', // Spade
            else => unreachable,
        };
        std.debug.print("{c}{u} ", .{ n, s });
    }
};

const Rand = struct {
    seed: u31 = 0,
    pub fn seed(rand: *Rand, value: u31) void {
        rand.seed = value;
    }

    pub fn next(rand: *Rand) u16 {
        const new_seed = rand.seed *% 214013 +% 2531011;
        rand.seed = new_seed;
        return @truncate(new_seed >> 16);
    }
};

pub fn deal(n: u31) void {
    const print = std.debug.print;
    var buffer: [52]u8 = undefined;
    var fba = std.heap.FixedBufferAllocator.init(&buffer);
    const allocator = fba.allocator();

    var deck = std.ArrayListUnmanaged(Card).initCapacity(allocator, 52) catch unreachable;
    var card: Card = .{};

    while (card.value < 52) : (card.value += 1) {
        deck.appendAssumeCapacity(card);
    }

    var col: usize = 0;
    var rand = Rand{ .seed = n };
    print("Deal {d}:\n", .{n});
    while (deck.items.len > 0) {
        card = deck.swapRemove(rand.next() % deck.items.len);
        card.print();
        col = (col + 1) % 8;
        if (col == 0)
            print("\n", .{});
    }
    print("\n\n", .{});
}

pub fn main() !void {
    deal(1);
    deal(617);
}
Output:
Deal 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♥

Deal 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♥

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
       (suits[n%4] + n/4).toString(8) }).copy();  // int-->UTF-8
   [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
🃇 🃁 🃕 🂣 🂥 🃘 🃂 🂱
🃊 🂧 🃍 🃑 🃆 🂸 🂡 🂾
🂺 🃝 🂳 🃉 🂦 🃈 🃃 🃚
🃎 🂵 🂩 🃓 🂨 🂷 🃄 🂫
🃔 🂭 🃙 🂹 🃗 🂶 🃒 🂢
🂤 🂪 🂲 🃅 🃛 🃖 🂻 🂽
🃋 🂮 🃞 🂴