Umbau auf MMR Dynamische Berechnung von Matches.
This commit is contained in:
parent
b6fea8b84d
commit
4dfdf2165c
|
|
@ -535,6 +535,7 @@ def get_player_name(player_id):
|
|||
else:
|
||||
return "Gelöschter Spieler"
|
||||
|
||||
|
||||
def get_system_name(sys_id):
|
||||
if sys_id is None:
|
||||
return "Unbekanntes System"
|
||||
|
|
@ -552,6 +553,27 @@ def get_system_name(sys_id):
|
|||
|
||||
|
||||
|
||||
def get_days_since_last_system_game(player_id, gamesystem_id):
|
||||
"""Gibt zurück, wie viele Tage das letzte Spiel in einem bestimmten System her ist."""
|
||||
connection = sqlite3.connect(DB_PATH)
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Julianday() berechnet in SQLite die Differenz in Tagen zwischen zwei Daten
|
||||
query = """
|
||||
SELECT CAST(julianday('now') - julianday(last_played) AS INTEGER)
|
||||
FROM player_game_statistic
|
||||
WHERE player_id = ? AND gamesystem_id = ?
|
||||
"""
|
||||
cursor.execute(query, (player_id, gamesystem_id))
|
||||
result = cursor.fetchone()
|
||||
connection.close()
|
||||
|
||||
# Wenn er gefunden wurde und ein Datum hat, gib die Tage zurück. Sonst (Erstes Spiel) 0.
|
||||
if result and result[0] is not None:
|
||||
return result[0]
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -668,3 +690,45 @@ def get_match_history_log(player_id):
|
|||
connection.close()
|
||||
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Testing and Prototyping
|
||||
# -----------------------------------------------------
|
||||
def create_random_dummy_match(player_id):
|
||||
connection = sqlite3.connect(DB_PATH)
|
||||
cursor = connection.cursor()
|
||||
|
||||
# 1. Die ID des Dummys suchen (Wir suchen einfach nach dem Namen 'Dummy')
|
||||
cursor.execute("SELECT id FROM players WHERE display_name LIKE '%Dummy%' OR discord_name LIKE '%Dummy%' LIMIT 1")
|
||||
dummy_row = cursor.fetchone()
|
||||
|
||||
if not dummy_row:
|
||||
connection.close()
|
||||
print("Fehler: Kein Dummy in der Datenbank gefunden!")
|
||||
return False
|
||||
dummy_id = dummy_row[0]
|
||||
# 2. Zufällige Punkte generieren (z.B. zwischen 0 und 100)
|
||||
score_p1 = random.randint(0, 100)
|
||||
score_p2 = random.randint(0, 100)
|
||||
# 3. Das Match hart in System 1 (gamesystem_id = 1) eintragen
|
||||
query = """
|
||||
INSERT INTO matches (gamesystem_id, player2_id, player1_id, score_player1, score_player2, player2_check)
|
||||
VALUES (?, ?, ?, ?, ?, 0)
|
||||
"""
|
||||
cursor.execute(query, (1, player_id, dummy_id, score_p1, score_p2))
|
||||
|
||||
connection.commit()
|
||||
connection.close()
|
||||
|
||||
p1_name = get_player_name(player_id)
|
||||
dummy_name = get_player_name(dummy_id)
|
||||
sys_name = get_system_name(1)
|
||||
|
||||
logger.log("TEST_MATCH", f"Zufallsspiel generiert. [{sys_name}]: {p1_name} ({score_p1}) vs. {dummy_name} ({score_p2})", player_id)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -197,74 +197,3 @@ def seed_dummy_player():
|
|||
print("Test-Gegner 'Dummy Mc DummDumm' ist bereit und in allen Ligen angemeldet!")
|
||||
|
||||
|
||||
|
||||
def generate_default_mmr_rules():
|
||||
"""Erstellt für jedes Spielsystem eine Standard-JSON-Datei, falls sie noch nicht existiert."""
|
||||
connection = sqlite3.connect(DB_PATH)
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute("SELECT name FROM gamesystems")
|
||||
systems = cursor.fetchall()
|
||||
connection.close()
|
||||
|
||||
# 1. Sicherstellen, dass der Ordner existiert (Best Practice!)
|
||||
folder_path = "mmr_calculations"
|
||||
os.makedirs(folder_path, exist_ok=True)
|
||||
|
||||
# 2. Wir gehen jedes gefundene Spielsystem durch
|
||||
for sys in systems:
|
||||
sys_name = sys[0]
|
||||
|
||||
# Wir machen den Namen "dateisicher" (z.B. "Warhammer 40k" -> "warhammer_40k")
|
||||
safe_name = sys_name.replace(" ", "_").lower()
|
||||
file_path = os.path.join(folder_path, f"mmr_rules_{safe_name}.json")
|
||||
|
||||
# 3. SICHERHEITS-CHECK: Existiert die Datei schon?
|
||||
# Wenn ja, ignorieren wir sie, damit wir dein händisches Balancing nicht überschreiben!
|
||||
if not os.path.exists(file_path):
|
||||
|
||||
# Das ist unsere Standard-Vorlage (Faktor 10)
|
||||
default_rules = {
|
||||
"system_info": f"Balancing für {sys_name}",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {"win": 10, "draw": 30},
|
||||
"9": {"win": 10, "draw": 30},
|
||||
"8": {"win": 10, "draw": 20},
|
||||
"7": {"win": 10, "draw": 20},
|
||||
"6": {"win": 20, "draw": 10},
|
||||
"5": {"win": 20, "draw": 10},
|
||||
"4": {"win": 20, "draw": 0},
|
||||
"3": {"win": 20, "draw": 0},
|
||||
"2": {"win": 30, "draw": 0},
|
||||
"1": {"win": 30, "draw": 0},
|
||||
"0": {"win": 30, "draw": 0},
|
||||
"-1": {"win": 30, "draw": 0},
|
||||
"-2": {"win": 40, "draw": 0},
|
||||
"-3": {"win": 40, "draw": -10},
|
||||
"-4": {"win": 50, "draw": -20},
|
||||
"-5": {"win": 60, "draw": -20},
|
||||
"-6": {"win": 70, "draw": -20},
|
||||
"-7": {"win": 80, "draw": -50},
|
||||
"-8": {"win": 100, "draw": -50},
|
||||
"-9": {"win": 120, "draw": -60},
|
||||
"-10": {"win": 150, "draw": -60}
|
||||
},
|
||||
"score_bonus": [
|
||||
{"min_diff": 95, "bonus": 40},
|
||||
{"min_diff": 85, "bonus": 30},
|
||||
{"min_diff": 65, "bonus": 20},
|
||||
{"min_diff": 35, "bonus": 10},
|
||||
{"min_diff": 0, "bonus": 0}
|
||||
]
|
||||
}
|
||||
|
||||
# 4. JSON-Datei schreiben
|
||||
# 'w' steht für write (schreiben). indent=4 macht es für Menschen schön lesbar formatiert.
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(default_rules, f, indent=4, ensure_ascii=False)
|
||||
|
||||
print(f"Neu: Balancing-Datei für '{sys_name}' wurde erstellt -> {file_path}")
|
||||
else:
|
||||
print(f"OK: Balancing-Datei für '{sys_name}' existiert bereits.")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from nicegui import ui, app
|
|||
from data import database, data_api
|
||||
from gui import gui_style
|
||||
from wood import logger
|
||||
from gui import main_gui
|
||||
|
||||
def setup_routes():
|
||||
@ui.page('/admin', dark=True)
|
||||
|
|
@ -14,7 +15,7 @@ def setup_routes():
|
|||
if app.storage.user.get('authenticated', False):
|
||||
with ui.card().classes("w-full"):
|
||||
with ui.row().classes("w-full"):
|
||||
ui.button("test")
|
||||
ui.button(text= "test", on_click=lambda: data_api.create_random_dummy_match(2))
|
||||
ui.button(icon="refresh", on_click=lambda: ui.navigate.reload)
|
||||
|
||||
ui.label("System Audit Log").classes('text-2xl font-bold text-white mb-4')
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ def setup_routes(admin_discord_id):
|
|||
ui.table(columns=table_columns, rows=table_rows, row_key='date').classes('w-full bg-zinc-900 text-white')
|
||||
|
||||
# NEU: Der Button, der zur großen Log-Seite führt
|
||||
ui.button("Komplette Historie & Log anzeigen", icon="history", on_click=lambda: ui.navigate.to('/matchhistory')).classes('w-full mt-4 bg-zinc-700 text-white hover:bg-zinc-600')
|
||||
ui.button("Komplette Historie & Log anzeigen", icon="history", on_click=lambda: ui.navigate.to('/matchhistory')).classes('mt-4 bg-zinc-700 text-white hover:bg-zinc-600')
|
||||
else:
|
||||
ui.label("Noch keine Spiele absolviert.").classes("text-gray-500 italic")
|
||||
|
||||
|
|
|
|||
|
|
@ -80,13 +80,3 @@ def calculate_match (match_id):
|
|||
# Das Match als Berechnet markieren
|
||||
data_api.set_match_counted(match_id)
|
||||
|
||||
|
||||
|
||||
def load_mmr_rule_matrix(systemname):
|
||||
safe_name = systemname.replace(" ", "_").lower()
|
||||
|
||||
file_path = f"match_calculations/mmr_rules_{safe_name}.json"
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
rules = json.load(file)
|
||||
|
||||
return rules
|
||||
|
|
|
|||
|
|
@ -4,29 +4,69 @@ from data import data_api
|
|||
# die meisten Spieler über 1000MMR sein. Sprich: Neueinsteiger, oder leute die weniger spielen sind eher im unteren Ende als in der Mitte.
|
||||
point_inflation = 0.7 # => entspricht % ! z.B. 0.7 = 70%
|
||||
|
||||
def calc_mmr_change(systemname, winner_id, looser_id, winner_points, looser_points, match_is_draw, rules):
|
||||
#Rang der Spieler holen.
|
||||
gamesystem_id = data_api.get_gamesystem_id_by_name(systemname)
|
||||
winner_rank = data_api.get_player_rank(winner_id,gamesystem_id)
|
||||
looser_rank = data_api.get_player_rank(looser_id, gamesystem_id)
|
||||
|
||||
if match_is_draw:
|
||||
mmr_change = rules["rank_matrix"][str(max(-10, min(10, winner_rank-looser_rank)))]["draw"]
|
||||
else:
|
||||
mmr_change = rules["rank_matrix"][str(max(-10, min(10, winner_rank-looser_rank)))]["win"]
|
||||
def calc_mmr_change(systemname, winner_id, looser_id, winner_points, looser_points, match_is_draw):
|
||||
|
||||
# Slaanesh Points berechnen und dem Change hinzufügen.
|
||||
mmr_change += (sla_points := slaanesh_delight(winner_points, looser_points, rules))
|
||||
point_inflation = 0.7 # Verlierer verliert nur 70% der Punkte
|
||||
K_FACTOR = 35 # Die "Border" (Maximalpunkte) die ein Sieg gibt.
|
||||
|
||||
# Variablen für den mmr_change anlegen. Sieger-Verlierer sind unterschiedlich!
|
||||
winner_mmr_change = 0 + (mmr_change + wrath_of_khorne(winner_id))
|
||||
looser_mmr_change = 0 + (mmr_change + wrath_of_khorne(looser_id))
|
||||
def get_rust_dampener(days_ago):
|
||||
"""Berechnet den Dämpfungsfaktor basierend auf den vergangen Tagen."""
|
||||
if days_ago <= 30:
|
||||
return 1.0 # Volle Punkte
|
||||
elif days_ago > 90:
|
||||
return 0.1 # Maximal eingerostet (nur 10% der Punkteänderung)
|
||||
else:
|
||||
# Lineare Rampe von 0.8 (bei Tag 31) runter auf 0.1 (bei Tag 90)
|
||||
# Formel: Startwert - (Differenz * Prozentualer Weg)
|
||||
factor = 0.8 - 0.7 * ((days_ago - 30) / 60)
|
||||
return round(factor, 2)
|
||||
|
||||
if not match_is_draw:
|
||||
# Verlierer verliert nur einen Teil der Punkte
|
||||
looser_mmr_change = -int(winner_mmr_change * point_inflation)
|
||||
|
||||
return winner_mmr_change, looser_mmr_change
|
||||
def calc_mmr_change(systemname, winner_id, looser_id, winner_points, looser_points, match_is_draw, rules):
|
||||
gamesystem_id = data_api.get_gamesystem_id_by_name(systemname)
|
||||
|
||||
# 1. Die aktuellen MMR-Punkte holen
|
||||
w_stat = data_api.get_player_statistics_for_system(winner_id, gamesystem_id)
|
||||
l_stat = data_api.get_player_statistics_for_system(looser_id, gamesystem_id)
|
||||
|
||||
w_mmr = w_stat['mmr']
|
||||
l_mmr = l_stat['mmr']
|
||||
|
||||
|
||||
# 2. Die fließende Elo-Mathematik (Ersetzt die JSON Datei)
|
||||
# Berechnet die Siegwahrscheinlichkeit des Gewinners (Wert zwischen 0.0 und 1.0)
|
||||
expected_win = 1 / (1 + 10 ** ((l_mmr - w_mmr) / 400))
|
||||
|
||||
if match_is_draw:
|
||||
# Bei einem Draw (0.5) gewinnt der Schwächere leicht Punkte, der Stärkere verliert leicht.
|
||||
base_change = K_FACTOR * (0.5 - expected_win)
|
||||
else:
|
||||
# Sieg (1.0). Gewinnt der Favorit, gibt es wenig Punkte. Gewinnt der Underdog, gibt es viele!
|
||||
base_change = K_FACTOR * (1.0 - expected_win)
|
||||
|
||||
# 3. Den "Rostigkeits-Dämpfer" anwenden
|
||||
w_days = data_api.get_days_since_last_system_game(winner_id, gamesystem_id)
|
||||
l_days = data_api.get_days_since_last_system_game(looser_id, gamesystem_id)
|
||||
|
||||
|
||||
|
||||
# 4. Deine Sonderregeln (Slaanesh & Khorne) addieren
|
||||
sla_points = slaanesh_delight(winner_points, looser_points, rules)
|
||||
w_mmr_change += sla_points
|
||||
|
||||
# Auch der Verlierer bekommt Slaanesh Punkte addiert, wenn es die Regel so sagt
|
||||
l_mmr_change += sla_points
|
||||
|
||||
winner_final = int(w_mmr_change + wrath_of_khorne(winner_id))
|
||||
|
||||
# 5. Verlierer-Punkte abziehen und Inflation (0.7) anwenden
|
||||
if match_is_draw:
|
||||
looser_final = int(-w_mmr_change) # Bei Draw spiegeln wir es einfach (ohne Inflation)
|
||||
else:
|
||||
looser_base = int(l_mmr_change + wrath_of_khorne(looser_id))
|
||||
looser_final = -int(looser_base * point_inflation)
|
||||
|
||||
return winner_final, looser_final
|
||||
|
||||
|
||||
|
||||
|
|
@ -34,8 +74,6 @@ def calc_mmr_change(systemname, winner_id, looser_id, winner_points, looser_poin
|
|||
# -----------------
|
||||
khorne_days = 16
|
||||
khorne_bonus = 8
|
||||
|
||||
|
||||
# -----------------
|
||||
def wrath_of_khorne(player_id):
|
||||
last_played = data_api.get_days_since_last_game(player_id)["days_ago"]
|
||||
|
|
@ -46,16 +84,7 @@ def wrath_of_khorne(player_id):
|
|||
|
||||
|
||||
def slaanesh_delight(winner_points, looser_points, rules):
|
||||
|
||||
point_diff = winner_points - looser_points
|
||||
# Standardwert, falls gar nichts zutrifft
|
||||
bonus = 0
|
||||
|
||||
for threshold in rules["score_bonus"]:
|
||||
if point_diff >= threshold["min_diff"]:
|
||||
bonus = threshold["bonus"]
|
||||
break
|
||||
return bonus
|
||||
print()
|
||||
|
||||
|
||||
def tzeentch_scemes():
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"system_info": "Balancing für Spearhead",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"9": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"8": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"7": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"6": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"5": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"4": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"3": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"2": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"0": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-2": {
|
||||
"win": 40,
|
||||
"draw": 0
|
||||
},
|
||||
"-3": {
|
||||
"win": 40,
|
||||
"draw": -10
|
||||
},
|
||||
"-4": {
|
||||
"win": 50,
|
||||
"draw": -20
|
||||
},
|
||||
"-5": {
|
||||
"win": 60,
|
||||
"draw": -20
|
||||
},
|
||||
"-6": {
|
||||
"win": 70,
|
||||
"draw": -20
|
||||
},
|
||||
"-7": {
|
||||
"win": 80,
|
||||
"draw": -50
|
||||
},
|
||||
"-8": {
|
||||
"win": 100,
|
||||
"draw": -50
|
||||
},
|
||||
"-9": {
|
||||
"win": 120,
|
||||
"draw": -60
|
||||
},
|
||||
"-10": {
|
||||
"win": 150,
|
||||
"draw": -60
|
||||
}
|
||||
},
|
||||
"score_bonus": [
|
||||
{
|
||||
"min_diff": 15,
|
||||
"bonus": 40
|
||||
},
|
||||
{
|
||||
"min_diff": 10,
|
||||
"bonus": 30
|
||||
},
|
||||
{
|
||||
"min_diff": 6,
|
||||
"bonus": 20
|
||||
},
|
||||
{
|
||||
"min_diff": 3,
|
||||
"bonus": 10
|
||||
},
|
||||
{
|
||||
"min_diff": 0,
|
||||
"bonus": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"system_info": "Balancing für Warhammer 40k",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"9": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"8": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"7": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"6": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"5": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"4": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"3": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"2": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"0": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-2": {
|
||||
"win": 40,
|
||||
"draw": 0
|
||||
},
|
||||
"-3": {
|
||||
"win": 40,
|
||||
"draw": -10
|
||||
},
|
||||
"-4": {
|
||||
"win": 50,
|
||||
"draw": -20
|
||||
},
|
||||
"-5": {
|
||||
"win": 60,
|
||||
"draw": -20
|
||||
},
|
||||
"-6": {
|
||||
"win": 70,
|
||||
"draw": -20
|
||||
},
|
||||
"-7": {
|
||||
"win": 80,
|
||||
"draw": -50
|
||||
},
|
||||
"-8": {
|
||||
"win": 100,
|
||||
"draw": -50
|
||||
},
|
||||
"-9": {
|
||||
"win": 120,
|
||||
"draw": -60
|
||||
},
|
||||
"-10": {
|
||||
"win": 150,
|
||||
"draw": -60
|
||||
}
|
||||
},
|
||||
"score_bonus": [
|
||||
{
|
||||
"min_diff": 95,
|
||||
"bonus": 40
|
||||
},
|
||||
{
|
||||
"min_diff": 85,
|
||||
"bonus": 30
|
||||
},
|
||||
{
|
||||
"min_diff": 65,
|
||||
"bonus": 20
|
||||
},
|
||||
{
|
||||
"min_diff": 35,
|
||||
"bonus": 10
|
||||
},
|
||||
{
|
||||
"min_diff": 0,
|
||||
"bonus": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"system_info": "Balancing für Warhammer Age of Sigmar",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"9": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"8": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"7": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"6": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"5": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"4": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"3": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"2": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"0": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-2": {
|
||||
"win": 40,
|
||||
"draw": 0
|
||||
},
|
||||
"-3": {
|
||||
"win": 40,
|
||||
"draw": -10
|
||||
},
|
||||
"-4": {
|
||||
"win": 50,
|
||||
"draw": -20
|
||||
},
|
||||
"-5": {
|
||||
"win": 60,
|
||||
"draw": -20
|
||||
},
|
||||
"-6": {
|
||||
"win": 70,
|
||||
"draw": -20
|
||||
},
|
||||
"-7": {
|
||||
"win": 80,
|
||||
"draw": -50
|
||||
},
|
||||
"-8": {
|
||||
"win": 100,
|
||||
"draw": -50
|
||||
},
|
||||
"-9": {
|
||||
"win": 120,
|
||||
"draw": -60
|
||||
},
|
||||
"-10": {
|
||||
"win": 150,
|
||||
"draw": -60
|
||||
}
|
||||
},
|
||||
"score_bonus": [
|
||||
{
|
||||
"min_diff": 40,
|
||||
"bonus": 40
|
||||
},
|
||||
{
|
||||
"min_diff": 30,
|
||||
"bonus": 30
|
||||
},
|
||||
{
|
||||
"min_diff": 20,
|
||||
"bonus": 20
|
||||
},
|
||||
{
|
||||
"min_diff": 10,
|
||||
"bonus": 10
|
||||
},
|
||||
{
|
||||
"min_diff": 0,
|
||||
"bonus": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"system_info": "Balancing für Spearhead",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"9": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"8": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"7": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"6": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"5": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"4": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"3": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"2": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"0": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-2": {
|
||||
"win": 40,
|
||||
"draw": 0
|
||||
},
|
||||
"-3": {
|
||||
"win": 40,
|
||||
"draw": -10
|
||||
},
|
||||
"-4": {
|
||||
"win": 50,
|
||||
"draw": -20
|
||||
},
|
||||
"-5": {
|
||||
"win": 60,
|
||||
"draw": -20
|
||||
},
|
||||
"-6": {
|
||||
"win": 70,
|
||||
"draw": -20
|
||||
},
|
||||
"-7": {
|
||||
"win": 80,
|
||||
"draw": -50
|
||||
},
|
||||
"-8": {
|
||||
"win": 100,
|
||||
"draw": -50
|
||||
},
|
||||
"-9": {
|
||||
"win": 120,
|
||||
"draw": -60
|
||||
},
|
||||
"-10": {
|
||||
"win": 150,
|
||||
"draw": -60
|
||||
}
|
||||
},
|
||||
"score_bonus": [
|
||||
{
|
||||
"min_diff": 95,
|
||||
"bonus": 40
|
||||
},
|
||||
{
|
||||
"min_diff": 85,
|
||||
"bonus": 30
|
||||
},
|
||||
{
|
||||
"min_diff": 65,
|
||||
"bonus": 20
|
||||
},
|
||||
{
|
||||
"min_diff": 35,
|
||||
"bonus": 10
|
||||
},
|
||||
{
|
||||
"min_diff": 0,
|
||||
"bonus": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"system_info": "Balancing für Warhammer 40k",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"9": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"8": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"7": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"6": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"5": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"4": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"3": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"2": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"0": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-2": {
|
||||
"win": 40,
|
||||
"draw": 0
|
||||
},
|
||||
"-3": {
|
||||
"win": 40,
|
||||
"draw": -10
|
||||
},
|
||||
"-4": {
|
||||
"win": 50,
|
||||
"draw": -20
|
||||
},
|
||||
"-5": {
|
||||
"win": 60,
|
||||
"draw": -20
|
||||
},
|
||||
"-6": {
|
||||
"win": 70,
|
||||
"draw": -20
|
||||
},
|
||||
"-7": {
|
||||
"win": 80,
|
||||
"draw": -50
|
||||
},
|
||||
"-8": {
|
||||
"win": 100,
|
||||
"draw": -50
|
||||
},
|
||||
"-9": {
|
||||
"win": 120,
|
||||
"draw": -60
|
||||
},
|
||||
"-10": {
|
||||
"win": 150,
|
||||
"draw": -60
|
||||
}
|
||||
},
|
||||
"score_bonus": [
|
||||
{
|
||||
"min_diff": 95,
|
||||
"bonus": 40
|
||||
},
|
||||
{
|
||||
"min_diff": 85,
|
||||
"bonus": 30
|
||||
},
|
||||
{
|
||||
"min_diff": 65,
|
||||
"bonus": 20
|
||||
},
|
||||
{
|
||||
"min_diff": 35,
|
||||
"bonus": 10
|
||||
},
|
||||
{
|
||||
"min_diff": 0,
|
||||
"bonus": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
{
|
||||
"system_info": "Balancing für Warhammer Age of Sigmar",
|
||||
"draw_point_difference": 3,
|
||||
"rank_matrix": {
|
||||
"10": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"9": {
|
||||
"win": 10,
|
||||
"draw": 30
|
||||
},
|
||||
"8": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"7": {
|
||||
"win": 10,
|
||||
"draw": 20
|
||||
},
|
||||
"6": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"5": {
|
||||
"win": 20,
|
||||
"draw": 10
|
||||
},
|
||||
"4": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"3": {
|
||||
"win": 20,
|
||||
"draw": 0
|
||||
},
|
||||
"2": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"0": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-1": {
|
||||
"win": 30,
|
||||
"draw": 0
|
||||
},
|
||||
"-2": {
|
||||
"win": 40,
|
||||
"draw": 0
|
||||
},
|
||||
"-3": {
|
||||
"win": 40,
|
||||
"draw": -10
|
||||
},
|
||||
"-4": {
|
||||
"win": 50,
|
||||
"draw": -20
|
||||
},
|
||||
"-5": {
|
||||
"win": 60,
|
||||
"draw": -20
|
||||
},
|
||||
"-6": {
|
||||
"win": 70,
|
||||
"draw": -20
|
||||
},
|
||||
"-7": {
|
||||
"win": 80,
|
||||
"draw": -50
|
||||
},
|
||||
"-8": {
|
||||
"win": 100,
|
||||
"draw": -50
|
||||
},
|
||||
"-9": {
|
||||
"win": 120,
|
||||
"draw": -60
|
||||
},
|
||||
"-10": {
|
||||
"win": 150,
|
||||
"draw": -60
|
||||
}
|
||||
},
|
||||
"score_bonus": [
|
||||
{
|
||||
"min_diff": 95,
|
||||
"bonus": 40
|
||||
},
|
||||
{
|
||||
"min_diff": 85,
|
||||
"bonus": 30
|
||||
},
|
||||
{
|
||||
"min_diff": 65,
|
||||
"bonus": 20
|
||||
},
|
||||
{
|
||||
"min_diff": 35,
|
||||
"bonus": 10
|
||||
},
|
||||
{
|
||||
"min_diff": 0,
|
||||
"bonus": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user