Created
August 29, 2019 21:01
-
-
Save Forty-Bot/58e65868bc09e77913f84433e019fbee to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import core.stdc.stdio : stderr; | |
| import std.bitmanip; | |
| import std.algorithm.comparison; | |
| import std.algorithm.iteration; | |
| import std.math; | |
| import std.range; | |
| import std.random; | |
| import std.stdio; | |
| immutable int CUBE_SIZE = 360; | |
| immutable int BITS_SIZE = ((CUBE_SIZE - 1) / size_t.sizeof / 8) + 1; | |
| immutable int PLAYERS = 8; | |
| immutable int ROUNDS = 24; | |
| immutable int PACK_COUNT = ROUNDS; | |
| //immutable int PACK_COUNT = ROUNDS * PLAYERS; | |
| immutable int PACK_SIZE = 15; | |
| immutable int EXTRA_CARDS = 0; | |
| immutable int SEAT_RANK = 0; | |
| static assert(SEAT_RANK < PLAYERS); | |
| static assert(PACK_COUNT * PACK_SIZE + EXTRA_CARDS <= CUBE_SIZE); | |
| immutable int REPS = 1_00_000; | |
| immutable int STATS = CUBE_SIZE; | |
| size_t[PACK_COUNT * BITS_SIZE] packs_buf; | |
| BitArray[PACK_COUNT] packs; | |
| size_t[BITS_SIZE] pool_buf; | |
| BitArray pool; | |
| immutable int[CUBE_SIZE] sort_cube = iota(360).array(); | |
| int[CUBE_SIZE] shuf_cube; | |
| int[STATS] counts; | |
| void main() | |
| { | |
| packs = packs_buf[].chunks(BITS_SIZE).map!(p => BitArray(p, CUBE_SIZE)).array; | |
| pool = BitArray(pool_buf, CUBE_SIZE); | |
| do_sim(); | |
| foreach (i; 0 .. STATS) | |
| writefln("%d,%1.6f", i + 1, cast(real)counts[i] / (i + 1) / REPS); | |
| } | |
| void do_sim() { | |
| foreach (r; 0 .. REPS) { | |
| packs_buf[] = 0; | |
| pool_buf[] = 0; | |
| /* | |
| * Even though the packs are bitmaps, the easiest way to shuffle is to shuffle the whole thing as an | |
| * array and then slice it up for the packs | |
| */ | |
| shuf_cube = sort_cube; | |
| shuf_cube[].randomShuffle(rndGen); | |
| foreach (pack, shuf_pack; zip(packs[], shuf_cube[].chunks(PACK_SIZE))) | |
| foreach (card; shuf_pack) | |
| pack[card] = 1; | |
| /* Do the draft */ | |
| rotisserie(); | |
| /* Calculate some stats */ | |
| auto count = 0; | |
| foreach (i; 0 .. STATS) { | |
| count += pool[i]; | |
| counts[i] += count; | |
| } | |
| if ((r & 0xFFF) == 0) | |
| fprintf(stderr, "%d\n", (r)); | |
| } | |
| } | |
| void booster() { | |
| foreach (round, round_packs; packs[].chunks(PLAYERS).enumerate()) { | |
| if (round == ROUNDS) | |
| break; | |
| /* we change seats while the packs stay still */ | |
| foreach (i; 0 .. PACK_SIZE) { | |
| auto j = i % PLAYERS; | |
| foreach (k; 0 .. PLAYERS) { | |
| auto pack = round_packs[k]; | |
| if (j == k) { | |
| auto card = pack.bitsSet.front; | |
| pool[card] = 1; | |
| pack[card] = 0; | |
| } else { | |
| pack[pack.bitsSet.drop(uniform(0, PACK_SIZE - i, rndGen)).front] = 0; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void forty() { | |
| size_t l = PLAYERS * PACK_SIZE; | |
| foreach (round, round_packs; packs[].chunks(PLAYERS).enumerate()) { | |
| if (round == ROUNDS) | |
| break; | |
| /* we change seats while the packs stay still */ | |
| foreach (i; 0 .. PACK_SIZE) { | |
| auto j = i % PLAYERS; | |
| foreach (k; 0 .. PLAYERS) { | |
| auto pack = round_packs[k]; | |
| if (j == k) { | |
| auto card = pack.bitsSet.front; | |
| pool[card] = 1; | |
| pack[card] = 0; | |
| } else { | |
| pack[pack.bitsSet.drop(uniform(0, PACK_SIZE - i, rndGen)).front] = 0; | |
| } | |
| } | |
| /* Add some more cards */ | |
| if (l < PLAYERS * PACK_SIZE + EXTRA_CARDS) | |
| foreach (pack; round_packs) | |
| pack[shuf_cube[l++]] = 1; | |
| } | |
| } | |
| } | |
| /* Also rochester */ | |
| void rotisserie() { | |
| foreach (round; 0 .. ROUNDS) { | |
| auto pack = packs[round]; | |
| auto j = (SEAT_RANK + round) % PLAYERS; | |
| foreach (i; 0 .. PACK_SIZE - DROPPED) { | |
| foreach (k; 0 .. min(PLAYERS, PACK_SIZE - (i * PLAYERS))) { | |
| if (j == k) { | |
| auto card = pack.bitsSet.front; | |
| pool[card] = 1; | |
| pack[card] = 0; | |
| } else { | |
| pack[pack.bitsSet.drop(uniform(0, PACK_SIZE - i, rndGen)).front] = 0; | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment