Deal cards for FreeCell: Difference between revisions
Content added Content deleted
(Restoring visibility of task description formulae (lost in under-tested cosmetic edits at 21:04, 15 May 2016)) |
(gathered C# which is in two places.) |
||
Line 369: | Line 369: | ||
return 0; |
return 0; |
||
}</lang> |
}</lang> |
||
=={{header|C sharp|C#}}== |
|||
Longer than it absolutely needs to be because I split out several independently useful classes. |
|||
<lang csharp>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)); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>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 |
|||
</pre> |
|||
===Shorter version=== |
|||
Shorter than the previous version. Adds a few classes, but stays closer to the gist of the C version. |
|||
<lang csharp> |
|||
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)); |
|||
} |
|||
} |
|||
} |
|||
</lang> |
|||
{{out}} |
|||
<pre>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♥ |
|||
</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 649: | Line 922: | ||
(show-deck 1) |
(show-deck 1) |
||
(show-deck 617)</lang> |
(show-deck 617)</lang> |
||
=={{header|C sharp|C#}}== |
|||
Longer than it absolutely needs to be because I split out several independently useful classes. |
|||
<lang csharp>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)); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>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 |
|||
</pre> |
|||
=={{header|C sharp|C# (shorter)}}== |
|||
Shorter than the previous version. Adds a few classes, but stays closer to the gist of the C version. |
|||
<lang csharp> |
|||
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)); |
|||
} |
|||
} |
|||
} |
|||
</lang> |
|||
{{out}} |
|||
<pre>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♥ |
|||
</pre> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
Line 1,124: | Line 1,124: | ||
4S TS 2H 5D JC 6C JH QH |
4S TS 2H 5D JC 6C JH QH |
||
JD KS KC 4H</pre> |
JD KS KC 4H</pre> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
<lang freebasic>' version 04-11-2016 |
<lang freebasic>' version 04-11-2016 |