summaryrefslogtreecommitdiffstats
path: root/src/scheduler_brutal.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/scheduler_brutal.py')
-rw-r--r--src/scheduler_brutal.py78
1 files changed, 0 insertions, 78 deletions
diff --git a/src/scheduler_brutal.py b/src/scheduler_brutal.py
deleted file mode 100644
index f0bfe99..0000000
--- a/src/scheduler_brutal.py
+++ /dev/null
@@ -1,78 +0,0 @@
-from scheduler import Scheduler
-from card import Card
-from random import shuffle
-
-HISTORY_DEPTH = 8
-
-class SchedulerBrutal(Scheduler):
- """
- The brutal scheduler tracks how well the player has consolidated each card
- and also how often the card has been shown.
-
- Using this information, it prioritizes cards that have been shown less
- frequently and recently, which means the player will often see totally new
- cards in test sessions.
- """
- def __init__(self, cards: dict[str, Card], state: dict):
- self._cards = cards
- self._state = {}
-
- # Synchronise state with current card collection
- for id, card in self._cards.items():
- history = state.get(id, [None] * HISTORY_DEPTH)
-
- # Adjust history if depth has changed
- if len(history) > HISTORY_DEPTH:
- history = history[-HISTORY_DEPTH:]
- elif len(history) < HISTORY_DEPTH:
- history = ([None] * (HISTORY_DEPTH - len(history))) + history
-
- self._state[id] = history
-
- def practice(self, size: int) -> list[str]:
- return self._schedule(size)
-
- def test(self, size: int) -> list[str]:
- return self._schedule(size)
-
- def update(self, results: dict[str, int]) -> None:
- # Add card result to sliding window, or None if card was not shown
- self._state = {id: history[1:] + [results.get(id, None)]
- for id, history in self._state.items()}
-
- def getState(self) -> dict:
- return self._state
-
- @staticmethod
- def _consolidationIndex(history: list, weights: range) -> float:
- """
- Consolidation index is a measure of how well the player has guessed the card recently
- """
- relevant_history = [(h, w) for h, w in zip(history, weights) if h is not None]
- weighted_history = sum([h * w for h, w in relevant_history])
- total_weights = sum([w for h, w in relevant_history])
- return weighted_history / total_weights if total_weights > 0 else 0.0
-
- @staticmethod
- def _exposureIndex(history: list) -> float:
- """
- Exposure index is a measure of how much and how recently a card has been shown
- """
- return sum([i + 1 for i, h in enumerate(history) if h is not None])
-
- def _schedule(self, size: int) -> list[str]:
- weights = range(10, 10 + HISTORY_DEPTH)
- cards = [id for id, card in self._cards.items()]
-
- # First sort by consolidation index
- cards.sort(key=lambda id: SchedulerBrutal._consolidationIndex(self._state[id], weights))
-
- # Next sort by exposure index
- cards.sort(key=lambda id: SchedulerBrutal._exposureIndex(self._state[id]))
-
- # Return least exposed and least consolidated cards, shuffled
- cards = cards[0:size]
-
- shuffle(cards)
-
- return cards