*Author

Active members:
serprex(1)

Offline serprexTopic starter

  • Administrator
  • ********
  • Posts: 2240
  • Reputation Power: 0
  • serprex hides under a Cloak.
  • Awards: War #12 Winner - Team Darkness
Pugons https://elementscommunity.org/forum/index.php?topic=62820.msg1242867#msg1242867
« on: August 28, 2016, 12:42:38 am »
Spoiler for python:
Code: [Select]
#!/bin/python
from multiprocessing import Pool
from random import shuffle

def decks():
pcount = 14
lidr = 17 - pcount
for aepi in range(pcount):
for lipi in range(pcount - aepi):
lipe = pcount - aepi - lipi
if lipe < 7:continue
if lipi+lidr+lipe < 15:continue
maxups = [aepi, 0, lipi, lipe, lidr, 6]
ups = {(0, 0, 0, 0, 0, 0)}
for u in range(8):
nups = set()
for up in ups:
for i in (0, 2, 3, 4, 5):
if up[i] < maxups[i]:
nup = list(up)
nup[i] += 1
nups.add((*nup,))
ups = nups
for up in ups:
yield (aepi, lipi, lipe, lidr), up

def simulate(tdeck, t = 6):
def find(v, s = 0):
try:return deck.index(v, s)
except:return 99
(aeli, lipi, lipe, lidr), up = tdeck
deck = [6,6,6,6,6,6,7]
deck += (0,)*(aeli - up[0])
deck += (2,)*(lipi - up[2])
deck += (3,)*(lipe - up[3])
deck += (4,)*(lidr - up[4])
deck += (5,)*(6 - up[5])
deck += (~0,)*up[0]
deck += (~2,)*up[2]
deck += (~3,)*up[3]
deck += (~4,)*up[4]
deck += (~5,)*up[5]
turns = [0]*t
exae = exli = 0
for a in range(1000):
shuffle(deck)
aepi = lipi = lipe = lupe = 0
lidr = 0
ludr = 0
lidrx = find(4)
ludrx = find(~4)
pux = find(5)
upux = find(~5)
dix = find(6)
lox = find(7)
li = 0
ae = 0
for c in range(7):
c = deck[c]
if c == 0:
aepi += 1
elif c == 2:
lipi += 1
elif c == 3:
lipe += 1
elif c == ~0:
aepi += 1
ae += 1
elif c == ~2:
lipi += 1
li += 1
elif c == ~3:
lupe += 1
li += 1
ae += aepi
li += lipi + lipe + lupe
lit = lipe > 0
lut = lupe > 0
dim = False
lob = False
turn = turns[:]
for i in range(t):
ti = i+7
c = deck[ti]
if c == 0:
aepi += 1
elif c == 2:
lipi += 1
elif c == 3:
lipe += 1
elif c == ~0:
aepi += 1
ae += 1
elif c == ~2:
lipi += 1
li += 1
elif c == ~3:
lupe += 1
li += 1
while ludrx <= ti and li >= 13:
ludr += 1
li -= 13
ludrx = find(~4, ludrx+1)
while lidrx <= ti and li >= 12:
lidr += 1
li -= 12
lidrx = find(4, lidrx+1)
while not dim and dix <= ti and i>3 and ae >= 6:
ae -= 6
dim = True
dix = find(6, dix+1)
while upux <= ti and ae >= (6 if dim or i<4 else 12) and (lidr > 0 or ludr > 0):
if ludr:ludr += 1
else:lidr += 1
ae -= 6
upux = find(~5, upux+1)
while pux <= ti and ae >= (7 if dim or i<4 else 13) and (lidr > 0 or ludr > 0):
if ludr:ludr += 1
else:lidr += 1
ae -= 7
pux = find(5, pux+1)
while not lob and lox <= ti and ae >= (3 if dim or i<5 else 9):
ae -= 3
lob = True
lox = find(7, lox+1)
ae += aepi
li += lipi
if lit:ae += lipe
else:li += lipe
lit ^= lipe > 0
if lut:ae += lupe
else:li += lupe
lut ^= lupe > 0
turn[i] += ludr * 12 + lidr * 10 + lob * 5
if dim:
turns = turn
exae += ae
exli += li
return tdeck, (turns, exae, exli)

def dmg(turns):
x = d = 0
for a in turns:
x += a
d += x
return d
res = list(Pool(processes=4).imap_unordered(simulate, decks()))
res.sort(key=lambda v:dmg(v[1][0]))
print(res[-1])
Spoiler for rust:
2 hours for 10k iterations spurred me to rewrite code in Rust, as I'm considering applying this to sofrrush
Code: [Select]
extern crate rand;
extern crate rayon;

use std::collections::HashSet;
use rayon::prelude::*;
use rand::Rng;

fn decks() -> Vec<((u8, u8, u8, u8), [u8; 6])> {
let mut ret = Vec::new();
let pcount = 14;
let lidr = 17 - pcount;
for aepi in 0..pcount {
for lipi in 0..(pcount - aepi) {
let lipe = pcount - aepi - lipi;
if lipe < 7 || lipi + lidr + lipe < 15 { continue }
let maxups = [aepi, 0, lipi, lipe, lidr, 3];
let mut ups = HashSet::new();
ups.insert([0; 6]);
for _ in 0..8 {
let mut nups = HashSet::new();
for up in &ups {
for &i in &[0, 2, 3, 4, 5] {
if up[i] < maxups[i] {
let mut nup = *up;
nup[i] += 1;
nups.insert(nup);
}
}
}
ups = nups;
}
for up in &ups {
if up[2] + up[3] + up[4] >= 4 {
ret.push(((aepi, lipi, lipe, lidr), *up))
}
}
}
}
ret
}

