-
-
Save leberechtreinhold/5bdb6c345eb8842b5ffc6f8b58cecd73 to your computer and use it in GitHub Desktop.
This file contains 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
# -*- coding: utf-8 -*- | |
# import pprint | |
# import csv | |
import xlsxwriter | |
MAX_BONUS = 9 | |
# Assumes the following: | |
# All elements are unsupported, Pikes are supported, Bows are being charged and | |
# is considered the first turn, and is close combat (the art is not shooting) | |
# Terrain is assumed plain | |
TROOP_NAMES = ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Art","Wwg"] | |
MOUNTED_TROOPS = ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm"] | |
TROOPS = { | |
"El": [4,5], | |
"Kn": [3,4], | |
"Hch": [3,4], | |
"Cv": [3,3], | |
"Lch": [3,3], | |
"Sch": [4,4], | |
"Cm": [2,4], | |
"Lh": [2,2], | |
"Lcm": [2,2], | |
"Sp": [4,4], | |
"Pk": [6,7], | |
"Bd": [5,3], | |
"Bw": [2,4], | |
"Wb": [3,2], | |
"Hd": [3,2], | |
"Ax": [3,2], | |
"Ps": [2,2], | |
"Art": [2,2], | |
"Wwg": [3,4], | |
} | |
KILLED_BY_SIMPLE = { | |
"El": ["Ps", "Ax", "Lh", "Lcm"], | |
"Kn": ["El", "Sch", "Lh", "Lcm", "Bw"], | |
"Hch": ["El", "Sch", "Lh", "Lcm", "Bw"], | |
"Cv": [], | |
"Lch": [], | |
"Sch": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Art","Wwg"], | |
"Cm": [], | |
"Lh": [], | |
"Lcm": [], | |
"Sp": ["El", "Kn", "Lh", "Sch", "Wb"], | |
"Pk": ["El", "Kn", "Lh", "Sch", "Wb"], | |
"Bd": ["Kn", "Sch", "Wb"], | |
"Bw": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm"], | |
"Wb": ["El","Kn","Sch"], | |
"Hd": ["El","Kn","Sch","Wb"], | |
"Ax": ["Kn"], | |
"Ps": ["Kn","Cv","Cm"], | |
"Art": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Art","Wwg"], | |
"Wwg": ["El"], | |
} | |
KILLED_BY_DOUBLE = { | |
"El": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Kn": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Hch": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Cv": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Bd","Bw","Wb","Ax","Ps","Wwg"], | |
"Lch": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Sch": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Art","Wwg"], | |
"Cm": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Lh": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Bw","Ps"], | |
"Lcm": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Bw","Ps"], | |
"Sp": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Pk": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Bd": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Bw": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Wb": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Hd": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Ax": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
"Ps": ["Kn","Cv","Cm","Lh","Lch","Bw","Ax","Ps"], | |
"Art": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Art","Wwg"], | |
"Wwg": ["El","Kn","Hch","Cv","Lch","Sch","Cm","Lh","Lcm","Sp","Pk","Bd","Bw","Wb","Hd","Ax","Ps","Wwg"], | |
} | |
def get_bonus(attacker, defender): | |
your_bonus = TROOPS[attacker][0] | |
if defender in MOUNTED_TROOPS: | |
your_bonus = TROOPS[attacker][1] | |
return your_bonus | |
def calculate_wins_by_dice(): | |
results_simple_win = {} | |
results_win_double = {} | |
for your_bonus in range(0,MAX_BONUS): | |
results_simple_win[your_bonus] = {} | |
results_win_double[your_bonus] = {} | |
for their_bonus in range(0,MAX_BONUS): | |
win_possibilties_simple = 0; | |
win_possibilties_double = 0; | |
for your_dice in range(1,7): | |
your_result = your_bonus + your_dice | |
for their_dice in range(1,7): | |
their_result = their_bonus + their_dice | |
if your_result > their_result: | |
win_possibilties_simple += 1 | |
if your_result >= their_result * 2: | |
win_possibilties_double += 1 | |
results_simple_win[your_bonus][their_bonus] = (win_possibilties_simple / 36.0) * 100.0 | |
results_win_double[your_bonus][their_bonus] = (win_possibilties_double / 36.0) * 100.0 | |
return results_simple_win, results_win_double | |
def calculate_kills_by_troop(results_simple_win, results_win_double): | |
# BEWARE, cant use dict.fromkeys(TROOP_NAMES, dict.fromkeys(TROOP_NAMES)) | |
# because that means all entries share the same reference | |
kill_by_troop = dict.fromkeys(TROOP_NAMES) | |
for key in kill_by_troop: | |
kill_by_troop[key] = dict.fromkeys(TROOP_NAMES) | |
for your_troop in TROOP_NAMES: | |
for their_troop in TROOP_NAMES: | |
your_bonus = get_bonus(your_troop, their_troop) | |
their_bonus = get_bonus(their_troop, your_troop) | |
is_killed_by_simple = your_troop in KILLED_BY_SIMPLE[their_troop] | |
is_killed_by_double = your_troop in KILLED_BY_DOUBLE[their_troop] | |
if is_killed_by_simple: | |
kill_by_troop[your_troop][their_troop] = results_simple_win[your_bonus][their_bonus] | |
#print(your_troop + " vs " + their_troop + ": " + str(kill_by_troop[your_troop][their_troop]) + " (Simple)") | |
elif is_killed_by_double: | |
kill_by_troop[your_troop][their_troop] = results_win_double[your_bonus][their_bonus] | |
#print(your_troop + " vs " + their_troop + ": " + str(kill_by_troop[your_troop][their_troop]) + " (Double)") | |
else: | |
kill_by_troop[your_troop][their_troop] = 0.0 | |
#print(your_troop + " vs " + their_troop + ": 0 " + "(Cannot)") | |
return kill_by_troop | |
def who_kills_what(): | |
kills_at_simple = dict.fromkeys(TROOP_NAMES) | |
kills_at_double = dict.fromkeys(TROOP_NAMES) | |
for troop_killed in TROOP_NAMES: | |
killers = KILLED_BY_SIMPLE[troop_killed] | |
for killer in killers: | |
if kills_at_simple[killer] is None: | |
kills_at_simple[killer] = set() | |
kills_at_simple[killer].add(troop_killed) | |
killers = KILLED_BY_DOUBLE[troop_killed] | |
for killer in killers: | |
if kills_at_double[killer] is None: | |
kills_at_double[killer] = set() | |
kills_at_double[killer].add(troop_killed) | |
return kills_at_simple, kills_at_double | |
def print_markdown(kills_at_simple, kills_at_double): | |
largest_str_simple = 0 | |
for troop in TROOP_NAMES: | |
len_str = len(','.join(kills_at_simple[troop])) | |
if (len_str > largest_str_simple): | |
largest_str_simple = len_str | |
print("Killer | {msg: <{width}} | Killed by double".format(msg="Killed by simple", width=largest_str_simple)) | |
print("-------|{0}|-----------------------".format('-' * (largest_str_simple + 2))) | |
for troop in TROOP_NAMES: | |
print("{killer: <6} | {simple_killed: <{width}} | {double_killed}" | |
.format(killer=troop, width=largest_str_simple, | |
simple_killed=','.join(kills_at_simple[troop]), | |
double_killed=','.join(kills_at_double[troop]))) | |
def write_table_dice_roll(worksheet, current_row, title, y_axis, x_axis, pos_threshold, neg_threshold, table_data, formats): | |
worksheet.write(current_row, 0, title, formats["format_title"]) | |
worksheet.write(current_row, 2, x_axis, formats["format_header"]) | |
for their_bonus in range(0,MAX_BONUS): | |
worksheet.write(current_row + 1, their_bonus + 2, their_bonus, formats["format_header"]) | |
worksheet.write(current_row + 2, 0, y_axis, formats["format_header"]) | |
for your_bonus in range(0,MAX_BONUS): | |
worksheet.write(your_bonus + current_row + 2, 1, your_bonus, formats["format_header"]) | |
for your_bonus in range(0,MAX_BONUS): | |
for their_bonus in range(0,MAX_BONUS): | |
row = your_bonus + current_row + 2 | |
col = their_bonus + 2 | |
val = table_data[your_bonus][their_bonus] | |
cellformat = formats["format_normal"] | |
if val > pos_threshold: | |
cellformat = formats["format_better_than"] | |
elif val < neg_threshold: | |
cellformat = formats["format_worse_than"] | |
worksheet.write(row, col, val, cellformat) | |
def write_table_kills(worksheet, current_row, title, y_axis, x_axis, pos_threshold, neg_threshold, table_data, formats): | |
worksheet.write(current_row, 0, title, formats["format_title"]) | |
worksheet.write(current_row, 2, x_axis, formats["format_header"]) | |
i = 0 | |
for troop in TROOP_NAMES: | |
worksheet.write(current_row + 1, i + 2, troop, formats["format_header"]) | |
i += 1 | |
worksheet.write(current_row + 2, 0, y_axis, formats["format_header"]) | |
i = 0 | |
for troop in TROOP_NAMES: | |
worksheet.write(i + current_row + 2, 1, troop, formats["format_header"]) | |
i += 1 | |
i = 0 | |
for your_troop in TROOP_NAMES: | |
j = 0 | |
for their_troop in TROOP_NAMES: | |
row = i + current_row + 2 | |
col = j + 2 | |
val = table_data[your_troop][their_troop] | |
cellformat = formats["format_normal"] | |
if val > pos_threshold: | |
cellformat = formats["format_better_than"] | |
elif val < neg_threshold: | |
cellformat = formats["format_worse_than"] | |
worksheet.write(row, col, val, cellformat) | |
j += 1 | |
i += 1 | |
def main(): | |
results_simple_win, results_win_double = calculate_wins_by_dice() | |
kill_by_troop = calculate_kills_by_troop(results_simple_win, results_win_double) | |
workbook = xlsxwriter.Workbook('dbastats.xlsx') | |
worksheet = workbook.add_worksheet() | |
formats = {} | |
formats["format_title"] = workbook.add_format({'bold': True, 'font_color': '#eeeeee', 'bg_color': '#222222'}) | |
formats["format_header"] = workbook.add_format({'bold': True}) | |
formats["format_better_than"] = workbook.add_format({'font_color': '#eeeeee', 'bg_color': '#46B64A', 'num_format': '0.0'}) | |
formats["format_worse_than"] = workbook.add_format({'font_color': '#eeeeee', 'bg_color': '#C0504D', 'num_format': '0.0'}) | |
formats["format_normal"] = workbook.add_format({'num_format': '0.0'}) | |
current_row = 0 | |
write_table_dice_roll(worksheet, current_row, "Win By Simple", "Your bonus", "Their bonus", 60, 40, results_simple_win, formats) | |
current_row = MAX_BONUS + 3 | |
write_table_dice_roll(worksheet, current_row, "Win By double", "Your bonus", "Their bonus", 60, 40, results_win_double, formats) | |
current_row = (MAX_BONUS + 3) * 2 | |
write_table_kills(worksheet, current_row, "Kill by troop", "Your troop", "Their troop", 20, 1, kill_by_troop, formats) | |
workbook.close() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment