Last active
December 28, 2017 01:07
-
-
Save ealmansi/86d9eded23851a00d487 to your computer and use it in GitHub Desktop.
TEG: probabilidad de conquistar otro país mediante ataques reiterados
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
#!/usr/bin/env python3 | |
import math; | |
########################################################################################## | |
# Basado en: http://openpool.com.ar/reglamento/T.E.G.-REGLAMENTO.pdf | |
# | |
# Probabilidad de conquistar otro pais si atacamos sin frenar hasta que: | |
# i) conquistamos el otro pais, o | |
# ii) nos quedamos con una sola ficha y no podemos atacar más | |
# | |
# Tabla: Cantidad de ejércitos disponibles (Atacante \ Defensor) vs Probabilidad (%) | |
# | |
# A\D | 1 2 3 4 5 6 7 8 9 10 | |
# ____________________________________________________________________ | |
# 1 | 41.7 10.6 1.8 0.3 0.1 0.0 0.0 0.0 0.0 0.0 | |
# 2 | 79.5 43.7 18.1 9.0 3.6 1.8 0.7 0.3 0.1 0.1 | |
# 3 | 95.2 73.6 45.7 35.2 23.7 14.2 10.2 6.8 4.0 2.8 | |
# 4 | 98.9 85.4 56.5 45.9 34.4 23.3 17.7 12.4 8.5 6.2 | |
# 5 | 99.7 93.4 68.6 57.0 45.4 33.5 25.7 19.4 14.2 10.4 | |
# 6 | 99.9 96.4 79.9 69.2 57.3 45.1 36.2 28.2 21.4 16.5 | |
# 7 | 100.0 98.4 85.0 75.7 65.9 54.1 44.9 36.4 28.8 22.9 | |
# 8 | 100.0 99.2 89.4 82.0 73.1 62.4 53.3 44.6 36.5 29.7 | |
# 9 | 100.0 99.6 93.4 87.0 79.2 70.1 61.3 52.6 44.3 37.0 | |
# 10 | 100.0 99.8 95.1 90.1 84.1 76.0 67.9 59.8 51.6 44.1 | |
# | |
# Aclaración: para el atacante, la cantidad de ejércitos disponibles es la cantidad total | |
# de ejércitos en el país atacante menos uno; para el defensor, es la cantidad total de | |
# ejércitos en el país defensor. Por ejemplo, si ataco desde un país con 5 fichas a un | |
# país con 3 fichas, miro la posición (4, 3) en la tabla: 56.5%. | |
########################################################################################## | |
def computarTabla(max_ejs_atacantes, max_ejs_defensores): | |
pt = computarProbabilidadesTransicion() | |
tb = [[-1 for j in range(max_ejs_defensores + 1)] for i in range(max_ejs_atacantes + 1)] | |
for i in range(1, max_ejs_atacantes + 1): | |
tb[i][0] = 1 | |
for j in range(1, max_ejs_defensores + 1): | |
tb[0][j] = 0 | |
for i in range(1, max_ejs_atacantes + 1): | |
for j in range(1, max_ejs_defensores + 1): | |
ejs_en_ataque = min(i, 3) | |
ejs_en_defensa = min(j, 3) | |
ejs_en_juego = min(ejs_en_ataque, ejs_en_defensa) | |
tb[i][j] = 0 | |
for k in range(ejs_en_juego + 1): | |
ejs_en_ataque_p = ejs_en_ataque - k | |
ejs_en_defensa_p = ejs_en_defensa - (ejs_en_juego - k) | |
p = pt[(ejs_en_ataque, ejs_en_defensa, | |
ejs_en_ataque_p, ejs_en_defensa_p)] | |
i_p, j_p = i - k, j - (ejs_en_juego - k) | |
tb[i][j] += p * tb[i_p][j_p] | |
return tb | |
def computarProbabilidadesTransicion(): | |
pt = {} | |
for ejs_en_ataque in range(1, 3 + 1): | |
for ejs_en_defensa in range(1, 3 + 1): | |
ejs_en_juego = min(ejs_en_ataque, ejs_en_defensa) | |
# inicializo el conteo de veces que sucedio cada posible resultado en 0 | |
for k in range(ejs_en_juego + 1): | |
ejs_en_ataque_p = ejs_en_ataque - k | |
ejs_en_defensa_p = ejs_en_defensa - (ejs_en_juego - k) | |
pt[(ejs_en_ataque, ejs_en_defensa, | |
ejs_en_ataque_p, ejs_en_defensa_p)] = 0.0 | |
# simulo cualquier par posible de tirada del atacante / del defensor | |
for tirada_atacante in obtenerPosiblesTiradas(ejs_en_ataque): | |
for tirada_defensor in obtenerPosiblesTiradas(ejs_en_defensa): | |
# cuento la cantidad de ejercitos vencidos por el atacante | |
ejs_vencidos = 0 | |
for i in range(ejs_en_juego): | |
if tirada_atacante[i] > tirada_defensor[i]: | |
ejs_vencidos = ejs_vencidos + 1 | |
# incremento el conteo de veces que sucedio este resultado | |
ejs_en_ataque_p = ejs_en_ataque - (ejs_en_juego - ejs_vencidos) | |
ejs_en_defensa_p = ejs_en_defensa - ejs_vencidos | |
pt[(ejs_en_ataque, ejs_en_defensa, | |
ejs_en_ataque_p, ejs_en_defensa_p)] += 1.0 | |
# transformo los conteos en probabilidades dividiendo por el total de resultados posibles | |
cant_resultados_posibles = int(math.pow(6, ejs_en_ataque + ejs_en_defensa)) | |
for k in range(ejs_en_juego + 1): | |
ejs_en_ataque_p = ejs_en_ataque - k | |
ejs_en_defensa_p = ejs_en_defensa - (ejs_en_juego - k) | |
pt[(ejs_en_ataque, ejs_en_defensa, | |
ejs_en_ataque_p, ejs_en_defensa_p)] /= cant_resultados_posibles | |
return pt | |
def obtenerPosiblesTiradas(ejs): | |
for n in range(0, int(math.pow(6, ejs))): | |
tirada = [] | |
for i in range(1, ejs + 1): | |
tirada.append(n % 6) | |
n = n / 6 | |
tirada.sort(reverse=True) | |
yield tirada | |
def imprimirTabla(tb, max_ejs_atacantes, max_ejs_defensores): | |
for i in range(1, max_ejs_atacantes + 1): | |
for j in range(1, max_ejs_defensores + 1): | |
print('{0:5.1f}'.format(100 * tb[i][j]), end='') | |
if (j + 1 < max_ejs_defensores + 1): | |
print(' ', end='') | |
print() | |
def main(): | |
max_ejs_atacantes = 10 | |
max_ejs_defensores = 10 | |
tb = computarTabla(max_ejs_atacantes, max_ejs_defensores) | |
imprimirTabla(tb, max_ejs_atacantes, max_ejs_defensores) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment