Skip to content

Commit 3070d2b

Browse files
author
Pavel Perestoronin
committed
Opt: tweak arena defaults, add the new tool
1 parent 8822247 commit 3070d2b

File tree

6 files changed

+84
-8
lines changed

6 files changed

+84
-8
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## `master`
4+
5+
- **Оптимизация**: настройки арены по умолчанию, новая утилита для отладки
6+
37
## `3.4.0b1`
48

59
- **Исправление**: падение при переборе противников на арене

bestmobabot/arena.py

+74-2
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@
44

55
from __future__ import annotations
66

7+
import pickle
8+
from base64 import b85decode
79
from dataclasses import dataclass
810
from functools import total_ordering
911
from itertools import combinations, count, product
12+
from pathlib import Path
1013
from typing import Any, Callable, Dict, Iterable, List, MutableMapping, Optional, TypeVar
1114

15+
import click
1216
import numpy
1317
from loguru import logger
1418
from numpy import arange, ndarray, vstack
1519
from numpy.random import choice, permutation, randint
1620

21+
import bestmobabot.logging_
22+
from bestmobabot import constants
1723
from bestmobabot.constants import TEAM_SIZE
18-
from bestmobabot.dataclasses_ import BaseArenaEnemy, Hero, Loggable
24+
from bestmobabot.database import Database
25+
from bestmobabot.dataclasses_ import ArenaEnemy, BaseArenaEnemy, GrandArenaEnemy, Hero, Loggable
1926
from bestmobabot.itertools_ import CountDown, secretary_max, slices
2027
from bestmobabot.model import Model
2128

@@ -130,9 +137,13 @@ def __init__(
130137
self.solutions = numpy.array([[]])
131138

132139
def solve(self) -> ArenaSolution:
140+
self.initialize()
141+
return secretary_max(self.yield_solutions(), self.max_iterations, early_stop=self.early_stop)
142+
143+
def initialize(self) -> ArenaSolver:
133144
logger.debug('Generating initial solutions…')
134145
self.solutions = vstack([permutation(len(self.heroes)) for _ in range(self.n_keep_solutions)])
135-
return secretary_max(self.yield_solutions(), self.max_iterations, early_stop=self.early_stop)
146+
return self
136147

137148
def yield_solutions(self) -> Iterable[ArenaSolution]:
138149
"""
@@ -325,3 +336,64 @@ def reduce_grand_arena(y1: ndarray, y2: ndarray, y3: ndarray) -> ndarray:
325336
Gives probability to win at least two of three battles.
326337
"""
327338
return y1 * y2 * y3 + y1 * y2 * (1.0 - y3) + y2 * y3 * (1.0 - y1) + y1 * y3 * (1.0 - y2)
339+
340+
341+
# Tester.
342+
# ----------------------------------------------------------------------------------------------------------------------
343+
344+
@click.command()
345+
@click.option('verbosity', '-v', '--verbose', count=True, help='Increase verbosity.')
346+
def main(verbosity: int):
347+
"""Test the solver on the pre-dumped data."""
348+
bestmobabot.logging_.install_logging(verbosity)
349+
350+
logger.info('Loading the dumps…')
351+
with Database(constants.DATABASE_NAME) as db:
352+
model: Model = pickle.loads(b85decode(db['bot:model']))
353+
heroes: List[Hero] = pickle.loads((Path('dumps') / 'heroes.pkl').read_bytes())
354+
arena_enemies: List[ArenaEnemy] = pickle.loads((Path('dumps') / 'arena_enemies.pkl').read_bytes())
355+
grand_enemies: List[GrandArenaEnemy] = pickle.loads((Path('dumps') / 'grand_enemies.pkl').read_bytes())
356+
357+
logger.info('')
358+
for enemy in arena_enemies:
359+
solution = ArenaSolver(
360+
db={},
361+
model=model,
362+
user_clan_id=None,
363+
heroes=heroes,
364+
n_required_teams=1,
365+
max_iterations=0,
366+
n_keep_solutions=50,
367+
n_generate_solutions=100,
368+
n_generations_count_down=25,
369+
early_stop=0.95,
370+
get_enemies=list,
371+
friendly_clans=[],
372+
reduce_probabilities=reduce_normal_arena,
373+
callback=lambda: None,
374+
).initialize().solve_enemy(enemy)
375+
logger.info('{}', solution)
376+
377+
logger.info('')
378+
for enemy in grand_enemies:
379+
solution = ArenaSolver(
380+
db={},
381+
model=model,
382+
user_clan_id=None,
383+
heroes=heroes,
384+
n_required_teams=constants.N_GRAND_TEAMS,
385+
max_iterations=0,
386+
n_keep_solutions=50,
387+
n_generate_solutions=500,
388+
n_generations_count_down=50,
389+
early_stop=0.95,
390+
get_enemies=list,
391+
friendly_clans=[],
392+
reduce_probabilities=reduce_grand_arena,
393+
callback=lambda: None,
394+
).initialize().solve_enemy(enemy)
395+
logger.info('{}', solution)
396+
397+
398+
if __name__ == '__main__':
399+
main()

bestmobabot/settings.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ class ArenaSettings(BaseModel):
3131

3232
# Normal arena.
3333
normal_max_pages: conint(ge=1) = 15 # maximal number of pages during normal enemy search
34-
normal_generations_count_down: conint(ge=1) = 5
35-
normal_generate_solutions: conint(ge=1) = 750
36-
normal_keep_solutions: conint(ge=1) = 250
34+
normal_generations_count_down: conint(ge=1) = 25
35+
normal_generate_solutions: conint(ge=1) = 100
36+
normal_keep_solutions: conint(ge=1) = 50
3737

3838
# Grand arena.
3939
grand_max_pages: conint(ge=1) = 15 # maximal number of pages during grand enemy search
40-
grand_generations_count_down: conint(ge=1) = 25 # maximum number of GA iterations without any improvement
41-
grand_generate_solutions: conint(ge=1) = 1250
42-
grand_keep_solutions: conint(ge=1) = 250
40+
grand_generations_count_down: conint(ge=1) = 50 # maximum number of GA iterations without any improvement
41+
grand_generate_solutions: conint(ge=1) = 500
42+
grand_keep_solutions: conint(ge=1) = 50
4343
randomize_grand_defenders: bool = False
4444

4545

dumps/arena_enemies.pkl

2.33 KB
Binary file not shown.

dumps/grand_enemies.pkl

4.93 KB
Binary file not shown.

dumps/heroes.pkl

8.98 KB
Binary file not shown.

0 commit comments

Comments
 (0)