@ -5,9 +5,11 @@ import net.pokeranalytics.android.calculus.Stat.*
import net.pokeranalytics.android.model.comparison.Comparator
import net.pokeranalytics.android.model.comparison.Comparator
import net.pokeranalytics.android.model.comparison.combined
import net.pokeranalytics.android.model.comparison.combined
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.filter.filter
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.model.realm.hourlyDuration
import net.pokeranalytics.android.util.extensions.startOfDay
import net.pokeranalytics.android.util.extensions.startOfDay
import timber.log.Timber
import timber.log.Timber
import java.util.*
import java.util.*
@ -65,9 +67,18 @@ class Calculator {
return false
return false
}
}
val computeLongestStreak = this . displayedStats . contains ( LONGEST _STREAKS )
val computeLongestStreak : Boolean
val computeLocationsPlayed = this . displayedStats . contains ( LOCATIONS _PLAYED )
get ( ) {
val computeDaysPlayed = this . displayedStats . contains ( DAYS _PLAYED )
return this . displayedStats . contains ( LONGEST _STREAKS )
}
val computeLocationsPlayed : Boolean
get ( ) {
return this . displayedStats . contains ( LOCATIONS _PLAYED )
}
val computeDaysPlayed : Boolean
get ( ) {
return this . displayedStats . contains ( DAYS _PLAYED )
}
}
}
@ -137,12 +148,12 @@ class Calculator {
group . cleanup ( )
group . cleanup ( )
// Computes actual sessionGroup stats
// Computes actual sessionGroup stats
val results : ComputedResults = Calculator . compute ( realm , group , options = options )
val results : ComputedResults = this . compute ( realm , group , options = options )
// Computes the compared sessionGroup if existing
// Computes the compared sessionGroup if existing
val comparedGroup = group . comparedComputables
val comparedGroup = group . comparedComputables
if ( comparedGroup != null ) {
if ( comparedGroup != null ) {
val comparedResults = Calculator . compute ( realm , comparedGroup , options = options )
val comparedResults = this . compute ( realm , comparedGroup , options = options )
group . comparedComputedResults = comparedResults
group . comparedComputedResults = comparedResults
results . computeStatVariations ( comparedResults )
results . computeStatVariations ( comparedResults )
}
}
@ -200,7 +211,9 @@ class Calculator {
var tWinningSessionCount = 0
var tWinningSessionCount = 0
var tBuyinSum = 0.0
var tBuyinSum = 0.0
var tHands = 0.0
var tHands = 0.0
var longestWinStreak = 0 ; var longestLoseStreak = 0 ; var currentStreak = 0
var longestWinStreak = 0 ;
var longestLoseStreak = 0 ;
var currentStreak = 0
computables . forEach { computable ->
computables . forEach { computable ->
index ++
index ++
@ -263,39 +276,49 @@ class Calculator {
val sessionSets = computableGroup . sessionSets ( realm )
val sessionSets = computableGroup . sessionSets ( realm )
// Compute for each serie
var gHourlyDuration : Double ? = null
val gHourlyDuration =
var gBBSum : Double ? = null
var maxDuration : Double ? = null
if ( computableGroup . conditions . size == 0 ) { // SessionSets are fine
gHourlyDuration =
sessionSets . sum ( SessionSet . Field . NET _DURATION . identifier ) . toDouble ( ) / 3600000 // (milliseconds to hours)
sessionSets . sum ( SessionSet . Field . NET _DURATION . identifier ) . toDouble ( ) / 3600000 // (milliseconds to hours)
val gSum = sessionSets . sum ( SessionSet . Field . RATED _NET . identifier ) . toDouble ( )
gBBSum = sessionSets . sum ( SessionSet . Field . BB _NET . identifier ) . toDouble ( )
val gTotalHands = sessionSets . sum ( SessionSet . Field . ESTIMATED _HANDS . 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
sessionSets . max ( SessionSet . Field . NET _DURATION . identifier ) ?. let {
// var bbHourlyRate = gBBSum / gDuration
maxDuration = it . toDouble ( ) / 3600000
}
}
val shouldIterateOverSets = ( options . evolutionValues != Options . EvolutionValues . NONE || options . computeDaysPlayed )
val shouldIterateOverSets = computableGroup . conditions . size > 0 ||
options . evolutionValues != Options . EvolutionValues . NONE ||
options . computeDaysPlayed
if ( shouldIterateOverSets ) {
if ( shouldIterateOverSets ) {
var tHourlyDuration = 0.0
var tHourlyDuration = 0.0
var tIndex = 0
var tIndex = 0
var tSum = 0.0
var tRatedNetSum = 0.0
var tTotalHands = 0.0
var tBBSum = 0.0
var tBBSum = 0.0
var tTotalHands = 0.0
var tHourlyRate = 0.0
var tHourlyRate = 0.0
var tHourlyRateBB = 0.0
var tHourlyRateBB = 0.0
val daysSet = mutableSetOf < Date > ( )
val daysSet = mutableSetOf < Date > ( )
var tMaxDuration = 0.0
sessionSets . forEach { sessionSet ->
sessionSets . forEach { sessionSet ->
tIndex ++
tIndex ++
tHourlyDuration += sessionSet . hourlyDuration
tSum += sessionSet . ratedNet
tTotalHands += sessionSet . estimatedHands
tBBSum += sessionSet . bbNet
tHourlyRate = gSum / tHourlyDuration
val setStats = SSStats ( realm , sessionSet , computableGroup . conditions )
tHourlyRateBB = gBBSum / tHourlyDuration
tRatedNetSum += setStats . ratedNet
tBBSum += setStats . bbSum
tHourlyDuration += setStats . hourlyDuration
tTotalHands += setStats . estimatedHands
tMaxDuration = max ( tMaxDuration , setStats . hourlyDuration )
tHourlyRate = tRatedNetSum / tHourlyDuration
tHourlyRateBB = tBBSum / tHourlyDuration
daysSet . add ( sessionSet . startDate . startOfDay ( ) )
daysSet . add ( sessionSet . startDate . startOfDay ( ) )
when ( options . evolutionValues ) {
when ( options . evolutionValues ) {
@ -314,13 +337,13 @@ class Calculator {
)
)
results . addEvolutionValue ( tHourlyRateBB , stat = HOURLY _RATE _BB , data = sessionSet )
results . addEvolutionValue ( tHourlyRateBB , stat = HOURLY _RATE _BB , data = sessionSet )
Stat . netBBPer100Hands ( gBBSum , g TotalHands) ?. let { netBB100 ->
Stat . netBBPer100Hands ( tBBSum , t TotalHands) ?. let { netBB100 ->
results . addEvolutionValue ( netBB100 , stat = NET _BB _PER _100 _HANDS , data = sessionSet )
results . addEvolutionValue ( netBB100 , stat = NET _BB _PER _100 _HANDS , data = sessionSet )
}
}
}
}
Options . EvolutionValues . TIMED -> {
Options . EvolutionValues . TIMED -> {
results . addEvolutionValue ( tSum , tHourlyDuration , NETRESULT , sessionSet )
results . addEvolutionValue ( tRatedNet Sum , tHourlyDuration , NETRESULT , sessionSet )
results . addEvolutionValue ( tHourlyRate , tHourlyDuration , HOURLY _RATE , sessionSet )
results . addEvolutionValue ( tHourlyRate , tHourlyDuration , HOURLY _RATE , sessionSet )
results . addEvolutionValue (
results . addEvolutionValue (
tIndex . toDouble ( ) ,
tIndex . toDouble ( ) ,
@ -342,7 +365,7 @@ class Calculator {
)
)
results . addEvolutionValue ( tHourlyRateBB , tHourlyDuration , HOURLY _RATE _BB , sessionSet )
results . addEvolutionValue ( tHourlyRateBB , tHourlyDuration , HOURLY _RATE _BB , sessionSet )
Stat . netBBPer100Hands ( gBBSum , g TotalHands) ?. let { netBB100 ->
Stat . netBBPer100Hands ( tBBSum , t TotalHands) ?. let { netBB100 ->
results . addEvolutionValue (
results . addEvolutionValue (
netBB100 ,
netBB100 ,
tHourlyDuration ,
tHourlyDuration ,
@ -351,14 +374,24 @@ class Calculator {
)
)
}
}
}
}
else -> {
// nothing
}
}
}
results . addStat ( DAYS _PLAYED , daysSet . size . toDouble ( ) )
results . addStat ( DAYS _PLAYED , daysSet . size . toDouble ( ) )
}
}
gHourlyDuration = tHourlyDuration
gBBSum = tBBSum
maxDuration = tMaxDuration
}
}
var average = 0.0
var average = 0.0
var hourlyRate = 0.0
if ( computables . size > 0 ) {
if ( computables . size > 0 ) {
average = sum / computables . size . toDouble ( )
average = sum / computables . size . toDouble ( )
val winRatio = winningSessionCount . toDouble ( ) / computables . size . toDouble ( )
val winRatio = winningSessionCount . toDouble ( ) / computables . size . toDouble ( )
@ -373,25 +406,30 @@ class Calculator {
)
)
}
}
if ( gHourlyDuration != null ) {
hourlyRate = sum / gHourlyDuration
if ( sessionSets . size > 0 ) {
if ( sessionSets . size > 0 ) {
val avgDuration = gHourlyDuration / sessionSets . size
val avgDuration = gHourlyDuration / sessionSets . size
results . addStats (
results . addStat ( HOURLY _RATE , hourlyRate )
setOf (
results . addStat ( AVERAGE _DURATION , avgDuration )
ComputedStat ( HOURLY _RATE , hourlyRate ) ,
}
ComputedStat ( AVERAGE _DURATION , avgDuration )
results . addStat ( DURATION , gHourlyDuration )
)
}
)
if ( gBBSum != null ) {
if ( gHourlyDuration != null ) {
results . addStat ( HOURLY _RATE _BB , gBBSum / gHourlyDuration )
}
results . addStat ( AVERAGE _NET _BB , gBBSum / bbSessionCount )
}
}
// Create stats
// Create stats
results . addStats (
results . addStats (
setOf (
setOf (
ComputedStat ( NETRESULT , sum ) ,
ComputedStat ( NETRESULT , sum ) ,
ComputedStat ( DURATION , gHourlyDuration ) ,
ComputedStat ( NUMBER _OF _SETS , sessionSets . size . toDouble ( ) ) ,
ComputedStat ( NUMBER _OF _SETS , sessionSets . size . toDouble ( ) ) ,
ComputedStat ( NUMBER _OF _GAMES , computables . size . toDouble ( ) ) ,
ComputedStat ( NUMBER _OF _GAMES , computables . size . toDouble ( ) ) ,
ComputedStat ( HOURLY _RATE _BB , gBBSum / gHourlyDuration ) ,
ComputedStat ( AVERAGE _NET _BB , gBBSum / bbSessionCount ) ,
ComputedStat ( HANDS _PLAYED , totalHands )
ComputedStat ( HANDS _PLAYED , totalHands )
)
)
)
)
@ -410,7 +448,7 @@ class Calculator {
results . addStat ( MINIMUM _NETRESULT , min )
results . addStat ( MINIMUM _NETRESULT , min )
}
}
maxDuration ?. let { maxd ->
maxDuration ?. let { maxd ->
results . addStat ( MAXIMUM _DURATION , maxd / 3600000 ) // (milliseconds to hours)
results . addStat ( MAXIMUM _DURATION , maxd ) // (milliseconds to hours)
}
}
val bbPer100Hands = bbSum / totalHands * 100
val bbPer100Hands = bbSum / totalHands * 100
@ -428,20 +466,22 @@ class Calculator {
val standardDeviation = Math . sqrt ( stdSum / computables . size )
val standardDeviation = Math . sqrt ( stdSum / computables . size )
val standardDeviationBBper100Hands = Math . sqrt ( stdBBper100HandsSum / computables . size )
val standardDeviationBBper100Hands = Math . sqrt ( stdBBper100HandsSum / computables . size )
results . addStat ( STANDARD _DEVIATION , standardDeviation )
results . addStat ( STANDARD _DEVIATION _BB _PER _100 _HANDS , standardDeviationBBper100Hands )
// Session Set
// Session Set
if ( gHourlyDuration != null ) {
var hourlyStdSum = 0.0
var hourlyStdSum = 0.0
sessionSets . forEach { set ->
sessionSets . forEach { set ->
hourlyStdSum += Math . pow ( set . hourlyRate - hourlyRate , 2.0 )
val ssStats = SSStats ( realm , set , computableGroup . conditions )
val sHourlyRate = ssStats . hourlyRate
hourlyStdSum += Math . pow ( sHourlyRate - hourlyRate , 2.0 )
}
}
val hourlyStandardDeviation = Math . sqrt ( hourlyStdSum / sessionSets . size )
val hourlyStandardDeviation = Math . sqrt ( hourlyStdSum / sessionSets . size )
results . addStats (
results . addStat ( STANDARD _DEVIATION _HOURLY , hourlyStandardDeviation )
setOf (
}
ComputedStat ( STANDARD _DEVIATION , standardDeviation ) ,
ComputedStat ( STANDARD _DEVIATION _HOURLY , hourlyStandardDeviation ) ,
ComputedStat ( STANDARD _DEVIATION _BB _PER _100 _HANDS , standardDeviationBBper100Hands )
)
)
}
}
return results
return results
@ -451,3 +491,46 @@ class Calculator {
}
}
class SSStats ( realm : Realm , sessionSet : SessionSet , conditions : List < QueryCondition > ) { // Session Set Stats
private var realm = realm
private var sessionSet = sessionSet
private var conditions = conditions
var hourlyDuration : Double = 0.0
var estimatedHands : Double = 0.0
var bbSum : Double = 0.0
var ratedNet : Double = 0.0
val hourlyRate : Double
get ( ) {
return this . ratedNet / this . hourlyDuration
}
init {
if ( sessionSet . sessions ?. size == 1 ) { // use precomputed values
this . initStatsWithSet ( sessionSet )
} else { // dynamically filter and compute subset
val setSessions = sessionSet . sessions !!
val filteredSessions = setSessions . filter ( realm , conditions )
if ( setSessions . size == filteredSessions . size ) {
this . initStatsWithSet ( sessionSet )
} else {
ratedNet = filteredSessions . sumByDouble { it . computableResult ?. ratedNet ?: 0.0 }
bbSum = filteredSessions . sumByDouble { it . bbNet }
hourlyDuration = filteredSessions . hourlyDuration
estimatedHands = filteredSessions . sumByDouble { it . estimatedHands }
}
}
}
private fun initStatsWithSet ( sessionSet : SessionSet ) {
ratedNet = sessionSet . ratedNet
bbSum = sessionSet . bbNet
hourlyDuration = sessionSet . hourlyDuration
estimatedHands = sessionSet . estimatedHands
}
}