parent
a6230736a7
commit
4b10acce58
@ -0,0 +1,169 @@ |
|||||||
|
package net.pokeranalytics.android |
||||||
|
|
||||||
|
import java.util.* |
||||||
|
|
||||||
|
class Session(bankroll: Bankroll, timeFrame: TimeFrame) { |
||||||
|
|
||||||
|
// A comment written by the user |
||||||
|
var comment: String? = null |
||||||
|
|
||||||
|
// The date of creation of the session |
||||||
|
var creationDate: Date = Date() |
||||||
|
|
||||||
|
var limit: Int? = null |
||||||
|
var game: Game? = null |
||||||
|
var numberOfTables: Int = 1 |
||||||
|
var tableSize: Int? = null |
||||||
|
|
||||||
|
var bankroll: Bankroll = bankroll |
||||||
|
|
||||||
|
var hands: List<HandHistory> = listOf() |
||||||
|
|
||||||
|
var timeFrame: TimeFrame = timeFrame |
||||||
|
|
||||||
|
var location: Location? = null |
||||||
|
|
||||||
|
var result: Result = Result() |
||||||
|
|
||||||
|
var opponents: List<Player> = listOf() |
||||||
|
|
||||||
|
// @todo serie |
||||||
|
|
||||||
|
// @todo cash game blind: 2/5/10, short deck ante, big bets in fixed limit |
||||||
|
|
||||||
|
// Tournament |
||||||
|
|
||||||
|
var entryFee: Double? = null |
||||||
|
var numberOfPlayers: Int? = null |
||||||
|
|
||||||
|
// @todo tournament type? |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class TimeFrame { |
||||||
|
|
||||||
|
var startDate: Date = Date() |
||||||
|
var endDate: Date? = null |
||||||
|
|
||||||
|
var breakDuration: Double = 0.0 |
||||||
|
var duration: Double = 0.0 |
||||||
|
var paused: Boolean = false |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
open class TimeFrameGroup(timeFrame: TimeFrame) { |
||||||
|
var timeFrame: TimeFrame = timeFrame |
||||||
|
var timeFrames: List<TimeFrame> = listOf() |
||||||
|
} |
||||||
|
|
||||||
|
class Serie(timeFrame: TimeFrame) : TimeFrameGroup(timeFrame) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class Result { |
||||||
|
var buyin: Double? = null |
||||||
|
var cashout: Double? = null |
||||||
|
var netResult: Double? = null |
||||||
|
var net: Double? = null |
||||||
|
|
||||||
|
var transactions: List<Transaction> = listOf() |
||||||
|
|
||||||
|
// @todo tips? |
||||||
|
|
||||||
|
var finalPosition: Int? = null |
||||||
|
|
||||||
|
// var player: Player? = null |
||||||
|
} |
||||||
|
|
||||||
|
class Bankroll(name: String) { |
||||||
|
|
||||||
|
var live: Boolean = true |
||||||
|
var name: String = name |
||||||
|
var transactions: List<Transaction> = listOf() |
||||||
|
var currency: Currency? = null |
||||||
|
|
||||||
|
// @todo rate management |
||||||
|
} |
||||||
|
|
||||||
|
class Currency { |
||||||
|
var code: String? = null |
||||||
|
var rate: Double? = null |
||||||
|
} |
||||||
|
|
||||||
|
class Transaction(value: Double, type: TransactionType) { |
||||||
|
var value: Double = value |
||||||
|
var date: Date = Date() |
||||||
|
var comment: String? = null |
||||||
|
var type: TransactionType = type |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
enum class TransactionKind { |
||||||
|
WITHDRAWAL, |
||||||
|
DEPOSIT |
||||||
|
} |
||||||
|
|
||||||
|
class TransactionType(name: String) { |
||||||
|
var name: String = name |
||||||
|
var additive: Boolean = false |
||||||
|
var lock: Boolean = false |
||||||
|
var kind: TransactionKind? = null |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class Game(name: String) { |
||||||
|
var name: String = name |
||||||
|
var shortName: String? = null |
||||||
|
} |
||||||
|
|
||||||
|
class Location(name: String) { |
||||||
|
var name: String = name |
||||||
|
var longitude: Double? = null |
||||||
|
var latitude: Double? = null |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class TournamentType(name: String) { |
||||||
|
var name: String = name |
||||||
|
} |
||||||
|
|
||||||
|
class Player {} |
||||||
|
|
||||||
|
enum class ReportDisplay { |
||||||
|
TABLE, |
||||||
|
GRAPH, |
||||||
|
MAP |
||||||
|
} |
||||||
|
|
||||||
|
class Report(name: String) { |
||||||
|
var name: String = name |
||||||
|
var display: ReportDisplay = ReportDisplay.TABLE |
||||||
|
|
||||||
|
// @todo define the configuration options |
||||||
|
|
||||||
|
var comparators: List<Int> = listOf() |
||||||
|
var stats: List<Int> = listOf() |
||||||
|
var filters: List<Filter> = listOf() |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class Filter(name: String) { |
||||||
|
var name: String = name |
||||||
|
var usageCount: Int = 0 |
||||||
|
var components: List<FilterComponent> = listOf() |
||||||
|
} |
||||||
|
|
||||||
|
class FilterComponent { |
||||||
|
// @todo how to store sub-filters? |
||||||
|
} |
||||||
|
|
||||||
|
class HandHistory { |
||||||
|
// @todo |
||||||
|
} |
||||||
|
|
||||||
|
class CustomField { |
||||||
|
// @todo |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
package net.pokeranalytics.android.calculus |
||||||
|
|
||||||
|
class AggregationParameter<T> { |
||||||
|
var values: List<T>? = null |
||||||
|
} |
||||||
|
|
||||||
|
class Aggregator { |
||||||
|
|
||||||
|
var parameters: List<AggregationParameter<*>> = listOf() |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
@ -0,0 +1,109 @@ |
|||||||
|
package net.pokeranalytics.android.calculus |
||||||
|
|
||||||
|
import net.pokeranalytics.android.Serie |
||||||
|
|
||||||
|
|
||||||
|
class Calculator { |
||||||
|
|
||||||
|
class Options { |
||||||
|
|
||||||
|
enum class Display { |
||||||
|
TABLE, |
||||||
|
EVOLUTION, |
||||||
|
COMPARISON, |
||||||
|
MAP, |
||||||
|
POLYNOMIAL |
||||||
|
} |
||||||
|
|
||||||
|
enum class EvolutionValues { |
||||||
|
NONE, |
||||||
|
STANDARD, |
||||||
|
DATED |
||||||
|
} |
||||||
|
|
||||||
|
var display: Display = Display.TABLE |
||||||
|
var evolutionValues: EvolutionValues = EvolutionValues.NONE |
||||||
|
var displayedStats: List<Stat> = listOf() |
||||||
|
|
||||||
|
// var aggregation: Aggregation? = null |
||||||
|
} |
||||||
|
|
||||||
|
companion object { |
||||||
|
|
||||||
|
fun computePreAggregation(groups: List<SessionGroup>, options: Options): List<ComputedGroup> { |
||||||
|
return listOf() |
||||||
|
} |
||||||
|
|
||||||
|
// Computes all stats for list of Session group |
||||||
|
fun computeGroups(groups: List<SessionGroup>, options: Options): List<ComputedGroup> { |
||||||
|
|
||||||
|
var computedGroups: MutableList<ComputedGroup> = mutableListOf() |
||||||
|
groups.forEach { group -> |
||||||
|
// Computes actual group stats |
||||||
|
val results: ComputedResults = Calculator.compute(group, options = options) |
||||||
|
|
||||||
|
// Computes the compared group if existing |
||||||
|
val comparedGroup = group.comparedGroup |
||||||
|
if (comparedGroup != null) { |
||||||
|
val comparedResults = Calculator.compute(comparedGroup, options = options) |
||||||
|
group.comparedComputedGroup = ComputedGroup(comparedGroup, comparedResults) |
||||||
|
|
||||||
|
results.computeStatVariations(comparedResults) |
||||||
|
} |
||||||
|
|
||||||
|
results.finalize(options) |
||||||
|
computedGroups.add(ComputedGroup(group, results)) |
||||||
|
} |
||||||
|
|
||||||
|
return computedGroups |
||||||
|
} |
||||||
|
|
||||||
|
// Computes stats for a SessionGroup |
||||||
|
fun compute(group: SessionGroup, options: Options) : ComputedResults { |
||||||
|
|
||||||
|
val sessions: List<SessionInterface> = group.sessionGroup |
||||||
|
val series: Set<Serie> = setOf() // @todo get unique list of serie |
||||||
|
var results: ComputedResults = ComputedResults() |
||||||
|
|
||||||
|
var sum: Double = 0.0 |
||||||
|
var duration: Double = 0.0 |
||||||
|
// @todo add all stats |
||||||
|
|
||||||
|
// Compute for each session |
||||||
|
sessions.forEach { item -> |
||||||
|
sum += item.value |
||||||
|
|
||||||
|
when (options.evolutionValues) { |
||||||
|
Options.EvolutionValues.STANDARD -> { |
||||||
|
results.addEvolutionValue(sum, Stat.NETRESULT) |
||||||
|
} |
||||||
|
Options.EvolutionValues.DATED -> { |
||||||
|
results.addEvolutionValue(sum, duration, Stat.NETRESULT) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Compute for each serie |
||||||
|
series.forEach { serie -> |
||||||
|
duration += serie.timeFrame.duration |
||||||
|
|
||||||
|
if (options.evolutionValues != Options.EvolutionValues.NONE) { |
||||||
|
results.addEvolutionValue(duration, Stat.DURATION) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Create stats |
||||||
|
results.addStats(setOf( |
||||||
|
ComputedStat(Stat.NETRESULT, sum), |
||||||
|
ComputedStat(Stat.AVERAGE,sum / sessions.size), |
||||||
|
ComputedStat(Stat.DURATION, duration) |
||||||
|
)) |
||||||
|
|
||||||
|
return results |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,111 @@ |
|||||||
|
package net.pokeranalytics.android.calculus |
||||||
|
|
||||||
|
import net.pokeranalytics.android.Serie |
||||||
|
|
||||||
|
// An interface to describe objects that can be summed |
||||||
|
interface Summable { |
||||||
|
var value: Double |
||||||
|
} |
||||||
|
|
||||||
|
// An interface describing some class that can be computed |
||||||
|
interface SessionInterface : Summable { |
||||||
|
var serie: Serie |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* A group of computable items identified by a name |
||||||
|
*/ |
||||||
|
class SessionGroup(name: String, sessions: List<SessionInterface>) { |
||||||
|
|
||||||
|
var name: String = name |
||||||
|
var sessionGroup: List<SessionInterface> = sessions |
||||||
|
|
||||||
|
// A subgroup used to compute stat variation |
||||||
|
var comparedGroup: SessionGroup? = null |
||||||
|
|
||||||
|
// The computed stats of the comparable group |
||||||
|
var comparedComputedGroup: ComputedGroup? = null |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class ComputedGroup(group: SessionGroup, computedResults: ComputedResults) { |
||||||
|
// A computable group |
||||||
|
var group: SessionGroup = group |
||||||
|
|
||||||
|
// The computed stats of the group |
||||||
|
var computedResults: ComputedResults = computedResults |
||||||
|
|
||||||
|
fun statValue(stat: Stat) : Double? { |
||||||
|
return computedResults.computedStat(stat)?.value |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class ComputedResults() { |
||||||
|
|
||||||
|
// The computed stats of the group |
||||||
|
private var _computedStats: MutableMap<Stat, ComputedStat> = mutableMapOf() |
||||||
|
|
||||||
|
// The map containing all evolution values for all stats |
||||||
|
private var _evolutionValues: MutableMap<Stat, MutableList<Point>> = mutableMapOf() |
||||||
|
|
||||||
|
fun addEvolutionValue(value: Double, stat: Stat) { |
||||||
|
this._addEvolutionValue(Point(value), stat = stat) |
||||||
|
} |
||||||
|
|
||||||
|
fun addEvolutionValue(value: Double, duration: Double, stat: Stat) { |
||||||
|
this._addEvolutionValue(Point(value, y = duration), stat = stat) |
||||||
|
} |
||||||
|
|
||||||
|
private fun _addEvolutionValue(point: Point, stat: Stat) { |
||||||
|
var evolutionValues = this._evolutionValues[stat] |
||||||
|
if (evolutionValues != null) { |
||||||
|
evolutionValues.add(point) |
||||||
|
} else { |
||||||
|
var values: MutableList<Point> = mutableListOf(point) |
||||||
|
this._evolutionValues[stat] = values |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun addStats(computedStats: Set<ComputedStat>) { |
||||||
|
computedStats.forEach { |
||||||
|
this._computedStats[it.stat] = it |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun computedStat(stat: Stat) : ComputedStat? { |
||||||
|
return this._computedStats[stat] |
||||||
|
} |
||||||
|
|
||||||
|
fun computeStatVariations(resultsToCompare: ComputedResults) { |
||||||
|
this._computedStats.keys.forEach { stat -> |
||||||
|
var computedStat = this.computedStat(stat) |
||||||
|
val comparedStat = resultsToCompare.computedStat(stat) |
||||||
|
if (computedStat != null && comparedStat != null) { |
||||||
|
computedStat.variation = (computedStat.value - comparedStat.value) / comparedStat.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun finalize(options: Calculator.Options) { |
||||||
|
if (options.evolutionValues != Calculator.Options.EvolutionValues.NONE) { |
||||||
|
|
||||||
|
// Sort points as a distribution |
||||||
|
this._computedStats.keys.filter { it.hasDistributionSorting() }.forEach { stat -> |
||||||
|
// @todo sort |
||||||
|
// var evolutionValues = this._evolutionValues[stat] |
||||||
|
// evolutionValues.so |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class Point(x: Double, y: Double) { |
||||||
|
val x: Double = x |
||||||
|
val y: Double = y |
||||||
|
|
||||||
|
constructor(x: Double) : this(x, 1.0) |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
package net.pokeranalytics.android.calculus |
||||||
|
|
||||||
|
import android.graphics.Color |
||||||
|
|
||||||
|
class StatFormat { |
||||||
|
var text: String = "" |
||||||
|
var color: Int = Color.BLUE |
||||||
|
} |
||||||
@ -0,0 +1,65 @@ |
|||||||
|
package net.pokeranalytics.android.calculus |
||||||
|
|
||||||
|
interface AnyStat { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
enum class Stat : AnyStat { |
||||||
|
|
||||||
|
NETRESULT, |
||||||
|
HOURLYRATE, |
||||||
|
DURATION, |
||||||
|
AVERAGE, |
||||||
|
STANDARDDEVIATION, |
||||||
|
HOURLYSTANDARDDEVIATION; |
||||||
|
|
||||||
|
fun label() : String = when (this) { |
||||||
|
NETRESULT -> "" |
||||||
|
HOURLYRATE -> "" |
||||||
|
else -> throw IllegalArgumentException("Label not defined") |
||||||
|
} |
||||||
|
|
||||||
|
fun hasDistributionSorting() : Boolean { |
||||||
|
when (this) { |
||||||
|
STANDARDDEVIATION, HOURLYSTANDARDDEVIATION -> return true |
||||||
|
else -> return false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
enum class CashSessionStat : AnyStat { |
||||||
|
NETBB, |
||||||
|
AVERAGEBB |
||||||
|
} |
||||||
|
|
||||||
|
class ComputedStat(stat: Stat, value: Double) { |
||||||
|
|
||||||
|
constructor(stat: Stat, value: Double, previousValue: Double?) : this(stat, value) { |
||||||
|
if (previousValue != null) { |
||||||
|
this.variation = (value - previousValue) / previousValue |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// The statistic type |
||||||
|
var stat: Stat = stat |
||||||
|
|
||||||
|
// The stat value |
||||||
|
var value: Double = value |
||||||
|
|
||||||
|
// The variation of the stat |
||||||
|
var variation: Double? = null |
||||||
|
|
||||||
|
// The data points leading to the current stat value |
||||||
|
// var points: List<Point> = mutableListOf() |
||||||
|
|
||||||
|
// Formats the value of the stat to be suitable for display |
||||||
|
fun format() : StatFormat { |
||||||
|
return StatFormat() |
||||||
|
} |
||||||
|
|
||||||
|
fun evolutionValueFormat(index: Int) : StatFormat { |
||||||
|
return StatFormat() |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue