Switch to Battlegrounds-style matchmaking

This commit is contained in:
Pyrex 2024-11-17 13:30:02 -08:00
parent ab7a31d6bf
commit 4baeeb0f18
3 changed files with 122 additions and 26 deletions

45
main.py
View File

@ -1,5 +1,6 @@
import sys import sys
from datetime import datetime, UTC from datetime import datetime, UTC
from functools import cmp_to_key
from typing import Optional from typing import Optional
import os.path import os.path
@ -36,14 +37,48 @@ def main():
while True: while True:
state: StateT = storage.fetch_last_state() state: StateT = storage.fetch_last_state()
state.do_tournament(names, _ask) state.do_tournament(names, _rerank)
storage.store_state(state) storage.store_state(state)
_write_rankings(state) _write_rankings(state)
def _rerank(items: list[ItemT]) -> list[ItemT]:
results = []
remaining = {ix: value for ix, value in enumerate(items, 1)}
def _ask(item0: ItemT, item1: ItemT) -> Optional[ItemT]: while len(remaining) > 1:
print("Pick your favorite(s): ")
for ix, i in remaining.items():
print(f"{ix: >4}. {i.name}")
while True:
choices = input("> ")
for choice in choices:
try:
choice_ix = int(choice)
except ValueError:
print(f"not a number: {choice}")
continue
if choice_ix not in remaining:
print(f"not a valid index: {choice_ix}")
continue
results.append(remaining.pop(choice_ix))
if len(choices) > 0:
break
assert len(remaining) <= 1
if remaining:
results.append(next(iter(remaining.values())))
return results
def _ask(item0: ItemT, item1: ItemT) -> int:
print("Which do you prefer?") print("Which do you prefer?")
print(f" 0: {item0.name}") print(f" 0: {item0.name}")
print(f" 1: {item1.name}") print(f" 1: {item1.name}")
@ -52,11 +87,11 @@ def _ask(item0: ItemT, item1: ItemT) -> Optional[ItemT]:
while True: while True:
i = input("0/1/2> ") i = input("0/1/2> ")
if i == "0": if i == "0":
return item0 return -1
elif i == "1": elif i == "1":
return item1 return 1
elif i == "2": elif i == "2":
return None return 0
print(f"unexpected input: {i}") print(f"unexpected input: {i}")

View File

@ -37,7 +37,7 @@ class StateT(BaseModel):
enabled=True, enabled=True,
)) ))
def do_tournament(self, names: list[str], callback: Callable[[ItemT, ItemT], Optional[ItemT]]): def do_tournament(self, names: list[str], callback: Callable[[list[ItemT]], list[ItemT]]):
# bring up to date # bring up to date
self._bring_up_to_date(names) self._bring_up_to_date(names)
@ -46,29 +46,21 @@ class StateT(BaseModel):
if len(possible_entrants) < 2: if len(possible_entrants) < 2:
raise ValueError("need at least two things to compare") raise ValueError("need at least two things to compare")
entrants = random.sample(possible_entrants, k=2) entrants = random.sample(possible_entrants, k=min(len(possible_entrants), 8))
expected_score = [0.0] * len(entrants)
score = [0.0] * len(entrants)
# ask for a winner reranked = callback(list(entrants))
winner = callback(entrants[0], entrants[1])
# update elo for e, entrant in enumerate(entrants):
score_0 = 0.0 for e2, other in enumerate(entrants):
score_1 = 0.0 if e2 == e:
continue
expected_score[e] += expected(entrant.elo, other.elo)
score[e] += float(reranked.index(entrant) < reranked.index(other))
if winner is None: for e, entrant in enumerate(entrants):
score_0 += 0.5 entrant.elo = elo(entrant.elo, expected_score[e], score[e])
score_1 += 0.5
elif winner == entrants[0]:
score_0 += 1.0
elif winner == entrants[1]:
score_1 += 1.0
expected_score_0 = expected(entrants[0].elo, entrants[1].elo)
expected_score_1 = expected(entrants[1].elo, entrants[0].elo)
# assert expected_score_0 == 1 - expected_score_1
entrants[0].elo = elo(entrants[0].elo, expected_score_0, score_0)
entrants[1].elo = elo(entrants[1].elo, expected_score_1, score_1)
def dump_rankings(self) -> list[tuple[str, int]]: def dump_rankings(self) -> list[tuple[str, int]]:
return [ return [

View File

@ -1,2 +1,71 @@
Saturday - Childish Gambino Saturday - Childish Gambino
Alice - Moby (Noisia Remix) Alice - Moby (Noisia Remix)
103 Degrees - Spor
Good Luck - Basement Jaxx
Rendez-Vu - Basement Jaxx
Mermaid of Salinas - Basement Jaxx
Do You Know Squarepusher - Squarepusher
A Soft Seduction - David Byrne
Army Dreamers - Kate Bush
The Long Honeymoon - Elvis Costello
Just Like Heaven - The Cure
Blood Red - Feed Me
It's Working - MGMT
Your Woman - White Town
Shimmy Shimmy Ya - Old Dirty Bastard
Ancient Voices - Russell Landau
Parade - Susumu Hirasawa
Casino Royale - Herb Alpert
Instant Crush - Daft Punk
Crazy - Gnarls Barkley
Alone Again Or - Love
Stars - Nina Simone
Alright - Kendrick Lamar
Hayloft - Mother Mother
Lola - The Kinks
Mandalay Song - Kurt Weill
Dance Anthem of the 80s - Regina Spektor
Cannibal Holocaust - Riz Ortolani
Kiss From A Rose - Seal
Shemokmedura - Basiani Ensemble
Not Like Us - Kendrick Lamar
It's Alright - Jack Stauber
Barracuda - John Cale
My Party - Kero Kero Bonito (bo en remix)
The Lovecats - The Cure
PREMIERE - AQUASINE
See Emily Play - Pink FLoyd
Little Wing - Jimi Hendrix
Girlfriend Is Better - Talking Heads
SNUFFY - Metaroom
KEYWING #001 - AQUASINE
Balatro Main Theme - ???
People Who Died - The Jim Carroll Band
Live (Big Brother Theme) - ???
Classical Gas - Mason Williams
Misirlou - Dick Dale
Alfonso Muskedunder - Todd Terje
Hey Kids - Molina
Scared - Mzekezeke
classic j dies and goes to hell part 1 - glass beach
Everything's Alright - Ginger Root
Red Dress - Sarah Brand
Unfunky UFO - Parliament
Babooshka - Kate Bush
Mr. Greives [sic] - TV on the Radio
Ready For The Floor - Hot Chip
Since I Left You - The Avalanches
She Said She Said - Beatles
Omen - The Prodigy
Eli Eli - Misun (Maduk Remix)
Blac - Qntal
Self-Aware Wolf - Loden (feat. Busdriver)
Goodbye - Paul McCartney
Ffunny Ffrends - Unknown Mortal Orchestra
Multi-Love - Unknown Mortal Orchestra
The Parasite - Eugene McDaniels
Here Comes The Sun - Bill Wurtz
Song For Dan Treacy - MGMT
Eyesore - Women
Paris 1919 - John Cale
Baby Hotline - Jack Stauber