Last active
May 17, 2020 16:25
-
-
Save ijp/ef0bada930217416f5ff715007e0444e to your computer and use it in GitHub Desktop.
Road to Yokozuna - Slohyo prototype
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class StdioLogger(object): | |
def log(self, msg): | |
print(msg) | |
class NullLogger(object): | |
def log(self, msg): | |
pass | |
# Discord logger, Coloured logger, etc. | |
class Commentator(object): | |
def __init__(self, logger=StdioLogger): | |
self.logger = logger() | |
def log(self, msg): | |
self.logger.log(msg) | |
def announce_wrestlers(self, east, west): | |
# FIXME: probably unnecessary | |
self.announce_wrestler("east", east) | |
self.announce_wrestler("west", west) | |
def announce_wrestler(self, side, wrestler): | |
self.log(f"On the {side}~~~ {wrestler.shikona}") | |
def new_round(self): | |
self.log("---") | |
def attempt_move(self, rikishi, move, roll): | |
self.log(f"{rikishi.shikona} attempting {move.name} rolls {roll}") | |
def matta(self): | |
self.log("Matta!") | |
def mono_ii(self): | |
self.log("The judges have called for a mono-ii") | |
def gunbai_dori(self, attacker, defender): | |
self.log(f"Gyoji gunbai dori. The victory goes to {attacker.shikona}") | |
def gunbai_sashichigae(self, attacker, defender): | |
# FIXME: better name | |
self.log(f"Gyoji gunbai sashichigae. The decision is reversed, and {defender.shikona} is awarded the victory") | |
def torinaoshi(self, attacker, defender): | |
self.log("Torinaoshi. We're going to have a playoff") | |
def successful_tachiai(self, attacker, move): | |
self.log(f"{attacker.shikona} has the advantage...transitioning to {move.transition}") | |
def successful_defense(self, defender, defense): | |
self.log(f"A great defense by {defender.shikona} and the momentum is now in their favour") | |
self.log(f"They transition to {defense.transition}") | |
def announce_victor(self, attacker): | |
self.log(f"Yes, a great victory for {attacker.shikona}") | |
def match_over(self, attacker): | |
self.log(f"It looks like {attacker.shikona} has succeeded") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rikishi import Rikishi | |
from slohyo import Game | |
import argparse | |
import json | |
parser = argparse.ArgumentParser(description="Run a slohyo") | |
parser.add_argument('east_file', help="JSON file for east wrestler") | |
parser.add_argument('west_file', help="JSON file for west wrestler") | |
args = parser.parse_args() | |
def wrestler_from_file(filename): | |
with open(filename) as fp: | |
j = json.load(fp) | |
return Rikishi.from_slohyo_form(j) | |
east = wrestler_from_file(args.east_file) | |
west = wrestler_from_file(args.west_file) | |
g = Game(east, west) | |
g.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from techniques import tachiai, kimarite, defense | |
class Rikishi(object): | |
def __init__(self, shikona, base_die, power, balance, footwork, skill, spirit, strategy): | |
self.shikona = shikona | |
self.base_die = base_die | |
self.power = power | |
self.balance = balance | |
self.footwork = footwork | |
self.skill = skill | |
self.spirit = spirit | |
self.strategy = strategy | |
def tachiai(self): | |
name, transition = self.strategy["tachiai"] | |
return tachiai(self, name, transition) | |
def offensive_technique(self, state): | |
return kimarite(self, self.strategy[state]["offense"]) | |
def defensive_technique(self, state): | |
name, transition = self.strategy[state]["defense"] | |
return defense(self, name, transition) | |
@staticmethod | |
def from_slohyo_form(slohyo_form): | |
shikona = slohyo_form["shikona"] | |
base_die = slohyo_form["base_die"] | |
power = slohyo_form["power"] | |
balance = slohyo_form["balance"] | |
footwork = slohyo_form["footwork"] | |
skill = slohyo_form["skill"] | |
spirit = slohyo_form["spirit"] | |
states = ['tachiai', 'grip', 'push', 'pull', 'rear', 'throw'] | |
strategy = {k: slohyo_form[k] for k in states} | |
return Rikishi(shikona, base_die, power, balance, footwork, skill, spirit, strategy) | |
def validate_strategy(self): | |
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"shikona": "chiyochiyochiyo", | |
"base_die": 20, | |
"power": 3, | |
"balance": 4, | |
"footwork": 3, | |
"skill": 4, | |
"spirit": 5, | |
"tachiai": ["powerful charge", "grip"], | |
"grip": { | |
"offense": "yorikiri", | |
"defense": ["makekai", "grip"] | |
}, | |
"push": { | |
"offense": null, | |
"defense": ["makekai", "grip"] | |
}, | |
"pull": { | |
"offense": "hikiotoshi", | |
"defense": ["sidestep", "pull"] | |
}, | |
"rear": { | |
"offense": null, | |
"defense": ["makekai", "grip"] | |
}, | |
"throw": { | |
"offense": null, | |
"defense": ["sidestep", "pull"] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"shikona": "wakawakawaka", | |
"base_die": 20, | |
"power": 4, | |
"balance": 3, | |
"footwork": 3, | |
"skill": 5, | |
"spirit": 4, | |
"tachiai": ["low", "pull"], | |
"grip" : { | |
"offense": null, | |
"defense": ["tawara ballet", "throw"] | |
}, | |
"push" : { | |
"offense": null, | |
"defense": ["sidestep", "pull"] | |
}, | |
"pull" : { | |
"offense": "hatakikomi", | |
"defense": ["tawara ballet", "throw"] | |
}, | |
"rear" : { | |
"offense": null, | |
"defense": ["sidestep", "pull"] | |
}, | |
"throw" : { | |
"offense": "kotenage", | |
"defense": ["sidestep", "pull"] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from commentator import Commentator | |
import random | |
MATTA_THRESHOLD = 2 | |
MONO_II_THRESHOLD = 2 | |
# game_states = ["tachiai", "grip", "pull", "throw", "lock", "push", "defense", "DONE"] | |
# Possible states: make sure they match slohyo terms, maybe use: yotsu, pull, nagete, limblock, oshi | |
class Game(object): | |
def __init__(self, east, west, commentator=Commentator): | |
self.east = east | |
self.west = west | |
self.attacker = self.defender = None | |
self.c = commentator() | |
def run(self): | |
self.state = "tachiai" | |
self.pre_bout() | |
self.tachiai() | |
while self.state != "DONE": | |
self.do_round() | |
def pre_bout(self): | |
self.c.announce_wrestlers(self.east, self.west) | |
self.c.new_round() | |
def tachiai(self): | |
east_move = self.east.tachiai() | |
west_move = self.west.tachiai() | |
east_roll = east_move.roll(west_move) | |
west_roll = west_move.roll(east_move) | |
self.c.attempt_move(self.east, east_move, east_roll) | |
self.c.attempt_move(self.west, west_move, west_roll) | |
if abs(east_roll - west_roll) <= MATTA_THRESHOLD: | |
self.c.matta() | |
self.state = "DONE" | |
elif east_roll > west_roll: | |
self.c.successful_tachiai(self.east, east_move) | |
self.state = east_move.transition | |
self.attacker = self.east | |
self.defender = self.west | |
else: | |
self.c.successful_tachiai(self.west, west_move) | |
self.state = west_move.transition | |
self.attacker = self.west | |
self.defender = self.east | |
def do_round(self): | |
self.c.new_round() | |
attack = self.attacker.offensive_technique(self.state) | |
defense = self.defender.defensive_technique(self.state) | |
atk_roll = attack.roll(defense) | |
def_roll = defense.roll(attack) | |
self.c.attempt_move(self.attacker, attack, atk_roll) | |
self.c.attempt_move(self.defender, defense, def_roll) | |
if atk_roll >= def_roll: | |
self.c.match_over(self.attacker) | |
if atk_roll <= def_roll + MONO_II_THRESHOLD: | |
self.c.mono_ii() | |
roll = random.randint(1, 10) | |
if roll <= 7: | |
self.c.gunbai_dori(self.attacker, self.defender) | |
elif roll >= 9: | |
self.c.gunbai_sashichigae(self.attacker, self.defender) | |
else: | |
self.c.torinaoshi(self.attacker, self.defender) | |
else: | |
self.c.announce_victor(self.attacker) | |
self.state = "DONE" | |
else: | |
self.c.successful_defense(self.defender, defense) | |
self.state = defense.transition | |
self.attacker, self.defender = self.defender, self.attacker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
class Technique(object): | |
def __init__(self, name, state, stats, counters): | |
self.name = name | |
self.state = state | |
self.stats = stats | |
self.counter_list = counters | |
def counters(self, other): | |
return other.name in self.counter_list | |
techniques = {} | |
def add_technique(name, state, stats, counters): | |
techniques[name] = Technique(name, state, stats, counters) | |
add_technique("powerful charge", "tachiai", ["power", "balance"], ["reserved"]) | |
# FIXME: transition to grip, throw | |
add_technique("reserved", "tachiai", ["footwork", "spirit"], ["low"]) | |
# FIXME: transition to lock, push | |
add_technique("low", "tachiai", ["power", "skill"], ["surprise"]) | |
# FIXME: transition to grip, pull | |
add_technique("surprise", "tachiai", ["balance", "spirit"], ["lateral"]) | |
# FIXME: transition to throw, push | |
add_technique("lateral", "tachiai", ["footwork", "skill"], ["powerful charge"]) | |
# FIXME: transition to lock, pull | |
add_technique("yorikiri", "grip", ["power", "balance"], ["sidestep"]) # Y1 | |
add_technique("shitatenage", "grip", ["footwork", "balance"], ["makekai"]) # Y2 | |
add_technique("harimanage", "grip", ["power", "spirit"], ["tawara ballet"]) # Y3 | |
add_technique("uwatenage", "grip", ["power", "skill"], ["momentum stop"]) # Y4 | |
add_technique("hatakikomi", "pull", ["skill", "spirit"], ["defensive tsuppari"]) # P1 | |
add_technique("hikiotoshi", "pull", ["footwork", "skill"], ["sidestep"]) # P2 | |
add_technique("uwatedashinage", "pull", ["balance", "skill"], ["makekai"]) # P3 | |
add_technique("tsukiotoshi", "pull", ["power", "spirit"], ["tawara ballet"]) # P4 | |
add_technique("kotenage", "throw", ["power", "balance"], ["momentum stop"]) # N1 | |
add_technique("sukuinage", "throw", ["footwork", "balance"], ["sidestep"]) # N2 | |
add_technique("kubinage", "throw", ["skill", "balance"], ["defensive tsuppari"]) # N3 | |
add_technique("okurinage", "throw", ["skill", "spirit"], ["makekai"]) # N4 | |
add_technique("ashitori", "lock", ["footwork", "spirit"], ["momentum stop"]) # L1 | |
add_technique("kimedashi", "lock", ["footwork", "power"], ["tawara ballet"]) # L2 | |
add_technique("sotogake", "lock", ["footwork", "skill"], ["defensive tsuppari"]) # L3 | |
add_technique("katasukashi", "lock", ["balance", "spirit"], ["sidestep"]) # L4 | |
add_technique("oshidashi", "push", ["balance", "spirit"], ["makekai"]) # O1 | |
add_technique("okuridashi", "push", ["power", "skill"], ["tawara ballet"]) # O2 | |
add_technique("tsukidashi", "push", ["footwork", "power"], ["momentum stop"]) # O3 | |
add_technique("waridashi", "push", ["footwork", "spirit"], ["defensive tsuppari"]) # O4 | |
add_technique("sidestep", "defense", ["skill", "spirit"], ["shitatenage", "uwatedashinage", "kubinage", "ashitori"]) # D1 | |
# FIXME: transition to pull, push | |
add_technique("makekai", "defense", ["power", "footwork"], ["harimanage", "tsukiotoshi", "kotenage", "okuridashi"]) # D2 | |
# FIXME: transition to grip, lock | |
add_technique("tawara ballet", "defense", ["balance", "footwork"], ["uwatenage", "hatakikomi", "sotogake", "tsukidashi"]) # D3 | |
# FIXME: transition to throw, lock | |
add_technique("momentum stop", "defense", ["balance", "skill"], ["yorikiri", "sukuinage", "kimedashi", "waridashi"]) # D4 | |
# FIXME: transition to throw, pull | |
add_technique("defensive tsuppari", "defense", ["power", "spirit"], ["hikiotoshi", "okurinage", "katasukashi", "oshidashi"]) # D5 | |
# FIXME: transition to grip, push | |
class Move(object): | |
def __init__(self, rikishi, technique, offensive_advantage=False, transition=False): | |
self.rikishi = rikishi | |
self.technique = technique | |
self.name = technique.name | |
self.offensive_advantage = offensive_advantage | |
self.transition = transition | |
def roll(self, opponent_move): | |
die_size = self.rikishi.base_die | |
if self.offensive_advantage: | |
die_size += 2 | |
die_size += self.stat_advantage(opponent_move) | |
total = 0 | |
counter = self.counters(opponent_move) | |
for i in range(5): | |
roll = random.randint(1, die_size) | |
if counter: | |
roll = max(roll, 7) | |
total += roll | |
return total | |
def stat_advantage(self, opponent_move): | |
sdiff = self.lookup_stats() - opponent_move.lookup_stats() | |
if 1 <= sdiff <= 4: | |
return 1 | |
elif 5 <= sdiff <= 9: | |
return 2 | |
elif 10 <= sdiff: | |
return 3 | |
else: | |
return 0 | |
def counters(self, opponent_move): | |
return self.technique.counters(opponent_move.technique) | |
def lookup_stats(self): | |
stat1, stat2 = self.technique.stats | |
return getattr(self.rikishi, stat1) + getattr(self.rikishi, stat2) | |
def tachiai(rikishi, name, transition): | |
m = techniques.get(name) | |
return Move(rikishi, m, transition=transition) | |
def kimarite(rikishi, name): | |
m = techniques.get(name) | |
return Move(rikishi, m, offensive_advantage=True) | |
def defense(rikishi, name, transition): | |
m = techniques.get(name) | |
return Move(rikishi, m, transition=transition) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment