proba_m44.py

Created by gradient01

Created on January 26, 2026

7.15 KB

This script is used to evaluate the probability of destroying a unit in the board game Memoir ‘44 with the binomial law. You can adjust:

  • the number of dice rolled,
  • the type of unit targeted,
  • the number of figures in the unit targeted,
  • whether retreating results in a loss,
  • whether a star results in a loss.

For more details, refer to the official rules of Memoir ‘44.


from kandinsky import *
from ion import *
from math import *
from time import *


##############
# letters.py #
##############

def draw_letters(string,x,y,size=1,col=(0,0,0),percent=False,sep=1,max=9999):
  characts={
    "0":"111111000111111",
    "1":"0100011111",
    "2":"101111010111101",
    "3":"101011010111111",
    "4":"111000010011111",
    "5":"111011010110111",
    "6":"111111010110111",
    "7":"100001000011111",
    "8":"111111010111111",
    "9":"111011010111111",
    " ":"00000",
    ".":"00001",
    "%":"100110010011001",
    "a":"01111101001010001111",
    "b":"11111101011010101010",
    "c":"011101000110001",
    "d":"11111100011000101110",
    "e":"011101010110001",
    "f":"011111010010000",
    "g":"01110100011010110111",
    "h":"11111001000010011111",
    "i":"10111",
    "j":"000100000111111",
    "k":"11111001000101010001",
    "l":"111100000100001",
    "m":"1111101000001000100011111",
    "n":"11111110000011111111",
    "o":"01110100011000101110",
    "p":"11111101001010001000",
    "q":"01110100011001101111",
    "r":"111111011001101",
    "s":"011011010110110",
    "t":"100001111110000",
    "u":"111110000111111",
    "v":"1100000110000010011011000",
    "w":"110000011100010000100011111000",
    "x":"110110010011011",
    "y":"111000001111100",
    "z":"10001100111010111001"
  }
  xo = x
  x -= size
  if percent:
    string = str(string)[:max]+" %"
  else:
    string = str(string)[:max]
  for charact in string:
    pixels = characts[charact]
    for i in range(len(pixels)):
      if i%5 == 0:
        x+=size
      if pixels[i]=="1":
        fill_rect(x,(i%5)*size+y,size,size,col)
    x+=sep
  return x - xo


###########
# menu.py #
###########

def k(key):
  if keydown(key):
    while keydown(key):
      pass
    return True
  return False

characters = [i for i in "abcdefghijklmnopqrstuvwxyz"]
colors = {
"b":(0,0,0),
"i":(0,118,255),
"a":(255,153,0),
"f":(255,0,0),
"t":(31,255,0),
}
logos = {
  "b":["0","0jc","0je","0if","0gh","0fi","0fi","0fi","0fi","0ej","0ej","0ej","0fi","0fi","0fi","0gaaf","0gabe","0gabd","0gabc"],
  "i":["0","0","0","0","0","0oe","0acbccdca","1n","1n","1dbcce","0aaebgd","0fbka","0fb","0fb","0fb","0fb","0fa","0fa","0fa"],
  "a":["0","0","0oa","0oa","0oa","0oa","0kbba","0kbaa","0kd","0jf","0ig","0ig","0hbad","0gbcb","0fb","0eb","0db","0cb"],
  "f":["1bpb","1cnc","0aclc","0bcjc","0cchc","0dcfc","0ecdc","0fcbc","0gf","0hd","0hd","0gf","0fcbc","0ecdc","0dcfc","0cchc","0bcjc","0aclca","1cnc","1bpb"],
  "t":["0jb","0jc","0kc","0lc","0mc","0nc","0oc","0pc","0qc","0qc","0od","0md","0kd","0id","0gd","0fc","0dd","0cc","0bc","0bb"],
}

def get_settings(default,pos=0):
  settings=default
  loop=True
  fill_rect(0,0,330,230,(255,255,255))
  draw_all_text()
  draw_settings(default,[0,1,2,3,4])
  draw_selector(pos)
  while loop:
    if k(KEY_UP):
      pos-=1
      if pos<0:pos+=6
      draw_selector(pos)
    if k(KEY_DOWN):
      pos+=1
      if pos>5:pos-=6
      draw_selector(pos)
    if k(KEY_OK) or k(KEY_RIGHT):
      if pos>4:
        return settings
      elif pos==0:
        typ="87654321"
      elif pos==2:
        typ="76543210"
      elif pos==1:
        typ="iba"
      elif pos==3 or pos==4:
        typ="tf"
      settings[pos]=get_right_set(typ,280,settings[pos])
      draw_settings(settings,[pos])

