# polymorphism in action
import random
from typing import Callable, Literal

type RollDieFn = Callable[[], int]
type RollCheck = Literal["success", "failure"]
success, failure = "success", "failure"

def roll_and_check(
        roll_die: RollDieFn,
        *modifiers: RollDieFn,
        difficulty: int
    ) -> RollCheck:
    roll = roll_die()
    print(f"main roll: {roll}")
    
    for roll_modifier_die in modifiers:
        roll_ = roll_modifier_die()
        roll += roll_
        print(f"modifier roll: {roll_}, total: {roll}")
    
    if roll >= difficulty:
    	return success
    
    return failure


def create_die(sides: int) -> RollDieFn:
    def roll() -> int:
        return random.randint(1, sides)
    return roll

roll_d20 = create_die(sides=20)
roll_d4 = create_die(sides=4)


for dif in range(5, 21, 4):
    print(f"difficulty: {dif}")
    print(roll_and_check(
        roll_d20,
        roll_d4,
        lambda: 6,  # flat modifier
        difficulty=dif
    ))
    print()