Merge branch 'dev' of gitlab.com:stax-river/poker-analytics into dev

feature/top10
Aurelien Hubert 7 years ago
commit 5d50a48fbf
  1. 107
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  2. 42
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  3. 8
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt

@ -27,7 +27,8 @@ class Calculator {
class Options(
display: Display = Display.TABLE,
evolutionValues: EvolutionValues = EvolutionValues.NONE,
stats: List<Stat> = listOf()
stats: List<Stat> = listOf(),
aggregationType: AggregationType? = null
) {
/**
@ -53,6 +54,7 @@ class Calculator {
var display: Display = display
var evolutionValues: EvolutionValues = evolutionValues
var displayedStats: List<Stat> = stats
var aggregationType: AggregationType? = aggregationType
/**
* This function determines whether the standard deviation should be computed
@ -80,6 +82,15 @@ class Calculator {
return this.displayedStats.contains(DAYS_PLAYED)
}
val evolutionForAggregatedValues: Boolean
get() {
if (this.aggregationType != null) {
return this.aggregationType == AggregationType.MONTH || this.aggregationType == AggregationType.YEAR
} else {
return false
}
}
}
companion object {
@ -91,7 +102,7 @@ class Calculator {
stats: List<Stat>? = null
): Report {
val options = Options(evolutionValues = Options.EvolutionValues.STANDARD)
val options = Options(evolutionValues = Options.EvolutionValues.STANDARD, aggregationType = aggregationType)
if (aggregationType == AggregationType.DURATION) {
options.evolutionValues = Options.EvolutionValues.TIMED
}
@ -121,6 +132,8 @@ class Calculator {
): Report {
val computableGroups: MutableList<ComputableGroup> = mutableListOf()
var previousGroup: ComputableGroup? = null
comparators.combined().forEach { comparatorConditions ->
val allConditions = mutableListOf<QueryCondition>()
@ -128,8 +141,10 @@ class Calculator {
allConditions.addAll(comparatorConditions)
val group = ComputableGroup(allConditions.name(), allConditions)
group.comparedGroup = previousGroup
computableGroups.add(group)
previousGroup = group
}
if (computableGroups.size == 0) {
@ -156,7 +171,7 @@ class Calculator {
val results: ComputedResults = this.compute(realm, group, options = options)
// Computes the compared sessionGroup if existing
val comparedGroup = group.comparedComputables
val comparedGroup = group.comparedGroup
if (comparedGroup != null) {
val comparedResults = this.compute(realm, comparedGroup, options = options)
group.comparedComputedResults = comparedResults
@ -180,29 +195,70 @@ class Calculator {
*/
fun compute(realm: Realm, computableGroup: ComputableGroup, options: Options): ComputedResults {
val results = ComputedResults(computableGroup)
val computables = computableGroup.computables(realm)
Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables")
results.addStat(NUMBER_OF_GAMES, computables.size.toDouble())
if (options.computeLongestStreak) {
computables.sort("session.startDate")
}
val results = ComputedResults(computableGroup)
val sum = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble()
results.addStat(NET_RESULT, sum)
val totalHands = computables.sum(ComputableResult.Field.ESTIMATED_HANDS.identifier).toDouble()
results.addStat(HANDS_PLAYED, totalHands)
val bbSum = computables.sum(ComputableResult.Field.BB_NET.identifier).toDouble()
results.addStat(BB_NET_RESULT, bbSum)
val bbSessionCount = computables.sum(ComputableResult.Field.HAS_BIG_BLIND.identifier).toInt()
results.addStat(BB_SESSION_COUNT, bbSessionCount.toDouble())
val winningSessionCount = computables.sum(ComputableResult.Field.IS_POSITIVE.identifier).toInt()
results.addStat(WINNING_SESSION_COUNT, winningSessionCount.toDouble())
val totalBuyin = computables.sum(ComputableResult.Field.RATED_BUYIN.identifier).toDouble()
results.addStat(TOTAL_BUYIN, totalBuyin)
val maxNetResult = computables.max(ComputableResult.Field.RATED_NET.identifier)?.toDouble()
maxNetResult?.let {
results.addStat(MAXIMUM_NETRESULT, it)
}
val minNetResult = computables.min(ComputableResult.Field.RATED_NET.identifier)?.toDouble()
minNetResult?.let {
results.addStat(MINIMUM_NETRESULT, it)
}
Stat.netBBPer100Hands(bbSum, totalHands)?.let { netBB100 ->
results.addStat(NET_BB_PER_100_HANDS, netBB100)
}
Stat.returnOnInvestment(sum, totalBuyin)?.let { roi ->
results.addStat(ROI, roi)
}
if (options.computeLocationsPlayed) {
results.addStat(LOCATIONS_PLAYED, computables.distinctBy { it.session?.location?.id }.size.toDouble())
}
var average = 0.0 // also used for standard deviation later
if (computables.size > 0) {
average = sum / computables.size.toDouble()
val winRatio = winningSessionCount.toDouble() / computables.size.toDouble()
val avgBuyin = totalBuyin / computables.size.toDouble()
results.addStats(
setOf(
ComputedStat(AVERAGE, average),
ComputedStat(WIN_RATIO, winRatio),
ComputedStat(AVERAGE_BUYIN, avgBuyin)
)
)
}
val shouldIterateOverComputables =
(options.evolutionValues == Options.EvolutionValues.STANDARD || options.computeLongestStreak)
@ -280,6 +336,7 @@ class Calculator {
}
val sessionSets = computableGroup.sessionSets(realm)
results.addStat(NUMBER_OF_SETS, sessionSets.size.toDouble())
var gHourlyDuration: Double? = null
var gBBSum: Double? = null
@ -394,23 +451,7 @@ class Calculator {
}
var average = 0.0
var hourlyRate = 0.0
if (computables.size > 0) {
average = sum / computables.size.toDouble()
val winRatio = winningSessionCount.toDouble() / computables.size.toDouble()
val avgBuyin = totalBuyin / computables.size
results.addStats(
setOf(
ComputedStat(AVERAGE, average),
ComputedStat(WIN_RATIO, winRatio),
ComputedStat(AVERAGE_BUYIN, avgBuyin)
)
)
}
if (gHourlyDuration != null) {
hourlyRate = sum / gHourlyDuration
@ -429,29 +470,6 @@ class Calculator {
results.addStat(AVERAGE_NET_BB, gBBSum / bbSessionCount)
}
// Create stats
results.addStats(
setOf(
ComputedStat(NET_RESULT, sum),
ComputedStat(NUMBER_OF_SETS, sessionSets.size.toDouble()),
ComputedStat(NUMBER_OF_GAMES, computables.size.toDouble()),
ComputedStat(HANDS_PLAYED, totalHands)
)
)
Stat.returnOnInvestment(sum, totalBuyin)?.let { roi ->
results.addStat(ROI, roi)
}
Stat.netBBPer100Hands(bbSum, totalHands)?.let { 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) // (milliseconds to hours)
}
@ -494,7 +512,6 @@ class Calculator {
}
}
class SSStats(sessionSet: SessionSet, conditions: List<QueryCondition>) { // Session Set Stats

@ -146,7 +146,7 @@ class ComputableGroup(name: String, conditions: List<QueryCondition> = listOf(),
/**
* A subgroup used to compute stat variation
*/
var comparedComputables: ComputableGroup? = null
var comparedGroup: ComputableGroup? = null
/**
* The computed stats of the comparable sessionGroup
@ -206,12 +206,40 @@ class ComputedResults(group: ComputableGroup) : StatEntry {
}
fun addStat(stat: Stat, value: Double, secondValue: Double? = null) {
this._computedStats[stat] = ComputedStat(stat, value, secondValue = secondValue)
val computedStat = ComputedStat(stat, value, secondValue = secondValue)
this.addComputedStat(computedStat)
}
fun addStats(computedStats: Set<ComputedStat>) {
computedStats.forEach {
this._computedStats[it.stat] = it
this.addComputedStat(it)
}
}
private fun addComputedStat(computedStat: ComputedStat) {
this.group.comparedComputedResults?.let { result ->
result.computedStat(computedStat.stat)?.let { previousComputedStat ->
val previousValue = previousComputedStat.secondValue ?: previousComputedStat.value
when (computedStat.stat) {
Stat.NET_RESULT, Stat.DURATION, Stat.BB_NET_RESULT -> {
computedStat.secondValue = previousValue + computedStat.value
}
}
}
}
this._computedStats[computedStat.stat] = computedStat
}
fun consolidateEvolutionStat() {
this.allStats().forEach { computedStat ->
when (computedStat.stat) {
}
}
}
@ -230,6 +258,9 @@ class ComputedResults(group: ComputableGroup) : StatEntry {
}
fun finalize(options: Calculator.Options) {
this.consolidateEvolutionStat()
if (options.evolutionValues != Calculator.Options.EvolutionValues.NONE) {
// Sort points as a distribution
@ -297,8 +328,9 @@ class ComputedResults(group: ComputableGroup) : StatEntry {
override val entryTitle: String = this.group.name
override fun formattedValue(stat: Stat, context: Context): TextFormat {
this.computedStat(stat)?.let {
return it.format(context)
this.computedStat(stat)?.secondValue?.let {
return stat.format(it, context = context)
// return it.format(context)
} ?: run {
throw IllegalStateException("Missing stat in results")
}

@ -56,6 +56,7 @@ enum class AggregationType {
enum class Stat : RowRepresentable {
NET_RESULT,
BB_NET_RESULT,
HOURLY_RATE,
AVERAGE,
NUMBER_OF_SETS,
@ -77,7 +78,10 @@ enum class Stat : RowRepresentable {
MAXIMUM_NETRESULT,
MINIMUM_NETRESULT,
MAXIMUM_DURATION,
DAYS_PLAYED
DAYS_PLAYED,
WINNING_SESSION_COUNT,
BB_SESSION_COUNT,
TOTAL_BUYIN,
;
/**
@ -112,6 +116,7 @@ enum class Stat : RowRepresentable {
get() {
return when (this) {
NET_RESULT -> R.string.net_result
BB_NET_RESULT -> R.string.total_net_result_bb_
HOURLY_RATE -> R.string.average_hour_rate
AVERAGE -> R.string.average
NUMBER_OF_SETS -> R.string.number_of_sessions
@ -134,6 +139,7 @@ enum class Stat : RowRepresentable {
MINIMUM_NETRESULT -> R.string.min_net_result
MAXIMUM_DURATION -> R.string.longest_session
DAYS_PLAYED -> R.string.days_played
else -> throw IllegalStateException("Stat ${this.name} name required but undefined")
}
}

Loading…
Cancel
Save