June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

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

View file

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

View file

@ -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 ? */

View file

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