python-dice-top-k-game-prob.../pydiceprob.py

89 lines
2.8 KiB
Python
Raw Permalink Normal View History

2024-04-19 12:57:47 +02:00
import sys
import json
import pprint
2024-04-20 09:21:06 +02:00
from fastapi import FastAPI, Header
2024-04-19 12:57:47 +02:00
pp = pp.Printer = pprint.PrettyPrinter(indent=2, compact=True)
2024-04-20 09:28:03 +02:00
def print(stuff):
pp.pprint(stuff)
2024-04-19 12:57:47 +02:00
def usagequit():
print("""Usage: python pydiceprob.py [k] [mode]
2024-04-20 09:21:06 +02:00
k between 6 and 99 (higher numbers are supported, up to however much your memory can handle; given that win probabilities approach 50%, this isn't very useful past about 100.)
2024-04-19 12:57:47 +02:00
modes: single, single-table, multi, multi-table
single prints out the probability of a single throw with a k-sided dice yielding k.
single-table prints out a table between 6 and k with the probabilities of a single throw yielding k.
multi prints out the probability of winning (assuming we're going first) in a game where two players take turns and the person who throws k first wins.
multi-table prints out the probability of winning for a range between 6 and k if you have the first throw.""")
quit()
2024-04-20 09:21:06 +02:00
app = FastAPI()
@app.get("/")
async def api_get(k: int = Header(default=None)):
if not isinstance(k, int) and k is not None:
return {"message": "Header k must be an integer between 6 and 100 inclusive or not present."}
if k is None:
result = one_turn_table(100)
2024-04-20 13:48:53 +02:00
return {"Probabilities-dice": result}
2024-04-20 09:21:06 +02:00
elif k >= 6 and k <= 100:
result = one_turn_single(k)
2024-04-20 13:48:53 +02:00
return {f"Probability-dice-size-{k}": result}
2024-04-20 09:21:06 +02:00
else:
return {"message": "Usage: no request body, use header k to specify what probability you want, if no k, then a table is given between dice sizes 6 and 100 inclusive."}
2024-04-19 12:57:47 +02:00
def main():
global k
try:
if int(sys.argv[1]) >= 6:
k = int(sys.argv[1])
else:
usagequit()
except IndexError:
usagequit()
global mode
try:
mode = sys.argv[2]
except IndexError:
usagequit()
dispatch(mode, k)
def dispatch(mode, k):
modes = ["single", "multi", "single-table", "multi-table"]
if mode not in modes:
usagequit()
if mode == "single":
2024-04-20 09:21:06 +02:00
print(one_turn_single(k))
2024-04-19 12:57:47 +02:00
elif mode == "multi" :
print(multi_turn_single(k))
elif mode == "single-table":
2024-04-20 09:21:06 +02:00
print(one_turn_table(k))
2024-04-19 12:57:47 +02:00
elif mode == "multi-table":
print(multi_turn_table(k))
2024-04-20 09:21:06 +02:00
def one_turn_table(k):
2024-04-19 12:57:47 +02:00
result = {}
for k in range(6, int(k)+1):
result[k] = 1/k
return result
2024-04-20 09:21:06 +02:00
def one_turn_single(k):
return one_turn_table(k)[k]
2024-04-19 12:57:47 +02:00
def multi_turn_single(k):
p_win = 1 / k # Winning probability on any given throw
p_lose = (k-1) / k # Losing probability on any given throw
r = p_lose**2
probability_win = p_win / (1 - r)
return probability_win
def multi_turn_table(k):
result = {}
for i in range(6, int(k+1)):
result[i] = multi_turn_single(i)
return result
if __name__ == "__main__":
main()