Switch to Battlegrounds-style matchmaking
This commit is contained in:
parent
ab7a31d6bf
commit
4baeeb0f18
45
main.py
45
main.py
@ -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}")
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 [
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user