Added - hobbit live draft (and support for drafting from shared pool and hobbit past games evaluator for draft bots)
This commit is contained in:
@@ -0,0 +1,434 @@
|
||||
{
|
||||
"name": "Hobbit Booster Draft",
|
||||
"code": "hobbit_table_draft",
|
||||
"format": "limited_hobbit",
|
||||
"max-players": 4,
|
||||
"starting-collection": [
|
||||
{
|
||||
"size": 68,
|
||||
"card-list": [
|
||||
"30_1" , "30_2" , "30_3" , "30_4" , "30_5" , "30_6" , "30_7" , "30_8" ,
|
||||
"30_9" , "30_10", "30_11", "30_12", "30_13", "30_14", "30_15", "30_16",
|
||||
"30_17", "30_18", "30_19", "30_20", "30_21", "30_22", "30_23", "30_24",
|
||||
"30_29", "30_30", "30_31", "30_47", "30_48", "30_32", "30_32", "30_32",
|
||||
"30_33", "30_33", "30_34", "30_34", "30_35", "30_35", "30_35", "30_35",
|
||||
"30_36", "30_36", "30_37", "30_37", "30_38", "30_38", "30_39", "30_39",
|
||||
"30_39", "30_40", "30_40", "30_40", "30_41", "30_41", "30_42", "30_42",
|
||||
"30_42", "30_42", "30_66", "30_49", "30_50", "30_51", "30_52", "30_53",
|
||||
"30_54", "30_55", "30_56", "30_57"
|
||||
]
|
||||
},
|
||||
{ "size": 1, "card-list": ["30_25", "30_26", "30_27", "30_28"] },
|
||||
{ "size": 1, "card-list": ["30_43", "30_44", "30_45", "30_46"] }
|
||||
],
|
||||
"card-sets": [
|
||||
{
|
||||
"set-name": "free-peoples-pack",
|
||||
"card-set": [
|
||||
"30_1" , "30_1" , "30_3" , "30_3" , "30_4" , "30_4" , "30_13", "30_13",
|
||||
"30_14", "30_14", "30_20", "30_20", "30_23", "30_23", "30_24", "30_24",
|
||||
"30_30", "30_30", "30_31", "30_31", "30_58", "30_59", "30_60", "30_61",
|
||||
"30_62", "30_63", "30_64", "30_65"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "swarm-pack-1",
|
||||
"card-set": [
|
||||
"31_30", "31_30", "31_30", "31_30", "31_31", "31_31", "31_31", "31_31",
|
||||
"31_32", "31_32", "31_32", "31_32", "31_34", "31_34", "31_35", "31_35",
|
||||
"31_35", "31_35", "31_36", "31_36", "31_49", "31_49", "31_49", "31_51",
|
||||
"31_51", "31_51", "31_51", "31_52", "31_52", "31_52", "31_53", "31_53",
|
||||
"31_53", "31_53", "31_54", "31_54", "31_55", "31_55", "31_55", "31_55"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "swarm-pack-2",
|
||||
"card-set": [
|
||||
"32_27", "32_27", "32_27", "32_27", "32_28", "32_28", "32_28", "32_28",
|
||||
"32_31", "32_31", "32_31", "32_32", "32_32", "32_32", "32_33", "32_33",
|
||||
"32_33", "32_34", "32_34", "32_34", "32_36", "32_36", "32_36", "32_38",
|
||||
"32_38", "32_40", "32_40", "32_40", "32_41", "32_41", "32_41", "32_41",
|
||||
"32_42", "32_42", "32_42", "32_42", "32_43", "32_43", "32_43", "32_43"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "swarm-pack-3",
|
||||
"card-set": [
|
||||
"33_38", "33_38", "33_38", "33_38", "33_39", "33_39", "33_39", "33_39",
|
||||
"33_40", "33_40", "33_40", "33_41", "33_41", "33_41", "33_43", "33_43",
|
||||
"33_45", "33_45", "33_45", "33_45", "33_46", "33_46", "33_46", "33_47",
|
||||
"33_47", "33_47", "33_47", "33_48", "33_48", "33_48", "33_49", "33_49",
|
||||
"33_49", "33_49", "33_50", "33_50", "33_50", "33_51", "33_51", "33_51"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "beatdown-pack-1",
|
||||
"card-set": [
|
||||
"31_19", "31_19", "31_19", "31_19", "31_20", "31_20", "31_20", "31_21",
|
||||
"31_21", "31_21", "31_23", "31_23", "31_23", "31_24", "31_24", "31_26",
|
||||
"31_26", "31_26", "31_27", "31_27", "31_27", "31_27", "31_28", "31_28",
|
||||
"31_28", "31_56", "31_56", "31_56", "31_58", "31_58", "31_58", "31_59",
|
||||
"31_59", "31_59", "31_60", "31_60", "31_60", "31_61", "31_61", "31_61"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "beatdown-pack-2",
|
||||
"card-set": [
|
||||
"32_37", "32_37", "32_37", "32_37", "32_44", "32_44", "32_45", "32_45",
|
||||
"32_45", "32_45", "32_50", "32_50", "32_51", "32_51", "32_51", "32_51",
|
||||
"32_52", "32_52", "32_52", "32_52", "32_54", "32_54", "32_54", "32_55",
|
||||
"32_55", "32_56", "32_56", "32_56", "32_58", "32_58", "32_58", "32_59",
|
||||
"32_60", "32_61", "32_62", "32_63", "32_64", "32_65", "32_66", "32_67"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "beatdown-pack-3",
|
||||
"card-set": [
|
||||
"33_24", "33_24", "33_24", "33_25", "33_25", "33_25", "33_26", "33_26",
|
||||
"33_26", "33_27", "33_27", "33_27", "33_28", "33_28", "33_28", "33_29",
|
||||
"33_29", "33_29", "33_30", "33_30", "33_30", "33_31", "33_31", "33_31",
|
||||
"33_32", "33_32", "33_32", "33_34", "33_34", "33_34", "33_35", "33_35",
|
||||
"33_35", "33_42", "33_42", "33_42", "33_42", "33_44", "33_44", "33_44"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-a-bilbo",
|
||||
"card-set": [
|
||||
"31_38", "31_38", "31_38", "31_39", "31_39", "31_40", "31_40", "31_41",
|
||||
"31_41", "31_41", "31_42", "31_42", "31_42", "31_43", "31_43", "31_22",
|
||||
"31_22", "31_22", "31_57", "31_57", "31_45", "31_45"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-b-dain",
|
||||
"card-set": [
|
||||
"32_1" , "32_1" , "32_1" , "32_2" , "32_2" , "32_2" , "32_4" , "32_4" ,
|
||||
"32_5" , "32_5" , "32_6" , "32_6" , "32_8" , "32_8" , "32_8" , "32_26",
|
||||
"32_26", "32_30", "32_30", "32_30", "32_49", "32_49"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-c-esgaroth",
|
||||
"card-set": [
|
||||
"32_15", "32_15", "32_15", "32_16", "32_16", "32_17", "32_17", "32_18",
|
||||
"32_18", "32_19", "32_19", "32_19", "32_20", "32_20", "32_20", "32_25",
|
||||
"32_25", "32_25", "32_53", "32_53", "32_47", "32_47"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-d-mirkwood",
|
||||
"card-set": [
|
||||
"31_3" , "31_3" , "31_3" , "31_8" , "31_8" , "31_9" , "31_9" , "31_10",
|
||||
"31_10", "31_11", "31_11", "31_11", "31_12", "31_12", "31_12", "31_29",
|
||||
"31_29", "31_37", "31_37", "31_37", "31_46", "31_46"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-e-thorin",
|
||||
"card-set": [
|
||||
"31_1" , "31_1" , "31_2" , "31_2" , "31_2" , "31_4" , "31_4" , "31_5" ,
|
||||
"31_5" , "31_5" , "31_6" , "31_6" , "31_7" , "31_7" , "31_7" , "31_33",
|
||||
"31_33", "31_33", "31_48", "31_48", "31_47", "31_47"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-f-thrain",
|
||||
"card-set": [
|
||||
"32_3" , "32_3" , "32_3" , "32_7" , "32_7" , "32_9" , "32_9" , "32_9" ,
|
||||
"32_10", "32_10", "32_11", "32_11", "32_11", "32_12", "32_12", "32_29",
|
||||
"32_29", "32_35", "32_35", "32_35", "32_48", "32_48"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-g-white-council",
|
||||
"card-set": [
|
||||
"32_13", "32_13", "32_13", "32_14", "32_14", "32_21", "32_21", "32_22",
|
||||
"32_22", "32_23", "32_23", "32_23", "32_24", "32_24", "32_24", "32_39",
|
||||
"32_39", "32_57", "32_57", "32_57", "32_46", "32_46"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-h-wizard",
|
||||
"card-set": [
|
||||
"31_13", "31_13", "31_13", "31_14", "31_14", "31_15", "31_15", "31_16",
|
||||
"31_16", "31_17", "31_17", "31_17", "31_18", "31_18", "31_18", "31_25",
|
||||
"31_25", "31_25", "31_50", "31_50", "31_44", "31_44"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-i-balin",
|
||||
"card-set": [
|
||||
"33_1" , "33_1" , "33_3" , "33_3" , "33_3" , "33_4" , "33_4" , "33_10",
|
||||
"33_10", "33_10", "33_11", "33_11", "33_11", "33_12", "33_12", "33_36",
|
||||
"33_36", "33_36", "33_59", "33_59", "33_56", "33_56"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-j-blue-mountains",
|
||||
"card-set": [
|
||||
"33_2" , "33_2" , "33_5" , "33_5" , "33_5" , "33_6" , "33_6" , "33_6" ,
|
||||
"33_7" , "33_7" , "33_8" , "33_8" , "33_9" , "33_9" , "33_9" , "33_37",
|
||||
"33_37", "33_37", "33_60", "33_60", "33_58", "33_58"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-k-rivendell",
|
||||
"card-set": [
|
||||
"33_13", "33_13", "33_13", "33_14", "33_14", "33_14", "33_15", "33_15",
|
||||
"33_16", "33_16", "33_17", "33_17", "33_17", "33_18", "33_18", "33_33",
|
||||
"33_33", "33_33", "33_61", "33_61", "33_57", "33_57"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "pack-l-travellers",
|
||||
"card-set": [
|
||||
"33_19", "33_19", "33_20", "33_20", "33_21", "33_21", "33_52", "33_52",
|
||||
"33_52", "33_53", "33_53", "33_53", "33_54", "33_54", "33_54", "33_22",
|
||||
"33_22", "33_23", "33_23", "33_23", "33_55", "33_55"
|
||||
]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-swarm-pack",
|
||||
"choose": 1,
|
||||
"set-set": ["swarm-pack-1", "swarm-pack-2", "swarm-pack-3"]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-beatdown-pack",
|
||||
"choose": 1,
|
||||
"set-set": ["beatdown-pack-1", "beatdown-pack-2", "beatdown-pack-3"]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-burglar-pack",
|
||||
"choose": 1,
|
||||
"set-set": ["pack-a-bilbo", "pack-i-balin", "pack-l-travellers"]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-arming-pack",
|
||||
"choose": 1,
|
||||
"set-set": ["pack-e-thorin", "pack-f-thrain", "pack-j-blue-mountains"]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-allies-pack",
|
||||
"choose": 1,
|
||||
"set-set": ["pack-b-dain", "pack-c-esgaroth", "pack-d-mirkwood"]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-wises-pack",
|
||||
"choose": 1,
|
||||
"set-set": ["pack-g-white-council", "pack-h-wizard", "pack-k-rivendell"]
|
||||
},
|
||||
{
|
||||
"set-name": "chosen-supplementary-packs",
|
||||
"choose": 2,
|
||||
"set-set": [
|
||||
"chosen-burglar-pack", "chosen-arming-pack" , "chosen-allies-pack" ,
|
||||
"chosen-wises-pack"
|
||||
]
|
||||
}
|
||||
],
|
||||
"pools": [
|
||||
{
|
||||
"pool-name": "draft-pool",
|
||||
"set-set": [
|
||||
"chosen-supplementary-packs",
|
||||
"chosen-swarm-pack" ,
|
||||
"chosen-beatdown-pack" ,
|
||||
"free-peoples-pack" ,
|
||||
"free-peoples-pack"
|
||||
]
|
||||
}
|
||||
],
|
||||
"boosters": [
|
||||
{
|
||||
"rounds": [ 1, 2, 3, 4, 5 ],
|
||||
"cards" : [ {"count": 9, "set-name": "draft-pool"} ]
|
||||
}
|
||||
],
|
||||
"card-values": [
|
||||
{"card": "33_7" , "value": 1.0 },
|
||||
{"card": "33_44", "value": 0.8333787095017696 },
|
||||
{"card": "32_67", "value": 0.8203103729921045 },
|
||||
{"card": "30_31", "value": 0.7296487884563028 },
|
||||
{"card": "32_18", "value": 0.6634903348761231 },
|
||||
{"card": "31_6" , "value": 0.6602232507487068 },
|
||||
{"card": "31_38", "value": 0.6471549142390417 },
|
||||
{"card": "31_5" , "value": 0.6471549142390417 },
|
||||
{"card": "33_42", "value": 0.5867138578818405 },
|
||||
{"card": "32_24", "value": 0.5513204465014974 },
|
||||
{"card": "31_20", "value": 0.5360740539068881 },
|
||||
{"card": "32_13", "value": 0.5317179417369997 },
|
||||
{"card": "32_40", "value": 0.5273618295671113 },
|
||||
{"card": "32_59", "value": 0.5262728015246393 },
|
||||
{"card": "32_60", "value": 0.5262728015246393 },
|
||||
{"card": "31_1" , "value": 0.5262728015246393 },
|
||||
{"card": "31_48", "value": 0.5132044650149742 },
|
||||
{"card": "33_37", "value": 0.5099373808875578 },
|
||||
{"card": "33_35", "value": 0.5012251565477811 },
|
||||
{"card": "33_39", "value": 0.4911516471549142 },
|
||||
{"card": "32_23", "value": 0.49033487612306015 },
|
||||
{"card": "32_66", "value": 0.4838007078682276 },
|
||||
{"card": "33_41", "value": 0.4827116798257555 },
|
||||
{"card": "31_26", "value": 0.47944459569833925 },
|
||||
{"card": "32_54", "value": 0.47944459569833925 },
|
||||
{"card": "32_4" , "value": 0.47399945548597877 },
|
||||
{"card": "32_36", "value": 0.4674652872311462 },
|
||||
{"card": "32_50", "value": 0.46419820310372994 },
|
||||
{"card": "32_43", "value": 0.4486795534985026 },
|
||||
{"card": "33_21", "value": 0.4478627824666485 },
|
||||
{"card": "32_45", "value": 0.44377892730737817 },
|
||||
{"card": "31_24", "value": 0.44132861421181596 },
|
||||
{"card": "31_22", "value": 0.4402395861693439 },
|
||||
{"card": "33_45", "value": 0.43887830111625376 },
|
||||
{"card": "33_38", "value": 0.43642798802069155 },
|
||||
{"card": "31_13", "value": 0.43152736182956714 },
|
||||
{"card": "31_19", "value": 0.4290770487340049 },
|
||||
{"card": "30_3" , "value": 0.42145385243670025 },
|
||||
{"card": "31_21", "value": 0.418459025319902 },
|
||||
{"card": "32_61", "value": 0.418459025319902 },
|
||||
{"card": "31_10", "value": 0.4151919411924857 },
|
||||
{"card": "31_37", "value": 0.41410291315001363 },
|
||||
{"card": "33_52", "value": 0.41410291315001363 },
|
||||
{"card": "33_40", "value": 0.4053906888102369 },
|
||||
{"card": "31_18", "value": 0.4010345766403485 },
|
||||
{"card": "31_23", "value": 0.3966784644704601 },
|
||||
{"card": "31_58", "value": 0.39341138034304385 },
|
||||
{"card": "30_1" , "value": 0.3920500952899537 },
|
||||
{"card": "31_61", "value": 0.39123332425809965 },
|
||||
{"card": "31_28", "value": 0.38905526817315544 },
|
||||
{"card": "32_53", "value": 0.38578818404573917 },
|
||||
{"card": "32_56", "value": 0.3825210999183229 },
|
||||
{"card": "32_51", "value": 0.37598693166349034 },
|
||||
{"card": "32_39", "value": 0.37598693166349034 },
|
||||
{"card": "32_52", "value": 0.37271984753607407 },
|
||||
{"card": "32_9" , "value": 0.37054179145112986 },
|
||||
{"card": "31_9" , "value": 0.3694527634086578 },
|
||||
{"card": "30_23", "value": 0.36836373536618566 },
|
||||
{"card": "32_42", "value": 0.3645521372175334 },
|
||||
{"card": "32_7" , "value": 0.35638442689899263 },
|
||||
{"card": "32_58", "value": 0.35311734277157636 },
|
||||
{"card": "32_41", "value": 0.35066702967601415 },
|
||||
{"card": "31_29", "value": 0.3465831745167438 },
|
||||
{"card": "33_20", "value": 0.3465831745167438 },
|
||||
{"card": "32_32", "value": 0.3422270623468554 },
|
||||
{"card": "31_8" , "value": 0.336781922134495 },
|
||||
{"card": "32_55", "value": 0.32861421181595424 },
|
||||
{"card": "33_23", "value": 0.3269806697522461 },
|
||||
{"card": "30_13", "value": 0.32534712768853796 },
|
||||
{"card": "32_63", "value": 0.3237135856248298 },
|
||||
{"card": "31_12", "value": 0.313912333242581 },
|
||||
{"card": "31_30", "value": 0.30737816498774845 },
|
||||
{"card": "33_19", "value": 0.3008439967329159 },
|
||||
{"card": "32_30", "value": 0.2986659406479717 },
|
||||
{"card": "33_12", "value": 0.2943098284780833 },
|
||||
{"card": "31_57", "value": 0.2943098284780833 },
|
||||
{"card": "32_31", "value": 0.28886468826572287 },
|
||||
{"card": "31_36", "value": 0.28777566022325074 },
|
||||
{"card": "32_37", "value": 0.2861421181595426 },
|
||||
{"card": "33_43", "value": 0.28450857609583446 },
|
||||
{"card": "33_60", "value": 0.2779744078410019 },
|
||||
{"card": "31_56", "value": 0.2768853797985298 },
|
||||
{"card": "33_17", "value": 0.27470732371358564 },
|
||||
{"card": "31_31", "value": 0.2730737816498775 },
|
||||
{"card": "32_64", "value": 0.27144023958616936 },
|
||||
{"card": "31_59", "value": 0.26708412741628096 },
|
||||
{"card": "33_59", "value": 0.26490607133133676 },
|
||||
{"card": "32_5" , "value": 0.26490607133133676 },
|
||||
{"card": "33_22", "value": 0.26490607133133676 },
|
||||
{"card": "32_29", "value": 0.26490607133133676 },
|
||||
{"card": "33_54", "value": 0.2638170432888647 },
|
||||
{"card": "32_34", "value": 0.2627280152463926 },
|
||||
{"card": "33_53", "value": 0.25728287503403213 },
|
||||
{"card": "33_47", "value": 0.25183773482167165 },
|
||||
{"card": "32_65", "value": 0.25183773482167165 },
|
||||
{"card": "31_41", "value": 0.2507487067791996 },
|
||||
{"card": "32_38", "value": 0.2502041927579635 },
|
||||
{"card": "30_30", "value": 0.2488429077048734 },
|
||||
{"card": "32_62", "value": 0.24857065069425538 },
|
||||
{"card": "31_14", "value": 0.2453035665668391 },
|
||||
{"card": "32_44", "value": 0.2453035665668391 },
|
||||
{"card": "31_17", "value": 0.244214538524367 },
|
||||
{"card": "32_35", "value": 0.24203648243942283 },
|
||||
{"card": "32_2" , "value": 0.23768037026953445 },
|
||||
{"card": "33_61", "value": 0.23550231418459025 },
|
||||
{"card": "31_60", "value": 0.23441328614211815 },
|
||||
{"card": "32_28", "value": 0.23060168799346584 },
|
||||
{"card": "31_35", "value": 0.22733460386604956 },
|
||||
{"card": "32_11", "value": 0.2267900898448135 },
|
||||
{"card": "32_17", "value": 0.22570106180234142 },
|
||||
{"card": "32_16", "value": 0.22570106180234142 },
|
||||
{"card": "33_36", "value": 0.22461203375986932 },
|
||||
{"card": "33_32", "value": 0.22134494963245305 },
|
||||
{"card": "33_50", "value": 0.21807786550503674 },
|
||||
{"card": "31_27", "value": 0.21671658045194664 },
|
||||
{"card": "31_16", "value": 0.20936564116526002 },
|
||||
{"card": "33_10", "value": 0.20936564116526002 },
|
||||
{"card": "32_15", "value": 0.20936564116526002 },
|
||||
{"card": "32_20", "value": 0.20936564116526002 },
|
||||
{"card": "33_34", "value": 0.20609855703784372 },
|
||||
{"card": "31_43", "value": 0.20609855703784372 },
|
||||
{"card": "30_4" , "value": 0.20528178600598965 },
|
||||
{"card": "33_27", "value": 0.20500952899537164 },
|
||||
{"card": "31_25", "value": 0.20283147291042744 },
|
||||
{"card": "33_3" , "value": 0.20065341682548327 },
|
||||
{"card": "33_49", "value": 0.20038115981486523 },
|
||||
{"card": "31_52", "value": 0.19738633269806696 },
|
||||
{"card": "31_49", "value": 0.19303022052817861 },
|
||||
{"card": "32_26", "value": 0.1897631364007623 },
|
||||
{"card": "33_4" , "value": 0.18649605227334604 },
|
||||
{"card": "32_10", "value": 0.18322896814592976 },
|
||||
{"card": "32_57", "value": 0.18105091206098556 },
|
||||
{"card": "33_8" , "value": 0.17996188401851348 },
|
||||
{"card": "31_42", "value": 0.17887285597604138 },
|
||||
{"card": "32_22", "value": 0.1734277157636809 },
|
||||
{"card": "31_53", "value": 0.1734277157636809 },
|
||||
{"card": "32_1" , "value": 0.17016063163626463 },
|
||||
{"card": "32_25", "value": 0.17016063163626463 },
|
||||
{"card": "33_9" , "value": 0.16798257555132046 },
|
||||
{"card": "32_19", "value": 0.16798257555132046 },
|
||||
{"card": "32_6" , "value": 0.16689354750884836 },
|
||||
{"card": "33_48", "value": 0.16471549142390415 },
|
||||
{"card": "33_5" , "value": 0.16362646338143208 },
|
||||
{"card": "33_46", "value": 0.16362646338143208 },
|
||||
{"card": "31_15", "value": 0.16362646338143208 },
|
||||
{"card": "32_8" , "value": 0.16362646338143208 },
|
||||
{"card": "31_2" , "value": 0.16362646338143208 },
|
||||
{"card": "33_6" , "value": 0.16144840729648788 },
|
||||
{"card": "31_32", "value": 0.16117615028586987 },
|
||||
{"card": "33_29", "value": 0.1603593792540158 },
|
||||
{"card": "31_51", "value": 0.15790906615845357 },
|
||||
{"card": "31_3" , "value": 0.1570922951265995 },
|
||||
{"card": "33_31", "value": 0.15491423904165533 },
|
||||
{"card": "31_34", "value": 0.1521916689354751 },
|
||||
{"card": "32_27", "value": 0.15055812687176695 },
|
||||
{"card": "32_14", "value": 0.15055812687176695 },
|
||||
{"card": "32_21", "value": 0.14729104274435068 },
|
||||
{"card": "31_4" , "value": 0.1407568744895181 },
|
||||
{"card": "31_7" , "value": 0.13531173427715765 },
|
||||
{"card": "33_2" , "value": 0.13422270623468555 },
|
||||
{"card": "33_30", "value": 0.13095562210726927 },
|
||||
{"card": "31_33", "value": 0.1265995099373809 },
|
||||
{"card": "33_14", "value": 0.1265995099373809 },
|
||||
{"card": "31_55", "value": 0.12605499591614483 },
|
||||
{"card": "33_33", "value": 0.1244214538524367 },
|
||||
{"card": "30_14", "value": 0.12060985570378437 },
|
||||
{"card": "33_25", "value": 0.12006534168254833 },
|
||||
{"card": "32_33", "value": 0.11570922951265995 },
|
||||
{"card": "31_39", "value": 0.11462020147018785 },
|
||||
{"card": "31_40", "value": 0.11135311734277158 },
|
||||
{"card": "31_54", "value": 0.11135311734277158 },
|
||||
{"card": "31_11", "value": 0.10917506125782739 },
|
||||
{"card": "33_28", "value": 0.10917506125782739 },
|
||||
{"card": "31_50", "value": 0.1080860332153553 },
|
||||
{"card": "33_51", "value": 0.10590797713041111 },
|
||||
{"card": "33_13", "value": 0.10264089300299482 },
|
||||
{"card": "33_18", "value": 0.10155186496052274 },
|
||||
{"card": "33_26", "value": 0.10046283691805064 },
|
||||
{"card": "33_15", "value": 0.09501769670569017 },
|
||||
{"card": "33_24", "value": 0.0917506125782739 },
|
||||
{"card": "33_1" , "value": 0.08194936019602504 },
|
||||
{"card": "32_12", "value": 0.08194936019602504 },
|
||||
{"card": "33_11", "value": 0.08086033215355296 },
|
||||
{"card": "30_24", "value": 0.015790906615845358},
|
||||
{"card": "30_20", "value": 0.010890280424720936}
|
||||
]
|
||||
}
|
||||
@@ -18,6 +18,8 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class TableDraftDefinitionBuilder {
|
||||
private static final int HIGH_ENOUGH_PRIME_NUMBER = 8963;
|
||||
@@ -45,7 +47,8 @@ public class TableDraftDefinitionBuilder {
|
||||
int maxPlayers = ((Number) definition.get("max-players")).intValue();
|
||||
|
||||
StartingCollectionProducer startingCollectionProducer = buildStartingCollectionProducer((JSONArray) definition.get("starting-collection"));
|
||||
BoosterProducer boosterProducer = buildBoosterProducer((JSONArray) definition.get("card-sets"), (JSONArray) definition.get("boosters"));
|
||||
// test if booster producer can be made from this json
|
||||
BoosterProducer testBoosterProducer = buildBoosterProducer((JSONArray) definition.get("card-sets"), (JSONArray) definition.get("boosters"), (JSONArray) definition.get("pools"));
|
||||
|
||||
Map<String, Double> cardValues = buildCardValues((JSONArray) definition.get("card-values"));
|
||||
|
||||
@@ -53,6 +56,7 @@ public class TableDraftDefinitionBuilder {
|
||||
return new TableDraftDefinition() {
|
||||
@Override
|
||||
public TableDraft getTableDraft(CollectionsManager collectionsManager, CollectionType collectionType, DraftTimer draftTimer) {
|
||||
BoosterProducer boosterProducer = buildBoosterProducer((JSONArray) definition.get("card-sets"), (JSONArray) definition.get("boosters"), (JSONArray) definition.get("pools"));
|
||||
return new TableDraftClassic(collectionsManager, collectionType, startingCollectionProducer, boosterProducer, maxPlayers, boosterProducer.getMaxRound(), draftTimer, cardValues);
|
||||
}
|
||||
|
||||
@@ -90,13 +94,43 @@ public class TableDraftDefinitionBuilder {
|
||||
return tbr;
|
||||
}
|
||||
|
||||
private static BoosterProducer buildBoosterProducer(JSONArray cardSets, JSONArray boosters) {
|
||||
private static BoosterProducer buildBoosterProducer(JSONArray cardSets, JSONArray boosters, JSONArray pools) {
|
||||
Map<String, List<String>> cardPools = new HashMap<>();
|
||||
Map<String, List<String>> setPools = new HashMap<>();
|
||||
Map<String, List<String>> draftPools = new HashMap<>();
|
||||
|
||||
for (JSONObject cardSet : (Iterable<JSONObject>) cardSets) {
|
||||
String name = (String) cardSet.get("set-name");
|
||||
List<String> cards = (List<String>) cardSet.get("card-set");
|
||||
cardPools.put(name, cards);
|
||||
if (cardSet.containsKey("card-set")) {
|
||||
List<String> cards = (List<String>) cardSet.get("card-set");
|
||||
cardPools.put(name, cards);
|
||||
} else if (cardSet.containsKey("set-set") && cardSet.containsKey("choose")) {
|
||||
List<String> setNames = (List<String>) cardSet.get("set-set");
|
||||
Collections.shuffle(setNames);
|
||||
int howMany = ((Number) cardSet.get("choose")).intValue();
|
||||
List<String> chosenSetNames = new ArrayList<>();
|
||||
if (howMany <= setNames.size()) {
|
||||
for (int i = 0; i < howMany; i++) {
|
||||
chosenSetNames.add(setNames.get(i));
|
||||
}
|
||||
setPools.put(name, chosenSetNames);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid JSON content");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid JSON content");
|
||||
}
|
||||
}
|
||||
|
||||
if (pools != null) {
|
||||
for (JSONObject cardSet : (Iterable<JSONObject>) pools) {
|
||||
String name = (String) cardSet.get("pool-name");
|
||||
draftPools.put(name, new ArrayList<>());
|
||||
List<String> sets = (List<String>) cardSet.get("set-set");
|
||||
for (String set : sets) {
|
||||
addSetToPool(cardPools, setPools, draftPools, name, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, List<Pair<String, Integer>>> boosterPlan = new HashMap<>();
|
||||
@@ -132,10 +166,25 @@ public class TableDraftDefinitionBuilder {
|
||||
}
|
||||
|
||||
return new BoosterProducer() {
|
||||
Lock poolLock = new ReentrantLock();
|
||||
|
||||
@Override
|
||||
public Booster getBooster(int round) {
|
||||
List<String> pickedCards = new ArrayList<>();
|
||||
boosterPlan.get(round).forEach(pair -> pickedCards.addAll(pickRandom(cardPools.get(pair.getLeft()), pair.getRight())));
|
||||
boosterPlan.get(round).forEach(pair -> {
|
||||
if (draftPools.get(pair.getLeft()) == null) {
|
||||
// opening boosters
|
||||
pickedCards.addAll(pickRandom(cardPools.get(pair.getLeft()), pair.getRight(), false));
|
||||
} else {
|
||||
// opening cards from draft pool
|
||||
poolLock.lock();
|
||||
try {
|
||||
pickedCards.addAll(pickRandom(draftPools.get(pair.getLeft()), pair.getRight(), true));
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
});
|
||||
return new Booster(pickedCards);
|
||||
}
|
||||
|
||||
@@ -144,7 +193,7 @@ public class TableDraftDefinitionBuilder {
|
||||
return boosterPlan.keySet().stream().max(Comparator.naturalOrder()).orElse(-1);
|
||||
}
|
||||
|
||||
private List<String> pickRandom(List<String> source, int count) {
|
||||
private List<String> pickRandom(List<String> source, int count, boolean remove) {
|
||||
if (source.isEmpty() || count <= 0) return Collections.emptyList();
|
||||
|
||||
int size = source.size();
|
||||
@@ -154,10 +203,18 @@ public class TableDraftDefinitionBuilder {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
Random rand = new Random();
|
||||
while (selectedIndexes.size() < count) {
|
||||
int randomIndex = rand.nextInt(size);
|
||||
if (selectedIndexes.add(randomIndex)) {
|
||||
result.add(source.get(randomIndex));
|
||||
while (result.size() < count) {
|
||||
int chosenIndex;
|
||||
if (size > 0) {
|
||||
chosenIndex = rand.nextInt(size);
|
||||
} else {
|
||||
chosenIndex = 0;
|
||||
}
|
||||
if (remove) {
|
||||
result.add(source.remove(chosenIndex));
|
||||
size--;
|
||||
} else if (selectedIndexes.add(chosenIndex)) {
|
||||
result.add(source.get(chosenIndex));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -165,6 +222,18 @@ public class TableDraftDefinitionBuilder {
|
||||
};
|
||||
}
|
||||
|
||||
private static void addSetToPool(Map<String, List<String>> cardPools, Map<String, List<String>> setPools, Map<String, List<String>> draftPools, String poolName, String setToAdd) {
|
||||
if (cardPools.containsKey(setToAdd)) {
|
||||
draftPools.get(poolName).addAll(cardPools.get(setToAdd));
|
||||
} else if (setPools.containsKey(setToAdd)) {
|
||||
for (String setName : setPools.get(setToAdd)) {
|
||||
addSetToPool(cardPools, setPools, draftPools, poolName, setName);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid JSON content");
|
||||
}
|
||||
}
|
||||
|
||||
private static StartingCollectionProducer buildStartingCollectionProducer(JSONArray jsonArray) {
|
||||
|
||||
return new StartingCollectionProducer() {
|
||||
|
||||
@@ -29,7 +29,7 @@ public abstract class AbstractDraftCardEvaluator {
|
||||
|
||||
|
||||
// This is what bots pick according to
|
||||
public final Map<String, Double> getValuesMap(Map<String, Integer> winningMap, Map<String, Integer> losingMap, int gamesAnalyzed) {
|
||||
public Map<String, Double> getValuesMap(Map<String, Integer> winningMap, Map<String, Integer> losingMap, int gamesAnalyzed) {
|
||||
// Merge win and lose maps (they are kept separate for potential wr info)
|
||||
Map<String, Integer> mergedMap = mergeMaps(winningMap, losingMap);
|
||||
|
||||
@@ -54,7 +54,7 @@ public abstract class AbstractDraftCardEvaluator {
|
||||
return shiftedMap;
|
||||
}
|
||||
|
||||
private static Map<String, Integer> mergeMaps(Map<String, Integer> map1, Map<String, Integer> map2) {
|
||||
static Map<String, Integer> mergeMaps(Map<String, Integer> map1, Map<String, Integer> map2) {
|
||||
Map<String, Integer> result = new HashMap<>(map1);
|
||||
|
||||
map2.forEach((key, value) -> result.merge(key, value, Integer::sum));
|
||||
@@ -62,7 +62,7 @@ public abstract class AbstractDraftCardEvaluator {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Double> normalizeCountByDraftPackChance(Map<String, Integer> map, int gamesAnalyzed) {
|
||||
Map<String, Double> normalizeCountByDraftPackChance(Map<String, Integer> map, int gamesAnalyzed) {
|
||||
Map<String, Double> normalizedMap = new HashMap<>();
|
||||
|
||||
map.forEach((key, value) -> {
|
||||
@@ -155,7 +155,7 @@ public abstract class AbstractDraftCardEvaluator {
|
||||
return fpInflatedMap;
|
||||
}
|
||||
|
||||
private Map<String, Double> shift(Map<String, Double> map) {
|
||||
Map<String, Double> shift(Map<String, Double> map) {
|
||||
double min = map.values().stream().min(Double::compareTo).orElse(0.0);
|
||||
|
||||
double positiveShift;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gempukku.lotro.draft3.evaluator;
|
||||
|
||||
import com.gempukku.lotro.common.AppConfig;
|
||||
import com.gempukku.lotro.game.CardNotFoundException;
|
||||
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
|
||||
import com.gempukku.lotro.game.ReplayMetadata;
|
||||
import com.gempukku.util.JsonUtils;
|
||||
@@ -46,6 +47,7 @@ public class Evaluator {
|
||||
// Define what we care for
|
||||
assignmentList.add(new Assignment("Limited - FOTR", "draft"));
|
||||
assignmentList.add(new Assignment("Limited - TTT", "draft"));
|
||||
assignmentList.add(new Assignment("Limited - Hobbit", "draft"));
|
||||
|
||||
System.out.println("Game history reading started at " + new SimpleDateFormat("HH.mm.ss").format(new Date()));
|
||||
// Load decks from the past
|
||||
@@ -60,29 +62,39 @@ public class Evaluator {
|
||||
|
||||
FotrDraftCardEvaluator fotrDraftCardEvaluator = new FotrDraftCardEvaluator(library);
|
||||
TttDraftCardEvaluator tttDraftCardEvaluator = new TttDraftCardEvaluator(library);
|
||||
HobbitDraftCardEvaluator hobbitDraftCardEvaluator = new HobbitDraftCardEvaluator(library);
|
||||
// Send the loaded data to card evaluators -> they convert card counts to values from 0.0 to 1.0
|
||||
// This is what bots pick according to in FotR drafts
|
||||
var fotrValues = fotrDraftCardEvaluator.getValuesMap(assignmentList.getFirst().winningMap, assignmentList.get(0).losingMap, assignmentList.getFirst().gamesAnalyzed);
|
||||
// Those are values to base fotr draft pools cuts on
|
||||
var fotrPlayRates = fotrDraftCardEvaluator.getPlayRateMap(assignmentList.getFirst().deckCount, assignmentList.getFirst().gamesAnalyzed);
|
||||
|
||||
// This is what bots pick according to in TTT drafts
|
||||
var tttValues = tttDraftCardEvaluator.getValuesMap(assignmentList.get(1).winningMap, assignmentList.get(1).losingMap, assignmentList.get(1).gamesAnalyzed);
|
||||
// Those are values to base TTT draft pools cuts on
|
||||
var tttPlayRates = tttDraftCardEvaluator.getPlayRateMap(assignmentList.get(1).deckCount, assignmentList.get(1).gamesAnalyzed);
|
||||
|
||||
var hobbitValues = hobbitDraftCardEvaluator.getValuesMap(assignmentList.get(2).winningMap, assignmentList.get(2).losingMap, assignmentList.get(2).gamesAnalyzed);
|
||||
|
||||
// Data from solo drafts do not contain rare one ring cards, don't forget to add some value manually after
|
||||
System.out.println("===FOTR VALUES");
|
||||
System.out.println("Games analyzes: " + assignmentList.get(0).gamesAnalyzed);
|
||||
printJsonStyle(fotrValues); // For json file
|
||||
printMapStyle(fotrValues); // For cached maps in evaluators (not being used right now)
|
||||
System.out.println("===FOTR PLAY RATES");
|
||||
// Regular draft - all rares included, U/C with play rate lower than 0.01 are cut
|
||||
// Power draft - R with play rate lower than 0.02 and U/C with play rate lower than 0.05 are cut
|
||||
printMapStyle(fotrPlayRates);
|
||||
printHumanReadable(fotrPlayRates, library);
|
||||
|
||||
System.out.println("===TTT VALUES");
|
||||
System.out.println("Games analyzes: " + assignmentList.get(1).gamesAnalyzed);
|
||||
printJsonStyle(tttValues);
|
||||
printMapStyle(tttValues);
|
||||
System.out.println("===TTT PLAY RATES");
|
||||
printMapStyle(tttPlayRates);
|
||||
printHumanReadable(tttPlayRates, library);
|
||||
|
||||
System.out.println("===HOBBIT VALUES");
|
||||
System.out.println("Games analyzes: " + assignmentList.get(2).gamesAnalyzed);
|
||||
printJsonStyle(hobbitValues);
|
||||
printHumanReadable(hobbitValues, library);
|
||||
}
|
||||
|
||||
private static void analyzeSummary(Path jsonFile, List<Assignment> assignmentList) {
|
||||
@@ -102,21 +114,29 @@ public class Evaluator {
|
||||
assignment.gamesAnalyzed++;
|
||||
|
||||
assignment.deckCount.merge(winningDeck.RingBearer.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
assignment.deckCount.merge(winningDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
if (winningDeck.Ring != null) {
|
||||
assignment.deckCount.merge(winningDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
}
|
||||
Set<String> winningCardSet = new HashSet<>(winningDeck.DrawDeck);
|
||||
winningCardSet.forEach(card -> assignment.deckCount.merge(card.replace("*", "").replace("T", ""), 1, Integer::sum));
|
||||
|
||||
assignment.deckCount.merge(losingDeck.RingBearer.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
assignment.deckCount.merge(losingDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
if (losingDeck.Ring != null) {
|
||||
assignment.deckCount.merge(losingDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
}
|
||||
Set<String> losingCardSet = new HashSet<>(losingDeck.DrawDeck);
|
||||
losingCardSet.forEach(card -> assignment.deckCount.merge(card.replace("*", "").replace("T", ""), 1, Integer::sum));
|
||||
|
||||
assignment.winningMap.merge(winningDeck.RingBearer.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
assignment.winningMap.merge(winningDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
if (winningDeck.Ring != null) {
|
||||
assignment.winningMap.merge(winningDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
}
|
||||
winningDeck.DrawDeck.forEach(card -> assignment.winningMap.merge(card.replace("*", "").replace("T", ""), 1, Integer::sum));
|
||||
|
||||
assignment.losingMap.merge(losingDeck.RingBearer.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
assignment.losingMap.merge(losingDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
if (losingDeck.Ring != null) {
|
||||
assignment.losingMap.merge(losingDeck.Ring.replace("*", "").replace("T", ""), 1, Integer::sum);
|
||||
}
|
||||
losingDeck.DrawDeck.forEach(card -> assignment.losingMap.merge(card.replace("*", "").replace("T", ""), 1, Integer::sum));
|
||||
}
|
||||
}
|
||||
@@ -153,4 +173,20 @@ public class Evaluator {
|
||||
System.out.println(s);
|
||||
});
|
||||
}
|
||||
|
||||
private static void printHumanReadable(Map<String, Double> toPrint, LotroCardBlueprintLibrary library) {
|
||||
// 33_44 Lavastone Giant: 0.8333787095017696
|
||||
toPrint.entrySet().stream()
|
||||
.sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue()))
|
||||
.forEach(stringDoubleEntry -> {
|
||||
try {
|
||||
String s = stringDoubleEntry.getKey() + " "
|
||||
+ library.getLotroCardBlueprint(stringDoubleEntry.getKey()).getFullName() + ": " +
|
||||
stringDoubleEntry.getValue();
|
||||
System.out.println(s);
|
||||
} catch (CardNotFoundException ignore) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.gempukku.lotro.draft3.evaluator;
|
||||
|
||||
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
|
||||
import org.apache.commons.collections4.map.UnmodifiableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HobbitDraftCardEvaluator extends AbstractDraftCardEvaluator {
|
||||
private static final Map<String, Double> AVERAGE_STARTING_COUNT_MAP = new HashMap<>();
|
||||
|
||||
private static final List<String> freePeoplesPack = List.of(
|
||||
"30_1", "30_1", "30_3", "30_3", "30_4", "30_4", "30_13", "30_13",
|
||||
"30_14", "30_14", "30_20", "30_20", "30_23", "30_23", "30_24", "30_24",
|
||||
"30_30", "30_30", "30_31", "30_31", "30_58", "30_59", "30_60", "30_61",
|
||||
"30_62", "30_63", "30_64", "30_65");
|
||||
private static final List<String> swarmPack1 = List.of(
|
||||
"31_30", "31_30", "31_30", "31_30", "31_31", "31_31", "31_31", "31_31",
|
||||
"31_32", "31_32", "31_32", "31_32", "31_34", "31_34", "31_35", "31_35",
|
||||
"31_35", "31_35", "31_36", "31_36", "31_49", "31_49", "31_49", "31_51",
|
||||
"31_51", "31_51", "31_51", "31_52", "31_52", "31_52", "31_53", "31_53",
|
||||
"31_53", "31_53", "31_54", "31_54", "31_55", "31_55", "31_55", "31_55");
|
||||
private static final List<String> swarmPack2 = List.of(
|
||||
"32_27", "32_27", "32_27", "32_27", "32_28", "32_28", "32_28", "32_28",
|
||||
"32_31", "32_31", "32_31", "32_32", "32_32", "32_32", "32_33", "32_33",
|
||||
"32_33", "32_34", "32_34", "32_34", "32_36", "32_36", "32_36", "32_38",
|
||||
"32_38", "32_40", "32_40", "32_40", "32_41", "32_41", "32_41", "32_41",
|
||||
"32_42", "32_42", "32_42", "32_42", "32_43", "32_43", "32_43", "32_43");
|
||||
private static final List<String> swarmPack3 = List.of(
|
||||
"33_38", "33_38", "33_38", "33_38", "33_39", "33_39", "33_39", "33_39",
|
||||
"33_40", "33_40", "33_40", "33_41", "33_41", "33_41", "33_43", "33_43",
|
||||
"33_45", "33_45", "33_45", "33_45", "33_46", "33_46", "33_46", "33_47",
|
||||
"33_47", "33_47", "33_47", "33_48", "33_48", "33_48", "33_49", "33_49",
|
||||
"33_49", "33_49", "33_50", "33_50", "33_50", "33_51", "33_51", "33_51");
|
||||
private static final List<String> beatDownPack1 = List.of(
|
||||
"31_19", "31_19", "31_19", "31_19", "31_20", "31_20", "31_20", "31_21",
|
||||
"31_21", "31_21", "31_23", "31_23", "31_23", "31_24", "31_24", "31_26",
|
||||
"31_26", "31_26", "31_27", "31_27", "31_27", "31_27", "31_28", "31_28",
|
||||
"31_28", "31_56", "31_56", "31_56", "31_58", "31_58", "31_58", "31_59",
|
||||
"31_59", "31_59", "31_60", "31_60", "31_60", "31_61", "31_61", "31_61");
|
||||
private static final List<String> beatDownPack2 = List.of(
|
||||
"32_37", "32_37", "32_37", "32_37", "32_44", "32_44", "32_45", "32_45",
|
||||
"32_45", "32_45", "32_50", "32_50", "32_51", "32_51", "32_51", "32_51",
|
||||
"32_52", "32_52", "32_52", "32_52", "32_54", "32_54", "32_54", "32_55",
|
||||
"32_55", "32_56", "32_56", "32_56", "32_58", "32_58", "32_58", "32_59",
|
||||
"32_60", "32_61", "32_62", "32_63", "32_64", "32_65", "32_66", "32_67");
|
||||
private static final List<String> beatDownPack3 = List.of(
|
||||
"33_24", "33_24", "33_24", "33_25", "33_25", "33_25", "33_26", "33_26",
|
||||
"33_26", "33_27", "33_27", "33_27", "33_28", "33_28", "33_28", "33_29",
|
||||
"33_29", "33_29", "33_30", "33_30", "33_30", "33_31", "33_31", "33_31",
|
||||
"33_32", "33_32", "33_32", "33_34", "33_34", "33_34", "33_35", "33_35",
|
||||
"33_35", "33_42", "33_42", "33_42", "33_42", "33_44", "33_44", "33_44");
|
||||
private static final List<String> packA = List.of(
|
||||
"31_38", "31_38", "31_38", "31_39", "31_39", "31_40", "31_40", "31_41",
|
||||
"31_41", "31_41", "31_42", "31_42", "31_42", "31_43", "31_43", "31_22",
|
||||
"31_22", "31_22", "31_57", "31_57", "31_45", "31_45");
|
||||
private static final List<String> packB = List.of(
|
||||
"32_1", "32_1", "32_1", "32_2", "32_2", "32_2", "32_4", "32_4",
|
||||
"32_5", "32_5", "32_6", "32_6", "32_8", "32_8", "32_8", "32_26",
|
||||
"32_26", "32_30", "32_30", "32_30", "32_49", "32_49");
|
||||
private static final List<String> packC = List.of(
|
||||
"32_15", "32_15", "32_15", "32_16", "32_16", "32_17", "32_17", "32_18",
|
||||
"32_18", "32_19", "32_19", "32_19", "32_20", "32_20", "32_20", "32_25",
|
||||
"32_25", "32_25", "32_53", "32_53", "32_47", "32_47");
|
||||
private static final List<String> packD = List.of(
|
||||
"31_3", "31_3", "31_3", "31_8", "31_8", "31_9", "31_9", "31_10",
|
||||
"31_10", "31_11", "31_11", "31_11", "31_12", "31_12", "31_12", "31_29",
|
||||
"31_29", "31_37", "31_37", "31_37", "31_46", "31_46");
|
||||
private static final List<String> packE = List.of(
|
||||
"31_1", "31_1", "31_2", "31_2", "31_2", "31_4", "31_4", "31_5",
|
||||
"31_5", "31_5", "31_6", "31_6", "31_7", "31_7", "31_7", "31_33",
|
||||
"31_33", "31_33", "31_48", "31_48", "31_47", "31_47");
|
||||
private static final List<String> packF = List.of(
|
||||
"32_3", "32_3", "32_3", "32_7", "32_7", "32_9", "32_9", "32_9",
|
||||
"32_10", "32_10", "32_11", "32_11", "32_11", "32_12", "32_12", "32_29",
|
||||
"32_29", "32_35", "32_35", "32_35", "32_48", "32_48");
|
||||
private static final List<String> packG = List.of(
|
||||
"32_13", "32_13", "32_13", "32_14", "32_14", "32_21", "32_21", "32_22",
|
||||
"32_22", "32_23", "32_23", "32_23", "32_24", "32_24", "32_24", "32_39",
|
||||
"32_39", "32_57", "32_57", "32_57", "32_46", "32_46");
|
||||
private static final List<String> packH = List.of(
|
||||
"31_13", "31_13", "31_13", "31_14", "31_14", "31_15", "31_15", "31_16",
|
||||
"31_16", "31_17", "31_17", "31_17", "31_18", "31_18", "31_18", "31_25",
|
||||
"31_25", "31_25", "31_50", "31_50", "31_44", "31_44");
|
||||
private static final List<String> packI = List.of(
|
||||
"33_1", "33_1", "33_3", "33_3", "33_3", "33_4", "33_4", "33_10",
|
||||
"33_10", "33_10", "33_11", "33_11", "33_11", "33_12", "33_12", "33_36",
|
||||
"33_36", "33_36", "33_59", "33_59", "33_56", "33_56");
|
||||
private static final List<String> packJ = List.of(
|
||||
"33_2", "33_2", "33_5", "33_5", "33_5", "33_6", "33_6", "33_6",
|
||||
"33_7", "33_7", "33_8", "33_8", "33_9", "33_9", "33_9", "33_37",
|
||||
"33_37", "33_37", "33_60", "33_60", "33_58", "33_58");
|
||||
private static final List<String> packK = List.of(
|
||||
"33_13", "33_13", "33_13", "33_14", "33_14", "33_14", "33_15", "33_15",
|
||||
"33_16", "33_16", "33_17", "33_17", "33_17", "33_18", "33_18", "33_33",
|
||||
"33_33", "33_33", "33_61", "33_61", "33_57", "33_57");
|
||||
private static final List<String> packL = List.of(
|
||||
"33_19", "33_19", "33_20", "33_20", "33_21", "33_21", "33_52", "33_52",
|
||||
"33_52", "33_53", "33_53", "33_53", "33_54", "33_54", "33_54", "33_22",
|
||||
"33_22", "33_23", "33_23", "33_23", "33_55", "33_55");
|
||||
private static final List<String> shadowPacks = new ArrayList<>();
|
||||
private static final List<String> supplementaryPacks = new ArrayList<>();
|
||||
private static final List<String> everything = new ArrayList<>();
|
||||
|
||||
|
||||
static {
|
||||
List<String> startingDeck = List.of(
|
||||
"30_1", "30_2", "30_3", "30_4", "30_5", "30_6", "30_7", "30_8",
|
||||
"30_9", "30_10", "30_11", "30_12", "30_13", "30_14", "30_15", "30_16",
|
||||
"30_17", "30_18", "30_19", "30_20", "30_21", "30_22", "30_23", "30_24",
|
||||
"30_29", "30_30", "30_31", "30_47", "30_48", "30_32", "30_32", "30_32",
|
||||
"30_33", "30_33", "30_34", "30_34", "30_35", "30_35", "30_35", "30_35",
|
||||
"30_36", "30_36", "30_37", "30_37", "30_38", "30_38", "30_39", "30_39",
|
||||
"30_39", "30_40", "30_40", "30_40", "30_41", "30_41", "30_42", "30_42",
|
||||
"30_42", "30_42", "30_66", "30_49", "30_50", "30_51", "30_52", "30_53",
|
||||
"30_54", "30_55", "30_56", "30_57");
|
||||
|
||||
for (String card : startingDeck) {
|
||||
AVERAGE_STARTING_COUNT_MAP.merge(card, 1.0, Double::sum);
|
||||
}
|
||||
List.of("30_25", "30_26", "30_27", "30_28").forEach(gandalf -> AVERAGE_STARTING_COUNT_MAP.put(gandalf, 0.25));
|
||||
List.of("30_43", "30_44", "30_45", "30_46").forEach(bilbo -> AVERAGE_STARTING_COUNT_MAP.put(bilbo, 0.25));
|
||||
|
||||
shadowPacks.addAll(swarmPack1);
|
||||
shadowPacks.addAll(swarmPack2);
|
||||
shadowPacks.addAll(swarmPack3);
|
||||
shadowPacks.addAll(beatDownPack1);
|
||||
shadowPacks.addAll(beatDownPack2);
|
||||
shadowPacks.addAll(beatDownPack3);
|
||||
|
||||
supplementaryPacks.addAll(packA);
|
||||
supplementaryPacks.addAll(packB);
|
||||
supplementaryPacks.addAll(packC);
|
||||
supplementaryPacks.addAll(packD);
|
||||
supplementaryPacks.addAll(packE);
|
||||
supplementaryPacks.addAll(packF);
|
||||
supplementaryPacks.addAll(packG);
|
||||
supplementaryPacks.addAll(packH);
|
||||
supplementaryPacks.addAll(packI);
|
||||
supplementaryPacks.addAll(packJ);
|
||||
supplementaryPacks.addAll(packK);
|
||||
supplementaryPacks.addAll(packL);
|
||||
|
||||
everything.addAll(freePeoplesPack);
|
||||
everything.addAll(freePeoplesPack);
|
||||
everything.addAll(freePeoplesPack);
|
||||
everything.addAll(freePeoplesPack);
|
||||
everything.addAll(shadowPacks);
|
||||
everything.addAll(shadowPacks);
|
||||
everything.addAll(supplementaryPacks);
|
||||
}
|
||||
|
||||
public HobbitDraftCardEvaluator(LotroCardBlueprintLibrary library) {
|
||||
super(library);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getValuesMap(Map<String, Integer> winningMap, Map<String, Integer> losingMap, int gamesAnalyzed) {
|
||||
// Merge win and lose maps (they are kept separate for potential wr info)
|
||||
Map<String, Integer> mergedMap = mergeMaps(winningMap, losingMap);
|
||||
// Lower count of cards from Draft Packs
|
||||
Map<String, Double> startingCollectionNormalizedCardCountMap = normalizeCountByDraftPackChance(mergedMap, gamesAnalyzed);
|
||||
|
||||
// Normalize for uneven set size
|
||||
Map<String, Double> packNormalizedCardCountMap = normalizeCountByPackType(startingCollectionNormalizedCardCountMap);
|
||||
|
||||
// Normalize count based on rarities
|
||||
Map<String, Double> normalizedCardCountMap = normalizeCountByRarity(packNormalizedCardCountMap);
|
||||
|
||||
// Make sure all values are positive and in 0-1 range
|
||||
Map<String, Double> shiftedMap = shift(normalizedCardCountMap);
|
||||
|
||||
return shiftedMap;
|
||||
}
|
||||
|
||||
private Map<String, Double> normalizeCountByRarity(Map<String, Double> map) {
|
||||
Map<String, Double> normalizedMap = new HashMap<>();
|
||||
|
||||
map.forEach((key, value) -> normalizedMap.put(key, value / everything.stream().filter(s -> s.equals(key)).count()));
|
||||
|
||||
return normalizedMap;
|
||||
|
||||
}
|
||||
|
||||
private Map<String, Double> normalizeCountByPackType(Map<String, Double> map) {
|
||||
|
||||
Map<String, Double> normalizedMap = new HashMap<>();
|
||||
|
||||
map.forEach((key, value) -> {
|
||||
if (shadowPacks.contains(key)) {
|
||||
normalizedMap.put(key, value * 3.0); // appear in 1/3 of drafts
|
||||
} else if (freePeoplesPack.contains(key)){
|
||||
normalizedMap.put(key, value); // appear in all drafts
|
||||
} else if (supplementaryPacks.contains(key)) {
|
||||
normalizedMap.put(key, value * 3.0); // appear in 1/3 of drafts (solo draft is using 4 packs out of 12)
|
||||
}
|
||||
});
|
||||
|
||||
return normalizedMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getAverageStartingCardMap() {
|
||||
return UnmodifiableMap.unmodifiableMap(AVERAGE_STARTING_COUNT_MAP);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user