Initial commit.

This commit is contained in:
overtired 2023-09-29 15:39:10 +03:00
commit 0125f5ea86
4 changed files with 315 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__

157
dicelib.py Normal file
View File

@ -0,0 +1,157 @@
from random import randint, choice, seed
from input_assist import ichoiced_input, iyes_or_no
class Die:
def __init__(self, ai):
self.ai = ai
self.die_id = "Die"
self.spec = False
def roll(self):
return (self.die_id, choice(self.possible_values))
@classmethod
def multiple(cls, count):
return [cls() for _ in range(count)]
class Deck:
def __init__(self, *dice, **kwargs):
try:
self.dice = [d for d in dice[0]]
except TypeError:
self.dice = dice
if "ai" in kwargs:
for die in self.dice:
die.ai = kwargs["ai"]
def roll(self, print_func=print, ai=False):
dice_list = []
for die in self.dice:
r = die.roll()
if die.spec and (r[1] in die.spec_results):
if ai:
r = (die.die_id, die.handle_ai(r, dice_list))
else:
print_func(dice_list)
r = (die.die_id, die.handle_input(r[1]))
dice_list.append(r)
return dice_list
@staticmethod
def sum(roll_result):
return sum([x[1] for x in roll_result])
@staticmethod
def as_str(roll_result):
paren_result = ', '.join([str(x[1]) for x in roll_result])
return f"{Deck.sum(roll_result)} ({paren_result})"
class QueueDeck(Deck):
def __init__(self, *dice, **kwargs):
super().__init__(*dice, **kwargs)
def roll(self, prompt, print_func=print, exit_check=None):
q = self.dice.copy()
dice_list = []
while die := q.pop():
r = die.roll()
if die.spec and (r[1] in die.spec_results):
r = (die.die_id, die.handle_input(r[1]))
dice_list.append(r)
if len(q) < 1:
break
# else:
# print_func(dice_list)
if exit_check is not None:
if exit_check(dice_list):
break
print_func(dice_list)
c = iyes_or_no(prompt, default_pos=True)
if c is None:
return None
if not c:
break
return dice_list
class AceDie(Die):
def __init__(self, ai=None):
if ai:
super().__init__(ai)
self.die_id = "AceDie"
self.possible_values = [1]
self.spec = True
self.spec_results = [1]
def handle_input(self, r):
r = int(ichoiced_input(
"Ace!",
("1", "6"))
)
if r is None:
exit()
return r
class AdvancedDie(Die):
def __init__(self, ai=None):
if ai:
super().__init__(ai)
self.die_id = "AdvancedDie"
self.possible_values = [1, 2, 3, 4, 5, 6]
self.spec = True
self.spec_results = [6]
def roll(self):
return (self.die_id, choice(self.possible_values))
def handle_input(self, r):
if r == 6:
r = int(ichoiced_input(
"Advanced die just rolled a 6! What would you like?",
("1", "6"))
)
if r is None:
exit()
return r
def handle_ai(self, r, dice_list):
print(f"REACHED AI: {r}, {dice_list}")
return self.ai(r, dice_list)
class BasicDie(Die):
def __init__(self, ai=None):
if ai:
super().__init__(ai)
self.die_id = "BasicDie"
self.possible_values = [1, 2, 3, 4, 5, 6]
self.spec = False
self.spec_results = []
class BlankDie(Die):
def __init__(self, ai=None):
if ai:
super().__init__(ai)
self.die_id = "BlankDie"
self.possible_values = [1, 2, 3, 4, 0, 0]
self.spec = True
self.spec_results = [0]
def handle_input(self, r):
if r in self.spec_results:
r = ichoiced_input(
"Blank die rolled a blank side! What would you like?",
("5", "6"))
if r is not None:
r = int(r)
else:
exit()
return r

71
input_assist.py Normal file
View File

@ -0,0 +1,71 @@
def err(i):
print(f"Not a choice: {i}")
def choiced_input(prompt, choices):
if len(choices) < 2:
exit("Achievement unlocked: How did we get here?")
prompt_add = f"{', '.join(choices[:-1])} or {choices[-1]}"
while (i := input(prompt + f" ({prompt_add}) ")) not in choices:
err(i)
return i
def choiced_input_ci(prompt, choices):
if len(choices) < 2:
exit("Achievement unlocked: How did we get here?")
prompt_add = f"{', '.join(choices[:-1])} or {choices[-1]}"
while (i := input(prompt + f" ({prompt_add}) ")).casefold() not in choices:
err(i)
return i
def yes_or_no(prompt, default_pos=False):
positive = list("+y") + ["yes"]
negative = list("-n") + ["no"]
choices = positive + negative + [""]
while (i := input(prompt)).strip().casefold() not in choices:
err(i)
if i == "":
return default_pos
return i in positive
def ranged_input_int(prompt, _range):
try:
while int((i := input(prompt)).strip().casefold()) not in _range:
err(i)
except ValueError:
return ranged_input_int(prompt, _range)
return i
def iwrapper(func, *args):
try:
return func(*args)
except (EOFError, KeyboardInterrupt):
return None
def ichoiced_input(prompt, choices):
return iwrapper(choiced_input, prompt, choices)
def ichoiced_input_ci(prompt, choices):
return iwrapper(choiced_input_ci, prompt, choices)
def iyes_or_no(prompt, default_pos=False):
return iwrapper(yes_or_no, prompt, default_pos)
def iranged_input_int(prompt, _ranged):
return iwrapper(ranged_input_int, prompt, _ranged)
if __name__ == "__main__":
print("TESTS AHEAD!!! :3")
print(iranged_input_int("HIIII (-10-10) ", range(-10, 11)))
exit()
print(ichoiced_input("x or y (no z)?", ["x", "y"]))
print(ichoiced_input_ci("X or Y or other case?", ["x", "y"]))

86
main.py Normal file
View File

@ -0,0 +1,86 @@
from dicelib import AceDie, AdvancedDie, BasicDie, BlankDie, Deck, QueueDeck
from input_assist import iyes_or_no, iranged_input_int
from random import choice, shuffle
# seed(42069) # for testing
def rai(r, dice_list):
if r[0] == "AdvancedDie":
return choice([1, 6])
exit("Achievement unlocked: How did we get here?")
def smolthink_ai(r, dice_list):
if r[0] == "AdvancedDie":
if Deck.sum(dice_list) > 7:
return 1
else:
return 6
def pfunc(dice_list):
dice = [f"{DICE_NAMES[x[0]]}: {x[1]}" for x in dice_list]
print("\nDice so far:\n " + ("\n ".join(dice) or "None"))
def efunc(dice_list):
return Deck.sum(dice_list) >= 13
def shuffled(_list):
l1 = _list.copy()
shuffle(l1)
return l1
if __name__ == "__main__":
DICE_NAMES = {
"AdvancedDie": "Advanced",
"BasicDie": "Basic",
"BlankDie": "Blank",
"AceDie": "Ace",
}
deck = QueueDeck(shuffled(BasicDie.multiple(11)
+ AdvancedDie.multiple(6)
+ BlankDie.multiple(3)
+ AceDie.multiple(1)))
balance = 500
while balance > 0:
bet = iranged_input_int(f"Your bet? [1-{balance}] ",
range(1, balance+1))
if bet is None:
exit("\nBye!~")
else:
bet = int(bet)
roll = deck.roll("Roll more? [Y/n] ",
print_func=pfunc, exit_check=efunc)
if roll is None:
exit()
print("\nDice:")
for res in roll:
print(f"> {DICE_NAMES[res[0]]}: {res[1]}")
print("Total:", Deck.sum(roll))
if Deck.sum(roll) > 13:
print("You've busted out!")
balance -= bet
if Deck.sum(roll) == 13:
print("You've won!")
balance += bet
if Deck.sum(roll) < 13:
print("You've backed out.")
balance -= bet // 2
print("-"*24)
if balance <= 0:
print("No money left :(")
print("Goodbye!")
exit()
print(f"Your beans: {balance}")
c = iyes_or_no("Continue playing? [Y/n] ", default_pos=True)
if c is None:
exit()
if not c:
break