fn simulate(tdeck: ((u8, u8, u8, u8), [u8; 6])) -> (((u8, u8, u8, u8), [u8; 6]), [i32; 6], i32, i32, i32) {
let ((aeli, lipi, lipe, lidr), up) = tdeck;
let mut deck = vec![6,6,6,6,6,6,7];
deck.reserve(23);
for _c0 in 0..(aeli - up[0]) {
deck.push(0);
}
for _c2 in 0..(lipi - up[2]) {
deck.push(2);
}
for _c3 in 0..(lipe - up[3]) {
deck.push(3);
}
for _c4 in 0..(lidr - up[4]) {
deck.push(4);
}
for _c5 in 0..(6 - up[5]) {
deck.push(5);
}
for &cx in &[0, 2, 3, 4, 5] {
for _c in 0..up[cx as usize] {
deck.push(!cx);
}
}
let mut turns = [0; 6];
let mut dies = 0;
let mut exae = 0;
let mut exli = 0;
for _ in 0..100000 {
rand::thread_rng().shuffle(&mut deck);
let mut aepi = 0;
let mut lipi = 0;
let mut lipe = 0;
let mut lupe = 0;
let mut lidr = 0;
let mut ludr = 0;
let mut lidrx = deck.iter().position(|&x| x == 4).unwrap_or(99);
let mut ludrx = deck.iter().position(|&x| x == !4).unwrap_or(99);
let mut pux = deck.iter().position(|&x| x == 5).unwrap_or(99);
let mut upux = deck.iter().position(|&x| x == !5).unwrap_or(99);
let mut dix = deck.iter().position(|&x| x == 6).unwrap_or(99);
let mut lox = deck.iter().position(|&x| x == 7).unwrap_or(99);
let mut li = 0;
let mut ae = 0;
for &c in &deck[0..7] {
match c {
0 => aepi += 1,
2 => lipi += 1,
3 => lipe += 1,
-1 => {aepi += 1; ae += 1},
-3 => {lipi += 1; li += 1},
-4 => {lupe += 1; li += 1},
_ => (),
}
}
ae += aepi;
li += lipi + lipe + lupe;
let mut lit = lipe > 0;
let mut lut = lupe > 0;
let mut dim = false;
let mut lob = false;
let mut turn = turns;
for i in 0..6 {
let ti = i+7;
let c = deck[ti];
match c {
0 => aepi += 1,
2 => lipi += 1,
3 => lipe += 1,
-1 => {aepi += 1; ae += 1},
-3 => {lipi += 1; li += 1},
-4 => {lupe += 1; li += 1},
_ => (),
}
while ludrx <= ti && li >= 13 {
ludr += 1;
li -= 13;
ludrx = deck[ludrx+1..].iter().position(|&x| x == !4).unwrap_or(99);
}
while lidrx <= ti && li >= 12 {
lidr += 1;
li -= 12;
lidrx = deck[lidrx+1..].iter().position(|&x| x == 4).unwrap_or(99);
}
while !dim && dix <= ti && i>3 && ae >= 6 {
ae -= 6;
dim = true;
dix = deck[dix+1..].iter().position(|&x| x == 6).unwrap_or(99);
}
while upux <= ti &&
ae >= if dim || i<4 { 6 } else { 12 } &&
(lidr > 0 || ludr > 0)
{
if ludr > 0 { ludr += 1 }
else { lidr += 1 }
ae -= 6;
upux = deck[upux+1..].iter().position(|&x| x == !5).unwrap_or(99);
}
while pux <= ti &&
ae >= if dim || i<4 { 7 } else { 13 } &&
(lidr > 0 || ludr > 0)
{
if ludr > 0 { ludr += 1 }
else { lidr += 1 }
ae -= 7;
pux = deck[pux+1..].iter().position(|&x| x == 5).unwrap_or(99);
}
while !lob && lox <= ti && ae >= if dim || i<5 { 3 } else { 9 } {
ae -= 3;
lob = true;
lox = deck[lox+1..].iter().position(|&x| x == 7).unwrap_or(99);
}
ae += aepi;
li += lipi;
if lit { ae += lipe }
else { li += lipe }
if lut { ae += lupe }
else { li += lupe }
lit ^= lipe > 0;
lut ^= lupe > 0;
turn[i] += ludr * 12 + lidr * 10 + if lob { 5 } else { 0 };
}
if dim { turns = turn }
else { dies += 1}
exae += ae;
exli += li;
}
(tdeck, turns, exae, exli, dies)
}

fn dmg(turns: &[i32]) -> i32 {
let mut x = 0;
let mut d = 0;
for a in turns {
x += *a;
d += x;
}
d
}

fn main() {
let d = decks();
let mut sim = Vec::new();
d.into_par_iter().weight_max().map(simulate).collect_into(&mut sim);
sim.sort_by_key(|x| dmg(&x.1));
println!("{:?}", sim.last().unwrap());
}
100k
Hover over cards for details, click for permalink
Deck import code : [Select]
5mq 5mq 5mq 5mq 5mq 5mq 5la 5la 5la 61u 61t 61t 61t 61t 61t 61t 61r 61r 61r 61r 61r 61r 7la 7la 7la 7la 7la 7la 7la 7la 8pu

Quanta's really tight on :aether wish it could fit Silence

This outrushes
Hover over cards for details, click for permalink
Deck import code : [Select]
4su 55k 576 61q 61q 61q 61q 61u 622 622 622 622 63a 63a 63a 63a 63a 63a 745 745 745 747 747 747 81q 81q 81q 81q 81q 81q 8pl
which aether ran R1 vs Light in #8
« Last Edit: August 29, 2016, 12:58:45 am by serprex »

 

blarg: