June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -0,0 +1,41 @@
|
|||
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)
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
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}";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,26 @@
|
|||
/*REXX program deals cards for a specific FreeCell solitaire card game (0 ──► 32767).*/
|
||||
numeric digits 15 /*ensure enough digits for the random #*/
|
||||
parse arg g c . /*obtain optional arguments from the CL*/
|
||||
if g=='' | g=="," then g=1 /*No game specified? Then use default.*/
|
||||
if c=='' | c=="," then c=8 /* " cols " " " " */
|
||||
state=g /*seed random # generator with game num*/
|
||||
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).*/
|
||||
__=left('', 13) /*used for indentation for the tableau.*/
|
||||
say center('tableau for FreeCell game' g,50,"─") /*show a title for the FreeCell game #.*/
|
||||
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*/
|
||||
@.#=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. */
|
||||
$=__ /*@: cards to be dealt, eight at a time*/
|
||||
$=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($)==c then do; say $; $=__; end /*deal FreeCell cards for the tableau. */
|
||||
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 ? */
|
||||
|
|
|
|||
|
|
@ -1,59 +1,48 @@
|
|||
struct MSVCRandGen {
|
||||
seed: u32
|
||||
}
|
||||
// Code available at https://rosettacode.org/wiki/Linear_congruential_generator#Rust
|
||||
extern crate linear_congruential_generator;
|
||||
|
||||
impl MSVCRandGen {
|
||||
fn rand(&mut self) -> u32 {
|
||||
self.seed = (self.seed.wrapping_mul(214013).wrapping_add(2531011)) % 0x80000000;
|
||||
assert!(self.seed >> 16 < 32768);
|
||||
(self.seed >> 16) & 0x7FFF
|
||||
}
|
||||
fn max_rand(&mut self, mymax: u32) -> u32 {
|
||||
self.rand() % mymax
|
||||
}
|
||||
fn shuffle<T>(&mut self, deck: &mut [T]) {
|
||||
if deck.len() > 0 {
|
||||
let mut i = (deck.len() as u32) - 1;
|
||||
while i > 0 {
|
||||
let j = self.max_rand(i+1);
|
||||
deck.swap(i as usize, j as usize);
|
||||
i = i-1;
|
||||
}
|
||||
}
|
||||
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 deal_ms_fc_board(seed: u32) -> String {
|
||||
let mut randomizer = MSVCRandGen { seed: seed, };
|
||||
let num_cols = 8;
|
||||
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 mut columns = vec![Vec::new(); num_cols];
|
||||
let mut deck: Vec<_> = (0..4*13).collect();
|
||||
let render_card = |card: usize| {
|
||||
let (suit, rank) = (card % 4, card / 4);
|
||||
format!("{}{}", RANKS[rank], SUITS[suit])
|
||||
};
|
||||
|
||||
let rank_strings: Vec<char> = "A23456789TJQK".chars().collect();
|
||||
let suit_strings: Vec<char> = "CDHS".chars().collect();
|
||||
(0..52).map(render_card).collect()
|
||||
}
|
||||
|
||||
randomizer.shuffle(&mut deck);
|
||||
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();
|
||||
|
||||
for i in 0..52 {
|
||||
columns[i % num_cols].push(deck[i]);
|
||||
}
|
||||
|
||||
let render_card = |card: usize| -> String {
|
||||
let (suit, rank) = (card % 4, card / 4);
|
||||
format!("{}{}", rank_strings[rank], suit_strings[suit])
|
||||
};
|
||||
|
||||
let render_column = |col: Vec<usize>| -> String {
|
||||
format!(": {}\n", col.into_iter().map(&render_card).collect::<Vec<String>>().join(" "))
|
||||
};
|
||||
|
||||
columns.into_iter().map(render_column).collect::<Vec<_>>().join("")
|
||||
deck.chunks(8).map(|row| row.join(" ")).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let arg: u32 = std::env::args().nth(1).and_then(|n| n.parse().ok()).expect("I need a number.");
|
||||
print!("{}", deal_ms_fc_board(arg));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue