370 lines
11 KiB
Python
370 lines
11 KiB
Python
import json
|
|
import os
|
|
import random
|
|
from os.path import exists
|
|
|
|
|
|
class CeaserChiffre:
|
|
chiffre = {}
|
|
|
|
def __init__(self, chiffre=None):
|
|
if chiffre is not None:
|
|
self.chiffre = chiffre
|
|
else:
|
|
self.renew_chiffre()
|
|
|
|
def __str__(self):
|
|
return str(self.chiffre)
|
|
|
|
def renew_chiffre(self):
|
|
codes = {}
|
|
chars = list(range(0, 255))
|
|
for char in range(0, 255):
|
|
rand = random.choice(chars)
|
|
chars.remove(rand)
|
|
codes[chr(char)] = chr(rand)
|
|
self.chiffre = codes
|
|
|
|
def encode(self, text):
|
|
return self._work(text, self.chiffre)
|
|
|
|
def decode(self, text):
|
|
chiffre = {value: key for key, value in self.chiffre.items()}
|
|
return self._work(text, chiffre)
|
|
|
|
def _work(self, text, chiffre):
|
|
result = []
|
|
for i in range(len(text)):
|
|
if text[i] in chiffre:
|
|
result.append(chiffre[text[i]])
|
|
else:
|
|
result.append(text[i])
|
|
return ''.join(result)
|
|
|
|
|
|
class Rational:
|
|
numerator = 0
|
|
divisor = 1
|
|
|
|
def __str__(self):
|
|
return "%d/%d" % (self.numerator, self.divisor)
|
|
|
|
def __init__(self, a=0, b=1):
|
|
if isinstance(a, Rational):
|
|
self.numerator = a.numerator
|
|
self.divisor = a.divisor
|
|
self.shorten()
|
|
elif isinstance(a, int) and isinstance(b, int):
|
|
if b == 0:
|
|
print("Divisor cannot be zero!")
|
|
exit(1)
|
|
if b < 0:
|
|
b = -b
|
|
a = -a
|
|
self.numerator = a
|
|
self.divisor = b
|
|
self.shorten()
|
|
else:
|
|
print("Numerator and divisor must be integer.")
|
|
exit(1)
|
|
|
|
def gcd(self, a, b):
|
|
while b != 0:
|
|
(a, b) = (b, a % b)
|
|
return a
|
|
|
|
def lcm(self, a, b):
|
|
return abs(a * b) // self.gcd(a, b)
|
|
|
|
def lcd(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
return self.lcm(self.divisor, other.divisor)
|
|
|
|
def shorten(self):
|
|
d = self.gcd(self.numerator, self.divisor)
|
|
self.numerator = self.numerator // d
|
|
self.divisor = self.divisor // d
|
|
|
|
# addition
|
|
def __add__(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
|
|
lcm = self.lcm(self.divisor, other.divisor)
|
|
|
|
fac1 = lcm // self.divisor
|
|
fac2 = lcm // other.divisor
|
|
|
|
new_divisor = lcm
|
|
new_nominator = self.numerator * fac1 + other.numerator * fac2
|
|
return Rational(new_nominator, new_divisor)
|
|
|
|
def __radd__(self, other):
|
|
return self.__add__(other)
|
|
|
|
# subtraction
|
|
def __sub__(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
divisor_lcm = self.lcm(self.divisor, other.divisor)
|
|
new_nominator = (self.numerator * divisor_lcm / self.divisor) - (other.numerator * divisor_lcm / other.divisor)
|
|
return Rational(int(new_nominator), int(divisor_lcm))
|
|
|
|
def __rsub__(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
divisor_lcm = self.lcm(self.divisor, other.divisor)
|
|
new_nominator = (other.numerator * divisor_lcm / other.divisor) - (self.numerator * divisor_lcm / self.divisor)
|
|
return Rational(int(new_nominator), int(divisor_lcm))
|
|
|
|
# multiplication
|
|
def __mul__(self, other):
|
|
if isinstance(other, Rational):
|
|
return Rational(self.numerator * other.numerator, self.divisor * other.divisor)
|
|
else:
|
|
return Rational(self.numerator * other, self.divisor)
|
|
|
|
def __rmul__(self, other):
|
|
return self.__mul__(other)
|
|
|
|
# division
|
|
def __truediv__(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
new_numerator = self.numerator * other.divisor
|
|
new_divisor = self.divisor * other.numerator
|
|
return Rational(new_numerator, new_divisor)
|
|
|
|
def __rtruediv__(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
new_numerator = self.divisor * other.numerator
|
|
new_divisor = self.numerator * other.divisor
|
|
return Rational(new_numerator, new_divisor)
|
|
|
|
def __lt__(self, other):
|
|
divisor_lcm = self.lcd(other)
|
|
return (self.numerator * divisor_lcm / self.divisor) < (other.numerator * divisor_lcm / other.divisor)
|
|
|
|
def __gt__(self, other):
|
|
divisor_lcm = self.lcd(other)
|
|
return (self.numerator * divisor_lcm / self.divisor) > (other.numerator * divisor_lcm / other.divisor)
|
|
|
|
def __le__(self, other):
|
|
divisor_lcm = self.lcd(other)
|
|
return (self.numerator * divisor_lcm / self.divisor) <= (other.numerator * divisor_lcm / other.divisor)
|
|
|
|
def __ge__(self, other):
|
|
divisor_lcm = self.lcd(other)
|
|
return (self.numerator * divisor_lcm / self.divisor) >= (other.numerator * divisor_lcm / other.divisor)
|
|
|
|
def __eq__(self, other):
|
|
if not isinstance(other, Rational):
|
|
other = Rational(other)
|
|
# all constructed Rationals are already shortened
|
|
return self.divisor == other.divisor and self.numerator == other.numerator
|
|
|
|
def __ne__(self, other):
|
|
return not self.__eq__(other)
|
|
|
|
|
|
class Game:
|
|
scores = {"player": 0, "bot": 0}
|
|
mode = "easy"
|
|
player = None
|
|
stop = False
|
|
|
|
def __init__(self, rules, mode="easy"):
|
|
self.mode = mode.lower()
|
|
self.rules = rules
|
|
self.player = None
|
|
self.scores = {"player": 0, "bot": 0}
|
|
self.stop = False
|
|
|
|
if os.path.exists("storage.json"):
|
|
load = input("Do you want to load the save game? (yes or no) ")
|
|
if str.lower(load) == "yes":
|
|
with open('storage.json', 'r') as file:
|
|
self.player = Player("player", {key: 0 for key in self.rules})
|
|
self._load_dump(json.load(file))
|
|
print("\n")
|
|
return
|
|
|
|
modes = ["easy", "hard", "god"]
|
|
if self.mode not in modes:
|
|
raise ValueError("Invalid mode. Please choose from: " + ', '.join(modes))
|
|
|
|
name = input("Enter your name: ")
|
|
self.player = Player(str.lower(name), {key: 0 for key in self.rules})
|
|
print("\n")
|
|
|
|
def __str__(self):
|
|
return "bot: " + str(self.scores["bot"]) + " - " + self.player.name + ": " + str(self.scores["player"])
|
|
|
|
def reset(self):
|
|
self.scores["player"] = 0
|
|
self.scores["bot"] = 0
|
|
self.player.choices = {key: 0 for key in self.rules}
|
|
if os.path.exists('storage.json'):
|
|
os.remove('storage.json')
|
|
|
|
def match(self, games=10):
|
|
while sum(self.scores.values()) < games and not self.stop:
|
|
self._play()
|
|
print("\n")
|
|
if self.scores["player"] > self.scores["bot"] and not self.stop:
|
|
print(self.player.name + " wins.")
|
|
self.reset()
|
|
elif not self.stop:
|
|
print("The bot wins.")
|
|
self.reset()
|
|
else:
|
|
print("The match is interrupted.")
|
|
|
|
def _play(self):
|
|
players_choice = self._get_players_choice()
|
|
if players_choice == "exit":
|
|
return self.exit()
|
|
bots_choice = self._get_bots_choice(players_choice)
|
|
self.player.choices[players_choice] += 1
|
|
result = self.rules[players_choice][bots_choice]
|
|
if result > 0:
|
|
self.scores["player"] += 1
|
|
elif result < 0:
|
|
self.scores["bot"] += 1
|
|
print(self)
|
|
|
|
def exit(self):
|
|
backup = self._create_dump()
|
|
with open('storage.json', 'w') as file:
|
|
json.dump(backup, file)
|
|
self.stop = True
|
|
|
|
def _get_players_choice(self):
|
|
players_choice = input("Enter your move (" + ', '.join(self.rules.keys()) + " or exit): ").lower()
|
|
if players_choice not in self.rules and players_choice != "exit":
|
|
raise ValueError("Invalid choice. Please choose from: " + ', '.join(self.rules.keys()) + ", exit")
|
|
return players_choice
|
|
|
|
def _get_bots_choice(self, players_choice):
|
|
bots_choice = ""
|
|
if self.mode == "easy":
|
|
bots_choice = self._easy()
|
|
elif self.mode == "hard":
|
|
bots_choice = self._hard()
|
|
elif self.mode == "god":
|
|
bots_choice = self._god(players_choice)
|
|
print("The bot chooses " + bots_choice)
|
|
return bots_choice
|
|
|
|
def _god(self, players_choice):
|
|
for bots_choice in self.rules:
|
|
if self.rules[bots_choice][players_choice] == 1:
|
|
return bots_choice
|
|
|
|
def _easy(self):
|
|
bots_choice = random.choice(list(self.rules.keys()))
|
|
return bots_choice
|
|
|
|
def _hard(self):
|
|
total = sum(self.player.choices.values())
|
|
if total == 0:
|
|
return self._easy()
|
|
probabilities = {choice: self.player.choices[choice] / total for choice in self.player.choices}
|
|
likely = random.choices(list(probabilities.keys()), weights=list(probabilities.values()))[0]
|
|
for choice in self.rules[likely].keys():
|
|
if self.rules[likely][choice] < 0:
|
|
return choice
|
|
|
|
def _create_dump(self):
|
|
player = self.player.create_dump()
|
|
dump = {
|
|
"player": player,
|
|
"mode": self.mode,
|
|
"rules": self.rules,
|
|
"scores": {
|
|
"player": self.scores["player"],
|
|
"bot": self.scores["bot"]
|
|
}
|
|
}
|
|
return json.dumps(dump)
|
|
|
|
def _load_dump(self, dump):
|
|
dump = json.loads(dump)
|
|
self.player.load_dump(dump["player"])
|
|
self.scores = dump["scores"]
|
|
self.mode = dump["mode"]
|
|
self.rules = dump["rules"]
|
|
|
|
|
|
class Player:
|
|
name = "player"
|
|
choices = {}
|
|
|
|
def __init__(self, name, choices):
|
|
self.choices = choices
|
|
self.name = name
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
def create_dump(self):
|
|
dump = {
|
|
"name": self.name,
|
|
"choices": self.choices
|
|
}
|
|
return json.dumps(dump)
|
|
|
|
def load_dump(self, dump):
|
|
dump = json.loads(dump)
|
|
self.name = dump["name"]
|
|
self.choices = dump["choices"]
|
|
|
|
|
|
def heron(a, x, run):
|
|
a = Rational(a)
|
|
x = Rational(x)
|
|
|
|
for i in range(run):
|
|
x = x - (x * x - a) / (2 * x)
|
|
return x
|
|
|
|
|
|
# start = Rational(3, 2)
|
|
# sol = heron(2, start, 10000)
|
|
# print(sol)
|
|
|
|
text = '''
|
|
Liebe/r Empfänger,
|
|
|
|
Herzliche Grüße aus dem hohen Norden! Ich hoffe, diese Nachricht erreicht dich in guter Verfassung und fügt einen Hauch
|
|
von festlicher Stimmung zu deinem Tag hinzu.
|
|
|
|
Ich wünsche dir Freude, Gelächter und einen festlichen Geist, der dein Herz erwärmt. Genieße die Magie der Feiertage!
|
|
|
|
Herzliche Grüße,
|
|
Rudolph
|
|
'''
|
|
|
|
# ceaser = CeaserChiffre()
|
|
# print(ceaser.decode(ceaser.encode(text)))
|
|
|
|
rock_paper_scissor = {
|
|
"rock": {"rock": 0, "paper": -1, "scissor": 1},
|
|
"paper": {"rock": 1, "paper": 0, "scissor": -1},
|
|
"scissor": {"rock": -1, "paper": 1, "scissor": 0}
|
|
|
|
}
|
|
|
|
rock_paper_scissor_lizard_spock = {
|
|
"rock": {"rock": 0, "paper": -1, "scissor": 1, "lizard": 1, "spock": -1},
|
|
"paper": {"rock": 1, "paper": 0, "scissor": -1, "lizard": -1, "spock": 1},
|
|
"scissor": {"rock": -1, "paper": 1, "scissor": 0, "lizard": 1, "spock": -1},
|
|
"lizard": {"rock": -1, "paper": 1, "scissor": -1, "lizard": 0, "spock": 1},
|
|
"spock": {"rock": 1, "paper": -1, "scissor": 1, "lizard": -1, "spock": 0}
|
|
}
|
|
|
|
# game = Game(rock_paper_scissor_lizard_spock, "hard")
|
|
# game.match(10)
|