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