|
|
|
|
@ -1,5 +1,8 @@ |
|
|
|
|
package net.pokeranalytics.android.calculus |
|
|
|
|
|
|
|
|
|
import android.os.Parcel |
|
|
|
|
import android.os.Parcelable |
|
|
|
|
import io.realm.Realm |
|
|
|
|
import net.pokeranalytics.android.calculus.Stat.* |
|
|
|
|
import net.pokeranalytics.android.model.realm.ComputableResult |
|
|
|
|
import net.pokeranalytics.android.model.realm.Filter |
|
|
|
|
@ -7,6 +10,31 @@ import net.pokeranalytics.android.model.realm.SessionSet |
|
|
|
|
import timber.log.Timber |
|
|
|
|
import java.util.* |
|
|
|
|
|
|
|
|
|
class ParcelableString(var string: String) : Parcelable { |
|
|
|
|
constructor(parcel: Parcel) : this(parcel.readString()) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun writeToParcel(parcel: Parcel, flags: Int) { |
|
|
|
|
parcel.writeString(string) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun describeContents(): Int { |
|
|
|
|
return 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
companion object CREATOR : Parcelable.Creator<ParcelableString> { |
|
|
|
|
override fun createFromParcel(parcel: Parcel): ParcelableString { |
|
|
|
|
return ParcelableString(parcel) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun newArray(size: Int): Array<ParcelableString?> { |
|
|
|
|
return arrayOfNulls(size) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The class performing stats computation |
|
|
|
|
*/ |
|
|
|
|
@ -59,35 +87,39 @@ class Calculator { |
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
|
|
|
|
|
fun computeStatsWithFilters(filters: List<Filter>, options: Options): List<ComputedResults> { |
|
|
|
|
fun computeStatsWithFilters(realm: Realm, filters: List<Filter>, options: Options): List<ComputedResults> { |
|
|
|
|
|
|
|
|
|
var computableGroups: MutableList<ComputableGroup> = mutableListOf() |
|
|
|
|
filters.forEach { filter -> |
|
|
|
|
|
|
|
|
|
val results = filter.results<ComputableResult>() |
|
|
|
|
val sets = filter.results<SessionSet>() |
|
|
|
|
val group = ComputableGroup(filter.name, results, sets) |
|
|
|
|
val group = ComputableGroup(filter.name, filter.filterConditions.map { it.queryCondition }) |
|
|
|
|
computableGroups.add(group) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
return Calculator.computeGroups(computableGroups, options) |
|
|
|
|
return Calculator.computeGroups(realm, computableGroups, options) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Computes all stats for list of Session sessionGroup |
|
|
|
|
*/ |
|
|
|
|
fun computeGroups(groups: List<ComputableGroup>, options: Options): List<ComputedResults> { |
|
|
|
|
fun computeGroups(realm: Realm, groups: List<ComputableGroup>, options: Options): List<ComputedResults> { |
|
|
|
|
|
|
|
|
|
val computedResults = mutableListOf<ComputedResults>() |
|
|
|
|
groups.forEach { group -> |
|
|
|
|
val s = Date() |
|
|
|
|
|
|
|
|
|
// Clean existing computables / sessionSets if group is reused |
|
|
|
|
group.cleanup() |
|
|
|
|
|
|
|
|
|
// Computes actual sessionGroup stats |
|
|
|
|
val results: ComputedResults = Calculator.compute(group, options = options) |
|
|
|
|
val results: ComputedResults = Calculator.compute(realm, group, options = options) |
|
|
|
|
|
|
|
|
|
// Computes the compared sessionGroup if existing |
|
|
|
|
val comparedGroup = group.comparedComputables |
|
|
|
|
if (comparedGroup != null) { |
|
|
|
|
val comparedResults = Calculator.compute(comparedGroup, options = options) |
|
|
|
|
val comparedResults = Calculator.compute(realm, comparedGroup, options = options) |
|
|
|
|
group.comparedComputedResults = comparedResults |
|
|
|
|
results.computeStatVariations(comparedResults) |
|
|
|
|
} |
|
|
|
|
@ -107,11 +139,10 @@ class Calculator { |
|
|
|
|
/** |
|
|
|
|
* Computes stats for a SessionSet |
|
|
|
|
*/ |
|
|
|
|
fun compute(computableGroup: ComputableGroup, options: Options): ComputedResults { |
|
|
|
|
|
|
|
|
|
Timber.d(">>>> Start computing group ${computableGroup.name}, ${computableGroup.computables.size} computables") |
|
|
|
|
fun compute(realm: Realm, computableGroup: ComputableGroup, options: Options): ComputedResults { |
|
|
|
|
|
|
|
|
|
val computables = computableGroup.computables |
|
|
|
|
val computables = computableGroup.computables(realm) |
|
|
|
|
Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables") |
|
|
|
|
|
|
|
|
|
val results: ComputedResults = ComputedResults(computableGroup) |
|
|
|
|
|
|
|
|
|
@ -135,30 +166,29 @@ class Calculator { |
|
|
|
|
var tBuyinSum = 0.0 |
|
|
|
|
var tHands = 0.0 |
|
|
|
|
|
|
|
|
|
computables.forEach { s -> |
|
|
|
|
computables.forEach { computable -> |
|
|
|
|
index++ |
|
|
|
|
tSum += s.ratedNet |
|
|
|
|
tBBSum += s.bbNet |
|
|
|
|
tBBSessionCount += s.hasBigBlind |
|
|
|
|
tWinningSessionCount += s.isPositive |
|
|
|
|
tBuyinSum += s.ratedBuyin |
|
|
|
|
tHands += s.estimatedHands |
|
|
|
|
tSum += computable.ratedNet |
|
|
|
|
tBBSum += computable.bbNet |
|
|
|
|
tBBSessionCount += computable.hasBigBlind |
|
|
|
|
tWinningSessionCount += computable.isPositive |
|
|
|
|
tBuyinSum += computable.ratedBuyin |
|
|
|
|
tHands += computable.estimatedHands |
|
|
|
|
|
|
|
|
|
results.addEvolutionValue(tSum, NETRESULT, s) |
|
|
|
|
results.addEvolutionValue(tSum / index, AVERAGE, s) |
|
|
|
|
results.addEvolutionValue(index.toDouble(), NUMBER_OF_GAMES, s) |
|
|
|
|
results.addEvolutionValue(tBBSum / tBBSessionCount, AVERAGE_NET_BB, s) |
|
|
|
|
results.addEvolutionValue((tWinningSessionCount / index).toDouble(), WIN_RATIO, s) |
|
|
|
|
results.addEvolutionValue(tBuyinSum / index, AVERAGE_BUYIN, s) |
|
|
|
|
val sessionId = ParcelableString(computable.session?.id ?: throw IllegalStateException("Computing lone ComputableResult")) |
|
|
|
|
results.addEvolutionValue(tSum, NETRESULT, sessionId) |
|
|
|
|
results.addEvolutionValue(tSum / index, AVERAGE, sessionId) |
|
|
|
|
results.addEvolutionValue(index.toDouble(), NUMBER_OF_GAMES, sessionId) |
|
|
|
|
results.addEvolutionValue(tBBSum / tBBSessionCount, AVERAGE_NET_BB, sessionId) |
|
|
|
|
results.addEvolutionValue((tWinningSessionCount / index).toDouble(), WIN_RATIO, sessionId) |
|
|
|
|
results.addEvolutionValue(tBuyinSum / index, AVERAGE_BUYIN, sessionId) |
|
|
|
|
|
|
|
|
|
val netBB100 = Stat.netBBPer100Hands(tBBSum, tHands) |
|
|
|
|
if (netBB100 != null) { |
|
|
|
|
results.addEvolutionValue(netBB100, NET_BB_PER_100_HANDS, s) |
|
|
|
|
Stat.netBBPer100Hands(tBBSum, tHands)?.let { netBB100 -> |
|
|
|
|
results.addEvolutionValue(netBB100, NET_BB_PER_100_HANDS, sessionId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val roi = Stat.returnOnInvestment(tSum, tBuyinSum) |
|
|
|
|
if (roi != null) { |
|
|
|
|
results.addEvolutionValue(roi, ROI, s) |
|
|
|
|
Stat.returnOnInvestment(tSum, tBuyinSum)?.let { roi -> |
|
|
|
|
results.addEvolutionValue(roi, ROI, sessionId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
@ -168,7 +198,7 @@ class Calculator { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val sessionSets = computableGroup.sets |
|
|
|
|
val sessionSets = computableGroup.sessionSets(realm) |
|
|
|
|
|
|
|
|
|
// Compute for each serie |
|
|
|
|
val gHourlyDuration = |
|
|
|
|
@ -201,20 +231,19 @@ class Calculator { |
|
|
|
|
tHourlyRate = gSum / tHourlyDuration |
|
|
|
|
tHourlyRateBB = gBBSum / tHourlyDuration |
|
|
|
|
|
|
|
|
|
results.addEvolutionValue(tSum, tHourlyDuration, NETRESULT, sessionSet) |
|
|
|
|
results.addEvolutionValue(tSum / tHourlyDuration, tHourlyDuration, HOURLY_RATE, sessionSet) |
|
|
|
|
results.addEvolutionValue(tHourlyRate, tHourlyDuration, HOURLY_RATE, sessionSet) |
|
|
|
|
results.addEvolutionValue(tIndex.toDouble(), tHourlyDuration, NUMBER_OF_SETS, sessionSet) |
|
|
|
|
results.addEvolutionValue(sessionSet.netDuration.toDouble(), tHourlyDuration, DURATION, sessionSet) |
|
|
|
|
results.addEvolutionValue(tHourlyDuration / tIndex, tHourlyDuration, AVERAGE_DURATION, sessionSet) |
|
|
|
|
results.addEvolutionValue(tHourlyRateBB, tHourlyDuration, HOURLY_RATE_BB, sessionSet) |
|
|
|
|
val id = ParcelableString(sessionSet.id) |
|
|
|
|
results.addEvolutionValue(tSum, tHourlyDuration, NETRESULT, id) |
|
|
|
|
results.addEvolutionValue(tSum / tHourlyDuration, tHourlyDuration, HOURLY_RATE, id) |
|
|
|
|
results.addEvolutionValue(tHourlyRate, tHourlyDuration, HOURLY_RATE, id) |
|
|
|
|
results.addEvolutionValue(tIndex.toDouble(), tHourlyDuration, NUMBER_OF_SETS, id) |
|
|
|
|
results.addEvolutionValue(sessionSet.netDuration.toDouble(), tHourlyDuration, DURATION, id) |
|
|
|
|
results.addEvolutionValue(tHourlyDuration / tIndex, tHourlyDuration, AVERAGE_DURATION, id) |
|
|
|
|
results.addEvolutionValue(tHourlyRateBB, tHourlyDuration, HOURLY_RATE_BB, id) |
|
|
|
|
|
|
|
|
|
val netBB100 = Stat.netBBPer100Hands(gBBSum, gTotalHands) |
|
|
|
|
if (netBB100 != null) { |
|
|
|
|
results.addEvolutionValue(netBB100, tHourlyDuration, NET_BB_PER_100_HANDS, sessionSet) |
|
|
|
|
} else { //@todo maybe not |
|
|
|
|
results.addEvolutionValue(0.0, tHourlyDuration, NET_BB_PER_100_HANDS, sessionSet) |
|
|
|
|
Stat.netBBPer100Hands(gBBSum, gTotalHands)?.let { netBB100 -> |
|
|
|
|
results.addEvolutionValue(netBB100, tHourlyDuration, NET_BB_PER_100_HANDS, id) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else -> { |
|
|
|
|
@ -261,13 +290,10 @@ class Calculator { |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
val roi = Stat.returnOnInvestment(sum, totalBuyin) |
|
|
|
|
val netBB100 = Stat.netBBPer100Hands(bbSum, totalHands) |
|
|
|
|
|
|
|
|
|
if (roi != null) { |
|
|
|
|
Stat.returnOnInvestment(sum, totalBuyin)?.let { roi -> |
|
|
|
|
results.addStats(setOf(ComputedStat(ROI, roi))) |
|
|
|
|
} |
|
|
|
|
if (netBB100 != null) { |
|
|
|
|
Stat.netBBPer100Hands(bbSum, totalHands)?.let { netBB100 -> |
|
|
|
|
results.addStats(setOf(ComputedStat(NET_BB_PER_100_HANDS, netBB100))) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|