Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added src/lpsim/grading/__init__.py
Empty file.
105 changes: 105 additions & 0 deletions src/lpsim/grading/grading.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import json
import os

from src.lpsim.server.consts import ObjectType


TEST_MATCH = os.path.dirname(os.path.abspath(__file__)) + "/match_1.json"


class Grading:
def __init__(self, match: str):
with open(match) as f:
self.data = json.load(f)
self.expected_turn = 4
self.current_turn = 0
self.character_element = []
self.grading_rules = {}
self.grade_match(self.data)

def load_grading(self, obj_type, name, version):
key = "%s+%s+%s" % (obj_type, name, version)
if key in self.grading_rules.keys():
return self.grading_rules[key]
grading_file = os.path.dirname(os.path.abspath(__file__)) + "/grading_rules/%s/%s+%s" % (obj_type, name, version)
with open(grading_file) as f:
rule = json.load(f)
self.grading_rules[key] = rule
return rule

def grade_by_rule(self, obj_type, name, version, usage):
rule = self.load_grading(obj_type, name, version)
a = rule[0]
q = rule[1]
n = usage
if usage == 0:
n = max(1, self.expected_turn - self.current_turn)
return a * (1 - pow(q, n)) / (1 - q)

def grade_match(self, match):
self.current_turn = match["round_number"]
return self.grade_player(match["player_tables"][0]) - self.grade_player(match["player_tables"][1])

def grade_player(self, player):
grade = 0
for character in player["characters"]:
grade += self.grade_character(character)
for status in player["team_status"]:
grade += self.grade_team_status(status)
grade += self.grade_dice(player["dice"])
grade += self.grade_hands(player["hands"])
for summon in player["summons"]:
grade += self.grade_summon(summon)
for support in player["supports"]:
grade += self.grade_support(support)
return grade

def grade_character(self, character):
grade = 0
if character["name"] == "Barbara":
self.expected_turn += 5
if character["name"] == "Dehya":
self.expected_turn += 2
# grading hp
grade += character["hp"] * 10
# grading attaches
grade += self.grade_attaches(character["attaches"])
# register elements
self.character_element.append(character["element"])
return grade

def grade_attaches(self, attaches):
grade = 0
for attach in attaches:
print(attach)
if attach["type"] == "character_status":
grade += self.grade_character_status(attach)
else:
grade += self.grade_character_status(attach)
return 0

def grade_dice(self, dice):
effect_dice = 0
for dice in dice["colors"]:
if dice == "OMNI" or dice in self.character_element:
effect_dice += 1
return effect_dice * 5 + len(dice)

def grade_hands(self, hands):
return len(hands) * 5

def grade_summon(self, summon):
return self.grade_by_rule("summon", summon["name"], summon["version"], summon["usage"])

def grade_support(self, support):
return self.grade_by_rule("support", support["name"], support["version"], support["usage"])

def grade_character_status(self, status):
return self.grade_by_rule("character_status", status["name"], status["version"], status["usage"])

def grade_team_status(self, status):
return self.grade_by_rule("team_status", status["name"], status["version"], status["usage"])


if __name__ == "__main__":
grading = Grading(TEST_MATCH)
Empty file added src/lpsim/model/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions src/lpsim/model/card.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "",
"version": ""
}
9 changes: 9 additions & 0 deletions src/lpsim/model/character.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "",
"version": "",
"hp": -1,
"charge": -1,
"attaches": [],
"element_application": [],
"is_alive": true
}
6 changes: 6 additions & 0 deletions src/lpsim/model/character_status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "",
"version": "",
"usage": -1,
"max_usage": -1
}
3 changes: 3 additions & 0 deletions src/lpsim/model/dice.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"colors": []
}
7 changes: 7 additions & 0 deletions src/lpsim/model/match.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "",
"version": "",
"player_tables": [],
"current_player": -1,
"round_number": -1
}
241 changes: 241 additions & 0 deletions src/lpsim/model/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import json
import os

from src.lpsim.server import *
from src.lpsim.server.consts import ObjectType
from src.lpsim.server.dice import Dice
from src.lpsim.server.match import Match
from src.lpsim.server.player_table import PlayerTable
from src.lpsim.utils import *

PROTOTYPE_PATH = os.path.dirname(os.path.abspath(__file__)) + "/"


class model:
def get_prototype(self, obj_str):
with open(PROTOTYPE_PATH + obj_str + ".json") as f:
data = json.load(f)
return data

def match_to_json(self, match, name):
match_data = self.get_match(match)
with open(PROTOTYPE_PATH + name + ".json", 'w') as f:
json.dump(match_data, f, indent=4)

def json_to_match(self, name):
with open(PROTOTYPE_PATH + name + ".json", 'r') as f:
data = json.load(f)
return self.set_match(data)

def get_match(self, match):
match_model = self.get_prototype("match")
match_model["name"] = match.name
match_model["version"] = match.version
match_model["round_number"] = match.round_number
match_model["current_player"] = match.current_player
match_model["player_tables"] = [self.get_player(x) for x in match.player_tables]
return match_model

def set_match(self, match_model):
match = Match()
match.name = match_model["name"]
match.version = match_model["version"]
match.round_number = match_model["round_number"]
match.current_player = match_model["current_player"]
match.player_tables = [self.set_player(x) for x in match_model["player_tables"]]
return match

