|
|
|
@ -8,8 +8,11 @@ import net.pokeranalytics.android.model.filter.QueryCondition |
|
|
|
import net.pokeranalytics.android.model.filter.name |
|
|
|
import net.pokeranalytics.android.model.filter.name |
|
|
|
import net.pokeranalytics.android.model.realm.ComputableResult |
|
|
|
import net.pokeranalytics.android.model.realm.ComputableResult |
|
|
|
import net.pokeranalytics.android.model.realm.SessionSet |
|
|
|
import net.pokeranalytics.android.model.realm.SessionSet |
|
|
|
|
|
|
|
import net.pokeranalytics.android.util.extensions.startOfDay |
|
|
|
import timber.log.Timber |
|
|
|
import timber.log.Timber |
|
|
|
import java.util.* |
|
|
|
import java.util.* |
|
|
|
|
|
|
|
import kotlin.math.max |
|
|
|
|
|
|
|
import kotlin.math.min |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The class performing stats computation |
|
|
|
* The class performing stats computation |
|
|
|
@ -62,7 +65,6 @@ class Calculator { |
|
|
|
return true |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// var aggregation: Aggregation? = null |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
companion object { |
|
|
|
@ -161,7 +163,12 @@ class Calculator { |
|
|
|
val computables = computableGroup.computables(realm) |
|
|
|
val computables = computableGroup.computables(realm) |
|
|
|
Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables") |
|
|
|
Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables") |
|
|
|
|
|
|
|
|
|
|
|
val results: ComputedResults = ComputedResults(computableGroup) |
|
|
|
val computeLongestStreak = options.displayedStats.contains(LONGEST_STREAKS) |
|
|
|
|
|
|
|
if (computeLongestStreak) { |
|
|
|
|
|
|
|
computables.sort("session.startDate") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val results = ComputedResults(computableGroup) |
|
|
|
|
|
|
|
|
|
|
|
val sum = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble() |
|
|
|
val sum = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble() |
|
|
|
val totalHands = computables.sum(ComputableResult.Field.ESTIMATED_HANDS.identifier).toDouble() |
|
|
|
val totalHands = computables.sum(ComputableResult.Field.ESTIMATED_HANDS.identifier).toDouble() |
|
|
|
@ -170,54 +177,85 @@ class Calculator { |
|
|
|
val winningSessionCount = computables.sum(ComputableResult.Field.IS_POSITIVE.identifier).toInt() |
|
|
|
val winningSessionCount = computables.sum(ComputableResult.Field.IS_POSITIVE.identifier).toInt() |
|
|
|
val totalBuyin = computables.sum(ComputableResult.Field.RATED_BUYIN.identifier).toDouble() |
|
|
|
val totalBuyin = computables.sum(ComputableResult.Field.RATED_BUYIN.identifier).toDouble() |
|
|
|
|
|
|
|
|
|
|
|
// Compute for each session |
|
|
|
val maxNetResult = computables.max(ComputableResult.Field.RATED_NET.identifier)?.toDouble() |
|
|
|
|
|
|
|
val minNetResult = computables.min(ComputableResult.Field.RATED_NET.identifier)?.toDouble() |
|
|
|
|
|
|
|
|
|
|
|
when (options.evolutionValues) { |
|
|
|
if (options.displayedStats.contains(LOCATIONS_PLAYED)) { |
|
|
|
Options.EvolutionValues.STANDARD -> { |
|
|
|
results.addStat(LOCATIONS_PLAYED, computables.distinctBy { it.session?.location?.id }.size.toDouble()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var index: Int = 0 |
|
|
|
val shouldIterateOverComputables = |
|
|
|
var tSum = 0.0 |
|
|
|
(options.evolutionValues == Options.EvolutionValues.STANDARD || computeLongestStreak) |
|
|
|
var tBBSum = 0.0 |
|
|
|
|
|
|
|
var tBBSessionCount = 0 |
|
|
|
// Iterate for each session |
|
|
|
var tWinningSessionCount = 0 |
|
|
|
if (shouldIterateOverComputables) { |
|
|
|
var tBuyinSum = 0.0 |
|
|
|
|
|
|
|
var tHands = 0.0 |
|
|
|
var index: Int = 0 |
|
|
|
|
|
|
|
var tSum = 0.0 |
|
|
|
computables.forEach { computable -> |
|
|
|
var tBBSum = 0.0 |
|
|
|
index++ |
|
|
|
var tBBSessionCount = 0 |
|
|
|
tSum += computable.ratedNet |
|
|
|
var tWinningSessionCount = 0 |
|
|
|
tBBSum += computable.bbNet |
|
|
|
var tBuyinSum = 0.0 |
|
|
|
tBBSessionCount += computable.hasBigBlind |
|
|
|
var tHands = 0.0 |
|
|
|
tWinningSessionCount += computable.isPositive |
|
|
|
var winStreak = 0; var loseStreak = 0; var currentStreak = 0 |
|
|
|
tBuyinSum += computable.ratedBuyin |
|
|
|
|
|
|
|
tHands += computable.estimatedHands |
|
|
|
computables.forEach { computable -> |
|
|
|
|
|
|
|
index++ |
|
|
|
val session = |
|
|
|
tSum += computable.ratedNet |
|
|
|
computable.session ?: throw IllegalStateException("Computing lone ComputableResult") |
|
|
|
tBBSum += computable.bbNet |
|
|
|
results.addEvolutionValue(tSum, stat = NETRESULT, data = session) |
|
|
|
tBBSessionCount += computable.hasBigBlind |
|
|
|
results.addEvolutionValue(tSum / index, stat = AVERAGE, data = session) |
|
|
|
tWinningSessionCount += computable.isPositive |
|
|
|
results.addEvolutionValue(index.toDouble(), stat = NUMBER_OF_GAMES, data = session) |
|
|
|
tBuyinSum += computable.ratedBuyin |
|
|
|
results.addEvolutionValue(tBBSum / tBBSessionCount, stat = AVERAGE_NET_BB, data = session) |
|
|
|
tHands += computable.estimatedHands |
|
|
|
results.addEvolutionValue( |
|
|
|
|
|
|
|
(tWinningSessionCount.toDouble() / index.toDouble()), |
|
|
|
if (computable.isPositive == 1) { |
|
|
|
stat = WIN_RATIO, |
|
|
|
if (currentStreak >= 0) { |
|
|
|
data = session |
|
|
|
currentStreak++ |
|
|
|
) |
|
|
|
} else { |
|
|
|
results.addEvolutionValue(tBuyinSum / index, stat = AVERAGE_BUYIN, data = session) |
|
|
|
currentStreak = 1 |
|
|
|
|
|
|
|
loseStreak = min(loseStreak, currentStreak) |
|
|
|
Stat.netBBPer100Hands(tBBSum, tHands)?.let { netBB100 -> |
|
|
|
|
|
|
|
results.addEvolutionValue(netBB100, stat = NET_BB_PER_100_HANDS, data = session) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
Stat.returnOnInvestment(tSum, tBuyinSum)?.let { roi -> |
|
|
|
if (computable.isPositive == 0) { |
|
|
|
results.addEvolutionValue(roi, stat = ROI, data = session) |
|
|
|
if (currentStreak <= 0) { |
|
|
|
|
|
|
|
currentStreak-- |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
currentStreak = -1 |
|
|
|
|
|
|
|
winStreak = max(winStreak, currentStreak) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val session = |
|
|
|
|
|
|
|
computable.session ?: throw IllegalStateException("Computing lone ComputableResult") |
|
|
|
|
|
|
|
results.addEvolutionValue(tSum, stat = NETRESULT, data = session) |
|
|
|
|
|
|
|
results.addEvolutionValue(tSum / index, stat = AVERAGE, data = session) |
|
|
|
|
|
|
|
results.addEvolutionValue(index.toDouble(), stat = NUMBER_OF_GAMES, data = session) |
|
|
|
|
|
|
|
results.addEvolutionValue(tBBSum / tBBSessionCount, stat = AVERAGE_NET_BB, data = session) |
|
|
|
|
|
|
|
results.addEvolutionValue( |
|
|
|
|
|
|
|
(tWinningSessionCount.toDouble() / index.toDouble()), |
|
|
|
|
|
|
|
stat = WIN_RATIO, |
|
|
|
|
|
|
|
data = session |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
results.addEvolutionValue(tBuyinSum / index, stat = AVERAGE_BUYIN, data = session) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stat.netBBPer100Hands(tBBSum, tHands)?.let { netBB100 -> |
|
|
|
|
|
|
|
results.addEvolutionValue(netBB100, stat = NET_BB_PER_100_HANDS, data = session) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stat.returnOnInvestment(tSum, tBuyinSum)?.let { roi -> |
|
|
|
|
|
|
|
results.addEvolutionValue(roi, stat = ROI, data = session) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else -> { |
|
|
|
|
|
|
|
// nothing |
|
|
|
if (currentStreak >= 0) { |
|
|
|
|
|
|
|
winStreak = max(winStreak, currentStreak) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
loseStreak = min(loseStreak, currentStreak) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
results.addStat(LONGEST_STREAKS, winStreak.toDouble(), loseStreak.toDouble()) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val sessionSets = computableGroup.sessionSets(realm) |
|
|
|
val sessionSets = computableGroup.sessionSets(realm) |
|
|
|
@ -228,6 +266,7 @@ class Calculator { |
|
|
|
val gSum = sessionSets.sum(SessionSet.Field.RATED_NET.identifier).toDouble() |
|
|
|
val gSum = sessionSets.sum(SessionSet.Field.RATED_NET.identifier).toDouble() |
|
|
|
val gTotalHands = sessionSets.sum(SessionSet.Field.ESTIMATED_HANDS.identifier).toDouble() |
|
|
|
val gTotalHands = sessionSets.sum(SessionSet.Field.ESTIMATED_HANDS.identifier).toDouble() |
|
|
|
val gBBSum = sessionSets.sum(SessionSet.Field.BB_NET.identifier).toDouble() |
|
|
|
val gBBSum = sessionSets.sum(SessionSet.Field.BB_NET.identifier).toDouble() |
|
|
|
|
|
|
|
val maxDuration = sessionSets.max(SessionSet.Field.NET_DURATION.identifier)?.toDouble() |
|
|
|
|
|
|
|
|
|
|
|
val hourlyRate = gSum / gHourlyDuration |
|
|
|
val hourlyRate = gSum / gHourlyDuration |
|
|
|
// var bbHourlyRate = gBBSum / gDuration |
|
|
|
// var bbHourlyRate = gBBSum / gDuration |
|
|
|
@ -242,6 +281,7 @@ class Calculator { |
|
|
|
var tBBSum = 0.0 |
|
|
|
var tBBSum = 0.0 |
|
|
|
var tHourlyRate = 0.0 |
|
|
|
var tHourlyRate = 0.0 |
|
|
|
var tHourlyRateBB = 0.0 |
|
|
|
var tHourlyRateBB = 0.0 |
|
|
|
|
|
|
|
val daysSet = mutableSetOf<Date>() |
|
|
|
|
|
|
|
|
|
|
|
sessionSets.forEach { sessionSet -> |
|
|
|
sessionSets.forEach { sessionSet -> |
|
|
|
tIndex++ |
|
|
|
tIndex++ |
|
|
|
@ -252,6 +292,7 @@ class Calculator { |
|
|
|
|
|
|
|
|
|
|
|
tHourlyRate = gSum / tHourlyDuration |
|
|
|
tHourlyRate = gSum / tHourlyDuration |
|
|
|
tHourlyRateBB = gBBSum / tHourlyDuration |
|
|
|
tHourlyRateBB = gBBSum / tHourlyDuration |
|
|
|
|
|
|
|
daysSet.add(sessionSet.startDate.startOfDay()) |
|
|
|
|
|
|
|
|
|
|
|
when (options.evolutionValues) { |
|
|
|
when (options.evolutionValues) { |
|
|
|
Options.EvolutionValues.STANDARD -> { |
|
|
|
Options.EvolutionValues.STANDARD -> { |
|
|
|
@ -308,6 +349,8 @@ class Calculator { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
results.addStat(DAYS_PLAYED, daysSet.size.toDouble()) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else -> { |
|
|
|
else -> { |
|
|
|
@ -350,15 +393,24 @@ class Calculator { |
|
|
|
ComputedStat(HOURLY_RATE_BB, gBBSum / gHourlyDuration), |
|
|
|
ComputedStat(HOURLY_RATE_BB, gBBSum / gHourlyDuration), |
|
|
|
ComputedStat(AVERAGE_NET_BB, gBBSum / bbSessionCount), |
|
|
|
ComputedStat(AVERAGE_NET_BB, gBBSum / bbSessionCount), |
|
|
|
ComputedStat(HANDS_PLAYED, totalHands) |
|
|
|
ComputedStat(HANDS_PLAYED, totalHands) |
|
|
|
|
|
|
|
|
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
Stat.returnOnInvestment(sum, totalBuyin)?.let { roi -> |
|
|
|
Stat.returnOnInvestment(sum, totalBuyin)?.let { roi -> |
|
|
|
results.addStats(setOf(ComputedStat(ROI, roi))) |
|
|
|
results.addStat(ROI, roi) |
|
|
|
} |
|
|
|
} |
|
|
|
Stat.netBBPer100Hands(bbSum, totalHands)?.let { netBB100 -> |
|
|
|
Stat.netBBPer100Hands(bbSum, totalHands)?.let { netBB100 -> |
|
|
|
results.addStats(setOf(ComputedStat(NET_BB_PER_100_HANDS, netBB100))) |
|
|
|
results.addStat(NET_BB_PER_100_HANDS, netBB100) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maxNetResult?.let { max -> |
|
|
|
|
|
|
|
results.addStat(MAXIMUM_NETRESULT, max) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
minNetResult?.let { min -> |
|
|
|
|
|
|
|
results.addStat(MINIMUM_NETRESULT, min) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
maxDuration?.let { maxd -> |
|
|
|
|
|
|
|
results.addStat(MAXIMUM_DURATION, maxd) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val bbPer100Hands = bbSum / totalHands * 100 |
|
|
|
val bbPer100Hands = bbSum / totalHands * 100 |
|
|
|
|