def draw_rect(x,y,typ,col=(220,220,220)):
  fill_rect(x,y,26,26,(255,255,255))
  fill_rect(x,y,2,26,col)
  fill_rect(x,y,26,2,col)
  fill_rect(x+24,y,2,26,col)
  fill_rect(x,y+24,26,2,col)
  if typ in [i for i in "0123456789"]:
    l=draw_letters(typ,1000,1000,4,(0,0,0),False)
    draw_letters(typ,x+(26-l)//2-1,y+3,4,(0,0,0),False)
  elif typ in [i for i in "ibatf"]:
    draw_logo(x+3,y+3,typ,colors[typ])

def draw_logo(x,y,logo,col=(0,0,0)):
  logo=logos[logo]
  yo=y
  for line in logo:
    y=yo
    withcol = int(line[0])
    for i in line[1:]:
      if withcol:
        fill_rect(x,y,1,characters.index(i)+1,col)
      withcol = not withcol
      y += characters.index(i)+1
    x+=1

def draw_right_rects(typ,x):
  offset=(221-len(typ)*26)//(len(typ)+1)+26
  y=(221-len(typ)*26-(len(typ)-1)*(offset-26))//2
  for i in range(len(typ)):
    draw_rect(x,y,typ[i])
    y+=offset

def draw_right_cursor(typ,x,last_pos,pos,col=(0,0,0)):
  offset=(221-len(typ)*26)//(len(typ)+1)+26
  y=(221-len(typ)*26-(len(typ)-1)*(offset-26))//2
  y+=offset*last_pos
  fill_rect(x,y,2,26,(220,)*3)
  fill_rect(x,y,26,2,(220,)*3)
  fill_rect(x+24,y,2,26,(220,)*3)
  fill_rect(x,y+24,26,2,(220,)*3)
  y=(221-len(typ)*26-(len(typ)-1)*(offset-26))//2
  y+=offset*pos
  fill_rect(x,y,2,26,col)
  fill_rect(x,y,26,2,col)
  fill_rect(x+24,y,2,26,col)
  fill_rect(x,y+24,26,2,col)

def get_right_set(typ,x,pos=0):
  pos=typ.index(pos)
  last_pos=pos
  draw_right_rects(typ,x)
  draw_right_cursor(typ,x,last_pos,pos)
  last_pos=pos
  while not (k(KEY_OK) or k(KEY_LEFT)):
    if k(KEY_DOWN):
      pos+=1
      if pos>len(typ)-1:pos-=len(typ)
      draw_right_rects(typ,x)
      draw_right_cursor(typ,x,last_pos,pos)
      last_pos=pos
    if k(KEY_UP):
      pos-=1
      if pos<0:pos+=len(typ)
      draw_right_rects(typ,x)
      draw_right_cursor(typ,x,last_pos,pos)
      last_pos=pos
  fill_rect(x,0,50,230,(255,255,255))
  return typ[pos]

def draw_all_text():
  draw_letters("number of dices",20,20,3,sep=3)
  draw_letters("unit type",20,53,3,sep=3)
  draw_letters("number of enemies",20,86,3,sep=3)
  draw_letters("flag",20,119,3,sep=3)
  draw_letters("star",20,152,3,sep=3)
  draw_letters("simulate",100,190,3,sep=3)

def draw_settings(settings,poss):
  for pos in poss:
    y=15+pos*(18+15)
    draw_rect(240,y,settings[pos])

def draw_selector(pos):
  if pos>4:
    x=90
    y=190
  else:
    x=10
    y=20+pos*(15+18)
  y+=1
  fill_rect(0,0,19,220,(255,255,255))
  fill_rect(90,190,9,16,(255,255,255))
  for i in range(7):
    fill_rect(x,y+i,i+1,1,(0,0,0))
  for i in reversed(range(7)):
    fill_rect(x,y+13-i,i+1,1,(0,0,0))


##############
# results.py #
##############

def draw(on1):
  fill_rect(0,0,330,230,(255,255,255))
  LENGHT=250
  HIGHT=20
  fill_rect((319-LENGHT-4)//2,(221-HIGHT-4)//2,LENGHT+4,HIGHT+4,(0,0,0))
  for i in range(LENGHT):
    fill_rect((319-LENGHT)//2+i,(221-HIGHT)//2,1,HIGHT,(255-(i/LENGHT)*255,(i/LENGHT)*255,0))
  fill_rect(int((319-LENGHT)//2+on1*LENGHT-1),(221-HIGHT)//2-7,2,14+HIGHT,(0,0,0))
  l=draw_letters(str(on1*100)[:5],1000,221//2+HIGHT//2+12,3,(0,0,0),True,2,5)
  draw_letters(str(on1*100)[:5],int((319-LENGHT)//2+on1*LENGHT-1-l/2),221//2+HIGHT//2+12,3,(0,0,0),True,2,5)


###############
# __main.py__ #
###############

def proba(numberOfDice,unitType,numberOfUnit,flag=False,star=False):
  if flag=="t":flag=True
  if flag=="f":flag=False
  if star=="t":star=True
  if star=="f":star=False
  numberOfUnit=int(numberOfUnit)
  numberOfDice=int(numberOfDice)
  cor = {"i":1/2,"b":1/3,"a":1/6}
  res = 0
  p = cor[unitType]+1/6*(flag+star)
  for k in range(numberOfUnit,numberOfDice+1):
    coef = factorial(numberOfDice)/(factorial(k)*factorial(numberOfDice-k))
    proba = coef*p**(k)*(1-p)**(numberOfDice-k)
    res += proba
  return res

default=["4","i","4","f","f"]
settings=default

while True:
  settings=get_settings(settings,5)
  fill_rect(0,0,330,230,(255,)*3)
  p=proba(*settings)
  draw(p)
  print(str(p*100)[:5],"%")
  while not k(4):
    pass

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.