Skip to content

Commit

Permalink
added mmr momentum
Browse files Browse the repository at this point in the history
  • Loading branch information
99oblivius committed Oct 6, 2024
1 parent 45fa64a commit 2badd0d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 11 deletions.
46 changes: 46 additions & 0 deletions alembic/versions/1e0b04a3790e_valorsbot_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""ValorsBot model
Revision ID: 1e0b04a3790e
Revises: 635cc8120b46
Create Date: 2024-10-06 04:30:38.165999
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '1e0b04a3790e'
down_revision: Union[str, None] = '635cc8120b46'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('bot_settings', schema=None) as batch_op:
batch_op.drop_column('mm_maps_phase')

with op.batch_alter_table('mm_bot_matches', schema=None) as batch_op:
batch_op.drop_column('maps_phase')

with op.batch_alter_table('mm_bot_user_summary_stats', schema=None) as batch_op:
batch_op.add_column(sa.Column('momentum', sa.Float(), nullable=True))

# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('mm_bot_user_summary_stats', schema=None) as batch_op:
batch_op.drop_column('momentum')

with op.batch_alter_table('mm_bot_matches', schema=None) as batch_op:
batch_op.add_column(sa.Column('maps_phase', sa.BIGINT(), server_default=sa.text('0'), autoincrement=False, nullable=False))

with op.batch_alter_table('bot_settings', schema=None) as batch_op:
batch_op.add_column(sa.Column('mm_maps_phase', sa.SMALLINT(), autoincrement=False, nullable=False))

# ### end Alembic commands ###
2 changes: 2 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
MATCH_PLAYER_COUNT = 10
STARTING_MMR = 900
BASE_MMR_CHANGE = 40
MOMENTUM_CHANGE = 0.05
MOMENTUM_RESET_FACTOR = 0.3
PLACEMENT_MATCHES = 10

REGION_TIMEZONES = {
Expand Down
19 changes: 16 additions & 3 deletions src/matches/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from typing import List
import numpy as np

from config import BASE_MMR_CHANGE, STARTING_MMR
from config import BASE_MMR_CHANGE, STARTING_MMR, MOMENTUM_CHANGE, MOMENTUM_RESET_FACTOR
from utils.models import MMBotMaps, MMBotUserMapPicks, Side
from utils.utils import lerp

Expand Down Expand Up @@ -71,7 +71,8 @@ def calculate_mmr_change(
enemy_team_avg_mmr: int=0,
win: bool=False,
abandoned_count: int=0,
placements: bool=False
placements: bool=False,
momentum: float=1.0
) -> int:
kills = player_stats.get('kills', 0)
deaths = player_stats.get('deaths', 0)
Expand All @@ -96,6 +97,8 @@ def calculate_mmr_change(
new_r = base_change * (int(win) - pr_a)
new_r *= closeness
new_r += kd_rate
if not abandoned_count:
new_r *= momentum
return new_r

def calculate_placements_mmr(user_avg_score: int, guild_avg_scores: List[int], initial_mmr: int) -> int:
Expand All @@ -119,4 +122,14 @@ def calculate_placements_mmr(user_avg_score: int, guild_avg_scores: List[int], i
mmr_change = lerp(lower_mmr, upper_mmr, normalized_score)
break

return max(STARTING_MMR - 300, min(STARTING_MMR + 450, initial_mmr + mmr_change))
return max(STARTING_MMR - 300, min(STARTING_MMR + 450, initial_mmr + mmr_change))

def update_momentum(current_momentum, win):
if (win and current_momentum >= 1.0) or (not win and current_momentum <= 1.0):
new_momentum = current_momentum + MOMENTUM_CHANGE if win else current_momentum - MOMENTUM_CHANGE
else:
difference = current_momentum - 1.0
reset = difference * MOMENTUM_RESET_FACTOR
new_momentum = current_momentum - reset

return max(0.5, min(2.0, new_momentum))
15 changes: 10 additions & 5 deletions src/matches/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from views.match.side_pick import ChosenSideView, SidePickView
from views.match.no_server_found import NoServerFoundView
from views.match.force_abandon import ForceAbandonView
from .functions import calculate_mmr_change, get_preferred_bans, get_preferred_map, get_preferred_side, calculate_placements_mmr
from .functions import calculate_mmr_change, get_preferred_bans, get_preferred_map, get_preferred_side, calculate_placements_mmr, update_momentum
from .match_states import MatchState
from .ranked_teams import get_teams

Expand Down Expand Up @@ -238,6 +238,7 @@ def update_user_match_stats(self, user_stats, player_data):
def update_summary_stats(self, summary_data, match_stats):
return {
"mmr": summary_data.mmr + match_stats['mmr_change'],
"momentum": update_momentum(summary_data.momentum, match_stats['win']),
"games": summary_data.games + 1,
"wins": summary_data.wins + int(match_stats['win']),
"losses": summary_data.losses + int(not match_stats['win']),
Expand Down Expand Up @@ -277,19 +278,23 @@ async def finalize_match(self, users_summary_data, team_scores, last_reply: dict
ct_start = current_stats['ct_start']
win = team_scores[0] > team_scores[1] if ct_start else team_scores[1] > team_scores[0]

summary_data = users_summary_data[user_id]
ally_score = team_scores[0] if ct_start else team_scores[1]
enemy_score = team_scores[1] if ct_start else team_scores[0]
ally_mmr = self.match.a_mmr if player.team == Team.A else self.match.b_mmr
enemy_mmr = self.match.b_mmr if player.team == Team.A else self.match.a_mmr


mmr_change = calculate_mmr_change(current_stats,
ally_team_score=ally_score, enemy_team_score=enemy_score,
ally_team_avg_mmr=ally_mmr, enemy_team_avg_mmr=enemy_mmr, win=win,
placements=games_played <= PLACEMENT_MATCHES)
ally_team_score=ally_score,
enemy_team_score=enemy_score,
ally_team_avg_mmr=ally_mmr,
enemy_team_avg_mmr=enemy_mmr, win=win,
placements=games_played <= PLACEMENT_MATCHES,
momentum=summary_data.momentum)

current_stats.update({"win": win, "mmr_change": mmr_change})

summary_data = users_summary_data[user_id]
new_mmr = summary_data.mmr + current_stats['mmr_change']
if games_played == PLACEMENT_MATCHES:
placement_completions.append((member, new_mmr))
Expand Down
1 change: 1 addition & 0 deletions src/utils/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ class MMBotUserSummaryStats(Base):
guild_id = Column(BigInteger, primary_key=True, nullable=False)
user_id = Column(BigInteger, primary_key=True, nullable=False)
mmr = Column(Float, default=900)
momentum = Column(Float, default=1)
games = Column(Integer, default=0)
wins = Column(Integer, default=0)
losses = Column(Integer, default=0)
Expand Down
6 changes: 3 additions & 3 deletions src/views/match/force_abandon.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ async def cancel_callback(interaction: nextcord.Integration):
cancel_button.callback = cancel_callback
view.add_item(cancel_button)

cancel_button = nextcord.ui.Button(
confirm_button = nextcord.ui.Button(
label="Confirm", emoji="✔️", style=nextcord.ButtonStyle.danger)
cancel_button.callback = confirm_callback
view.add_item(confirm_callback)
confirm_button.callback = confirm_callback
view.add_item(confirm_button)

embed = nextcord.Embed(
title="Force Abandon the missing players?",
Expand Down

0 comments on commit 2badd0d

Please sign in to comment.