def get_player(self, player):
player_model = self.get_prototype("player")
player_model["name"] = player.name
player_model["version"] = player.version
player_model["player_idx"] = player.player_idx
player_model["active_character_idx"] = player.active_character_idx
player_model["has_round_ended"] = player.has_round_ended
player_model["arcane_legend"] = player.arcane_legend
player_model["plunge_satisfied"] = player.plunge_satisfied
player_model["dice"] = self.get_dice(player.dice)
player_model["characters"] = [self.get_character(x) for x in player.characters]
player_model["team_status"] = [self.get_team_status(x) for x in player.team_status]
player_model["summons"] = [self.get_summon(x) for x in player.summons]
player_model["supports"] = [self.get_support(x) for x in player.supports]
player_model["hands"] = self.get_hands(player.hands)
player_model["table_deck"] = self.get_deck(player.table_deck)
return player_model

def set_player(self, player_model):
player = PlayerTable(
version=player_model["version"],
player_idx=player_model["player_idx"],
)
player.dice = self.set_dice(player_model["dice"])
player.characters = [self.set_character(x) for x in player_model["characters"]]
player.team_status = [self.set_character_status(x) for x in player_model["team_status"]]
player.summons = [self.set_character_status(x) for x in player_model["summons"]]
player.supports = [self.set_character_status(x) for x in player_model["supports"]]
player.hands = self.set_hands(player_model["hands"])
player.table_deck = self.set_deck(player_model["table_deck"])
return player

def get_character(self, character):
character_model = self.get_prototype("character")
character_model["name"] = character.name
character_model["version"] = character.version
character_model["element"] = character.element
character_model["hp"] = character.hp
character_model["charge"] = character.charge
character_model["attaches"] = [self.get_attach(x) for x in character.attaches]
character_model["element_application"] = character.element_application
character_model["is_alive"] = character.is_alive
return character_model

def set_character(self, character_model):
args = {"name": character_model["name"], "version": character_model["version"]}
character = get_instance(CharacterBase, args)
character.attaches = [self.set_attach(x) for x in character_model["attaches"]]
return character

def get_attach(self, attach):
if attach.type == ObjectType.CHARACTER_STATUS:
attach_model = self.get_character_status(attach)
attach_model["type"] = "character_status"
return attach_model
else:
attach_model = self.get_card(attach)
attach_model["type"] = "equipment"
return attach_model

def set_attach(self, attach_model):
if attach_model["type"] == "character_status":
return self.set_character_status(attach_model)
elif attach_model["type"] == "equipment":
return self.set_card(attach_model)

def get_card(self, card):
if card is None:
return None
card_model = self.get_prototype("card")
card_model["name"] = card.name
card_model["version"] = card.version
return card_model

def set_card(self, card_model):
if card_model is None:
return None
return get_instance(CardBase, card_model)

def get_character_status(self, status):
character_status_model = self.get_prototype("character_status")
character_status_model["name"] = status.name
character_status_model["version"] = status.version
character_status_model["usage"] = status.usage
character_status_model["max_usage"] = status.max_usage
return character_status_model

def set_character_status(self, status_model):
return get_instance(CharacterStatusBase, status_model)

def get_deck(self, deck):
return [self.get_card(x) for x in deck]

def set_deck(self, deck_model):
return [get_instance(CardBase, x) for x in deck_model]

def get_dice(self, dice):
dice_model = self.get_prototype("dice")
dice_model["colors"] = dice.colors
return dice_model

def set_dice(self, dice_model):
dice = Dice()
dice.colors = dice_model["colors"]
return dice

def get_hands(self, hands):
return [self.get_card(x) for x in hands]

def set_hands(self, hands_model):
return [get_instance(CardBase, x) for x in hands_model]

def get_summon(self, summon):
summon_model = self.get_prototype("summon")
summon_model["name"] = summon.name
summon_model["version"] = summon.version
summon_model["usage"] = summon.usage
summon_model["max_usage"] = summon.max_usage
return summon_model

def set_summon(self, summon_model):
return get_instance(SummonBase, summon_model)

def get_support(self, support):
support_model = self.get_prototype("support")
support_model["name"] = support.name
support_model["version"] = support.version
support_model["usage"] = support.usage
return support_model

def set_support(self, support_model):
return get_instance(SupportBase, support_model)

def get_team_status(self, status):
team_status_model = self.get_prototype("team_status")
team_status_model["name"] = status.name
team_status_model["version"] = status.version
team_status_model["usage"] = status.usage
team_status_model["max_usage"] = status.max_usage
return team_status_model

def set_team_status(self, status_model):
return get_instance(TeamStatusBase, status_model)


if __name__ == "__main__":
from src.lpsim.server.deck import Deck
from src.lpsim.agents import RandomAgent
agent_0 = RandomAgent(player_idx=0)
agent_1 = RandomAgent(player_idx=1)
deck = Deck.from_str(
'''
default_version:4.1
character:Rhodeia of Loch
character:Kamisato Ayaka
character:Yaoyao
Traveler's Handy Sword*5
Gambler's Earrings*5
Kanten Senmyou Blessing*5
Sweet Madame*5
Abyssal Summons*5
Fatui Conspiracy*5
Timmie*5
'''
)
match = Match()
match.set_deck([deck, deck])
match.config.max_same_card_number = 30
match.config.history_level = 10
match.config.check_deck_restriction = False
match.config.initial_hand_size = 20
match.config.max_hand_size = 30
match.config.card_number = None
assert match.start()[0]
match.step()

while match.round_number < 3 \
and not match.is_game_end():
if match.need_respond(0):
current_agent = agent_0
elif match.need_respond(1):
current_agent = agent_1
else:
raise RuntimeError("no agent need to respond")
resp = current_agent.generate_response(match)
assert resp is not None
match.respond(resp)
match.step()

Model = model()
Model.match_to_json(match, "match_1")
match = Model.json_to_match("match_1")
Model.match_to_json(match, "match_2")
assert Model.get_prototype("match_1") == Model.get_prototype("match_2")
Loading