# Path: modules/game/Player.py
# class Player(NamedTuple('Player', [
#     ('id', 'PlayerID'),
#     ('titled', bool),
#     ('engine', bool),
#     ('gamesPlayed', int)])):
# class PlayerBSONHandler:
# class PlayerDB(NamedTuple('PlayerDB', [
#         ('playerColl', 'Collection')
#     ])):
#     def fromJson(userData: Dict):
#     def reads(bson: Dict) -> Player:
#     def writes(player: Player) -> Dict:
#     def byId(self, playerId: PlayerID) -> Opt[Player]:
#     def byPlayerId(self, playerId: PlayerID) -> Opt[Player]:
#     def unmarkedByUserIds(self, playerIds: List[PlayerID]) -> List[Player]:
#     def engineSample(self, engine: bool, size: int) -> List[Player]:
#     def oldestNonEngine(self) -> Opt[Player]:
#     def byEngine(self, engine: bool = True) -> List[Player]:
#     def all(self) -> List[Player]:
#     def write(self, player: Player):
# 
# Path: modules/game/AnalysedGame.py
# class AnalysedGame(NamedTuple('AnalysedGame', [
#         ('id', AnalysedGameID),
#         ('playerId', PlayerID),
#         ('gameId', GameID),
#         ('analysedMoves', List[AnalysedMove])
#     ])):
# class GameAnalysedGame(NamedTuple('GameAnalysedGame', [
#         ('analysedGame', AnalysedGame),
#         ('game', Game)
#     ])):
# class AnalysedGameBSONHandler:
# class AnalysedGameDB(NamedTuple('AnalysedGameDB', [
#         ('analysedGameColl', Collection)
#     ])):
#     def new(gameId: GameID, colour: Colour, playerId: PlayerID, analysedMoves: List[AnalysedMove]):
#     def makeId(gameId: GameID, colour: Colour) -> AnalysedGameID:
#     def tensor(self, length: int = 60) -> AnalysedGameTensor:
#     def toJson(self):
#     def emtAverage(self) -> Number:
#     def wclAverage(self) -> Number:
#     def gameLength(self) -> int:
#     def emts(self) -> List[Emt]:
#     def emtSeconds(self) -> List[Number]:
#     def winningChances(self) -> List[Number]:
#     def winningChancesPercent(self) -> List[Number]:
#     def winningChancesLossPercent(self, usePV: bool = True) -> List[Number]:
#     def winningChancesLossByPV(self):
#     def ranks(self) -> List[TrueRank]:
#     def ambiguities(self) -> List[int]:
#     def length(self) -> int:
#     def ranksJSON(self) -> str:
#     def binnedSeconds(self, bins: int = 10) -> Dict:
#     def binnedLosses(self, bins: int = 10) -> Dict:
#     def binnedPVs(self, bins: int = 6) -> Dict:
#     def moveRankByTime(self) -> List[Dict]:
#     def moveRankByTimeJSON(self) -> str:
#     def lossByTime(self) -> List[Dict]:
#     def lossByTimeJSON(self) -> str:
#     def lossByRank(self) -> List[Dict]:
#     def lossByRankJSON(self) -> str:
# def round_sig(x, sig=2):
#     def length(self):
#     def tensor(self):
#     def reads(bson: Dict) -> AnalysedGame:
#     def writes(analysedGame: AnalysedGame) -> Dict:
#     def write(self, analysedGame: AnalysedGame):
#     def writeMany(self, analysedGames: List[AnalysedGame]):
#     def byPlayerId(self, playerId: PlayerID) -> List[AnalysedGame]:
#     def byPlayerIds(self, playerIds: List[PlayerID]) -> List[AnalysedGame]:
#     def byId(self, _id: AnalysedGameID) -> Opt[AnalysedGame]:
#     def byIds(self, ids: List[AnalysedGameID]) -> List[AnalysedGame]:
#     def allBatch(self, batch: int, batchSize: int = 500):
#     def byGameIdAndUserId(self, gameId: GameID, playerId: PlayerID) -> Opt[AnalysedGame]:
# 
# Path: modules/irwin/AnalysedGameModel.py
# class AnalysedGamePrediction(NamedTuple('AnalysedGamePrediction', [
#         ('game', GamePrediction),
#         ('lstmMoves', List[MovePrediction]),
#         ('isolatedMoves', List[MovePrediction])
#     ])):
#     @staticmethod
#     def fromTensor(tensor: ndarray, length: int):
#         return AnalysedGamePrediction(
#             game = int(100*tensor[0][0]),
#             lstmMoves = [int(100*i) for i in tensor[1][0][:length]],
#             isolatedMoves = [int(100*i) for i in tensor[2][0][:length]])
# 
#     def weightedMovePredictions(self) -> List[WeightedMovePrediction]:
#         return [int(0.5*(l + i)) for l, i in zip(self.lstmMoves, self.isolatedMoves)]
#     
#     def weightedGamePrediction(self) -> WeightedGamePrediction:
#         moveActivations = sorted(self.weightedMovePredictions(), reverse=True)
#         moveActivationsLen = len(moveActivations)
# 
#         nanToZero = lambda x: 0 if np.isnan(x) else x
# 
#         highest = nanToZero(np.average([i for i in moveActivations if i > 80]))
#         topX = np.average(moveActivations[:ceil(0.3*moveActivationsLen)])
#         topY = np.average(moveActivations[:ceil(0.9*moveActivationsLen)])
# 
#         return int(np.average([highest, topX, topY]))


from default_imports import *
from modules.game.Player import PlayerID
from modules.game.AnalysedGame import AnalysedGame, AnalysedGameID
from modules.irwin.AnalysedGameModel import AnalysedGamePrediction
from pymongo.collection import Collection




Prediction = NewType('Prediction', int)

class AnalysedGameActivation(NamedTuple('AnalysedGameActivation', [
        ('id', AnalysedGameID),
        ('playerId', PlayerID),
        ('engine', bool),
        ('length', int),

# Path: modules/game/Player.py
# class Player(NamedTuple('Player', [
#     ('id', 'PlayerID'),
#     ('titled', bool),
#     ('engine', bool),
#     ('gamesPlayed', int)])):
# class PlayerBSONHandler:
# class PlayerDB(NamedTuple('PlayerDB', [
#         ('playerColl', 'Collection')
#     ])):
#     def fromJson(userData: Dict):
#     def reads(bson: Dict) -> Player:
#     def writes(player: Player) -> Dict:
#     def byId(self, playerId: PlayerID) -> Opt[Player]:
#     def byPlayerId(self, playerId: PlayerID) -> Opt[Player]:
#     def unmarkedByUserIds(self, playerIds: List[PlayerID]) -> List[Player]:
#     def engineSample(self, engine: bool, size: int) -> List[Player]:
#     def oldestNonEngine(self) -> Opt[Player]:
#     def byEngine(self, engine: bool = True) -> List[Player]:
#     def all(self) -> List[Player]:
#     def write(self, player: Player):
# 
# Path: modules/game/AnalysedGame.py
# class AnalysedGame(NamedTuple('AnalysedGame', [
#         ('id', AnalysedGameID),
#         ('playerId', PlayerID),
#         ('gameId', GameID),
#         ('analysedMoves', List[AnalysedMove])
#     ])):
# class GameAnalysedGame(NamedTuple('GameAnalysedGame', [
#         ('analysedGame', AnalysedGame),
#         ('game', Game)
#     ])):
# class AnalysedGameBSONHandler:
# class AnalysedGameDB(NamedTuple('AnalysedGameDB', [
#         ('analysedGameColl', Collection)
#     ])):
#     def new(gameId: GameID, colour: Colour, playerId: PlayerID, analysedMoves: List[AnalysedMove]):
#     def makeId(gameId: GameID, colour: Colour) -> AnalysedGameID:
#     def tensor(self, length: int = 60) -> AnalysedGameTensor:
#     def toJson(self):
#     def emtAverage(self) -> Number:
#     def wclAverage(self) -> Number:
#     def gameLength(self) -> int:
#     def emts(self) -> List[Emt]:
#     def emtSeconds(self) -> List[Number]:
#     def winningChances(self) -> List[Number]:
#     def winningChancesPercent(self) -> List[Number]:
#     def winningChancesLossPercent(self, usePV: bool = True) -> List[Number]:
#     def winningChancesLossByPV(self):
#     def ranks(self) -> List[TrueRank]:
#     def ambiguities(self) -> List[int]:
#     def length(self) -> int:
#     def ranksJSON(self) -> str:
#     def binnedSeconds(self, bins: int = 10) -> Dict:
#     def binnedLosses(self, bins: int = 10) -> Dict:
#     def binnedPVs(self, bins: int = 6) -> Dict:
#     def moveRankByTime(self) -> List[Dict]:
#     def moveRankByTimeJSON(self) -> str:
#     def lossByTime(self) -> List[Dict]:
#     def lossByTimeJSON(self) -> str:
#     def lossByRank(self) -> List[Dict]:
#     def lossByRankJSON(self) -> str:
# def round_sig(x, sig=2):
#     def length(self):
#     def tensor(self):
#     def reads(bson: Dict) -> AnalysedGame:
#     def writes(analysedGame: AnalysedGame) -> Dict:
#     def write(self, analysedGame: AnalysedGame):
#     def writeMany(self, analysedGames: List[AnalysedGame]):
#     def byPlayerId(self, playerId: PlayerID) -> List[AnalysedGame]:
#     def byPlayerIds(self, playerIds: List[PlayerID]) -> List[AnalysedGame]:
#     def byId(self, _id: AnalysedGameID) -> Opt[AnalysedGame]:
#     def byIds(self, ids: List[AnalysedGameID]) -> List[AnalysedGame]:
#     def allBatch(self, batch: int, batchSize: int = 500):
#     def byGameIdAndUserId(self, gameId: GameID, playerId: PlayerID) -> Opt[AnalysedGame]:
# 
# Path: modules/irwin/AnalysedGameModel.py
# class AnalysedGamePrediction(NamedTuple('AnalysedGamePrediction', [
#         ('game', GamePrediction),
#         ('lstmMoves', List[MovePrediction]),
#         ('isolatedMoves', List[MovePrediction])
#     ])):
#     @staticmethod
#     def fromTensor(tensor: ndarray, length: int):
#         return AnalysedGamePrediction(
#             game = int(100*tensor[0][0]),
#             lstmMoves = [int(100*i) for i in tensor[1][0][:length]],
#             isolatedMoves = [int(100*i) for i in tensor[2][0][:length]])
# 
#     def weightedMovePredictions(self) -> List[WeightedMovePrediction]:
#         return [int(0.5*(l + i)) for l, i in zip(self.lstmMoves, self.isolatedMoves)]
#     
#     def weightedGamePrediction(self) -> WeightedGamePrediction:
#         moveActivations = sorted(self.weightedMovePredictions(), reverse=True)
#         moveActivationsLen = len(moveActivations)
# 
#         nanToZero = lambda x: 0 if np.isnan(x) else x
# 
#         highest = nanToZero(np.average([i for i in moveActivations if i > 80]))
#         topX = np.average(moveActivations[:ceil(0.3*moveActivationsLen)])
#         topY = np.average(moveActivations[:ceil(0.9*moveActivationsLen)])
# 
#         return int(np.average([highest, topX, topY]))


# Path: modules/irwin/training/AnalysedGameActivation.py
from default_imports import *
from modules.game.Player import PlayerID
from modules.game.AnalysedGame import AnalysedGame, AnalysedGameID
from modules.irwin.AnalysedGameModel import AnalysedGamePrediction
from pymongo.collection import Collection





Prediction = NewType('Prediction', int)

class AnalysedGameActivation(NamedTuple('AnalysedGameActivation', [
        ('id', AnalysedGameID),
        ('playerId', PlayerID),
        ('engine', bool),
        ('length', int),

        ('prediction', Prediction)]