Add assignment
This commit is contained in:
89
Tests/puzzlerating.py
Executable file
89
Tests/puzzlerating.py
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from puzzledb import PuzzleDb
|
||||
from puzzlerunner import run_puzzle
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from random import Random
|
||||
|
||||
import glicko2
|
||||
|
||||
|
||||
def select_puzzles(player, puzzle_db, num_puzzles, played_puzzles, random):
|
||||
rd = player.rd
|
||||
candidates = []
|
||||
|
||||
while len(candidates) < num_puzzles:
|
||||
candidates = puzzle_db \
|
||||
.filter(lambda p: p.rating >= player.rating - 2 * rd) \
|
||||
.filter(lambda p: p.rating <= player.rating + 2 * rd) \
|
||||
.filter(lambda p: p not in played_puzzles) \
|
||||
.collect()
|
||||
|
||||
rd += 50
|
||||
|
||||
return sorted(random.sample(candidates, num_puzzles),
|
||||
key=lambda p: p.rating)
|
||||
|
||||
|
||||
def play_round(player, puzzle_db, num_puzzles, engine,
|
||||
timeout, played_puzzles, random):
|
||||
puzzles = select_puzzles(player, puzzle_db, num_puzzles,
|
||||
played_puzzles, random)
|
||||
played_puzzles.update(puzzles)
|
||||
outcomes = []
|
||||
|
||||
for puzzle in puzzles:
|
||||
print(f'Running puzzle {puzzle.puzzle_id} '
|
||||
f'with rating {puzzle.rating}... ',
|
||||
end='', flush=True)
|
||||
|
||||
result = run_puzzle(puzzle, engine, timeout)
|
||||
success = result.is_success()
|
||||
outcomes.append(success)
|
||||
|
||||
if success:
|
||||
print('OK')
|
||||
else:
|
||||
print('FAIL')
|
||||
|
||||
ratings = [p.rating for p in puzzles]
|
||||
rds = [p.rd for p in puzzles]
|
||||
player.update_player(ratings, rds, outcomes)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--engine', type=Path, required=True)
|
||||
parser.add_argument('--timeout', type=float, default=60)
|
||||
parser.add_argument('--min-plays', type=int, default=500)
|
||||
parser.add_argument('--min-popularity', type=int, default=50)
|
||||
parser.add_argument('--rounds', type=int, default=20)
|
||||
parser.add_argument('--puzzles-per-round', type=int, default=5)
|
||||
parser.add_argument('--random-seed', type=int, default=0)
|
||||
parser.add_argument('--puzzle-db', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
with args.puzzle_db.open(newline='') as f:
|
||||
puzzle_db = PuzzleDb.from_csv(f) \
|
||||
.filter(lambda p: p.num_plays >= args.min_plays) \
|
||||
.filter(lambda p: p.popularity >= args.min_popularity) \
|
||||
.sorted(key=lambda p: p.rating)
|
||||
|
||||
player = glicko2.Player()
|
||||
played_puzzles = set()
|
||||
random = Random(args.random_seed)
|
||||
|
||||
for current_round in range(1, args.rounds + 1):
|
||||
print(f'=== Round {current_round}/{args.rounds}, '
|
||||
f'current rating: {round(player.rating)} '
|
||||
f'(rd: {round(player.rd)}) ===')
|
||||
play_round(player, puzzle_db, args.puzzles_per_round,
|
||||
args.engine, args.timeout, played_puzzles, random)
|
||||
|
||||
print(f'Final rating: {round(player.rating)} (rd: {round(player.rd)})')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Reference in New Issue
Block a user