diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index e37b87bc..566fa1f6 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -192,7 +192,6 @@ class PokerAnalyticsMigration : RealmMigration { hhSchema.addField("month", Integer::class.java) hhSchema.addField("year", Integer::class.java) hhSchema.addField("dayOfMonth", Integer::class.java) - hhSchema.addRealmListField("winningPositions", Integer::class.java) val cardSchema = schema.create("Card") cardSchema.addField("value", Int::class.java) @@ -219,6 +218,11 @@ class PokerAnalyticsMigration : RealmMigration { playerSetupSchema.addRealmListField("cards", cardSchema) hhSchema.addRealmListField("playerSetups", playerSetupSchema) + val wonPotSchema = schema.create("WonPot") + wonPotSchema.addField("position", Int::class.java) + wonPotSchema.addField("amount", Double::class.java) + hhSchema.addRealmListField("winnerPots", wonPotSchema) + } currentVersion++ diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt index 8702626a..0cd44a07 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt @@ -29,6 +29,7 @@ import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.util.extensions.addLineReturn import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.fullDate +import timber.log.Timber import java.util.* open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, TimeFilterable, @@ -120,7 +121,7 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, /*** * Indicates if the hero wins the hand */ - var winningPositions: RealmList = RealmList() + var winnerPots: RealmList = RealmList() /*** * The board @@ -143,6 +144,12 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, override var year: Int? = null override var dayOfMonth: Int? = null + /*** + * Returns the indexes of all players + */ + val positionIndexes: IntRange + get() { return (0 until this.numberOfPlayers) } + // Deletable override fun isValidForDelete(realm: Realm): Boolean { @@ -199,7 +206,7 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, val totalActions = this.actions.size val startingPosition = lastStraddler?.let { it + 1 } ?: totalActions - for (i in 0 until this.numberOfPlayers) { + for (i in this.positionIndexes) { this.addAction((startingPosition + i) % this.numberOfPlayers) } @@ -415,8 +422,8 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, */ val heroWins: Boolean? get() { - return this.heroIndex?.let { - this.winningPositions.contains(it) + return this.heroIndex?.let { heroIndex -> + this.winnerPots.any { it.position == heroIndex } } ?: run { null } @@ -474,40 +481,114 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, return views } + data class Pot(var amount: Double, var positions: Set, var level: Double? = null) + fun pots(): List { + + var currentPot = 0.0 + val positions = this.positionIndexes.toMutableSet() + val pots = mutableListOf() + var allinAtStreet: Street? = null + val allinActions = mutableListOf() + this.sortedActions.forEach { + + if (allinAtStreet == null) { + + when { + it.type == Action.Type.FOLD -> { + positions.remove(it.position) + } + it.type?.isPullOut == false -> { + currentPot += it.effectiveAmount + } + it.type == Action.Type.CALL_ALLIN -> { + allinAtStreet = it.street + // TODO create pot + } + it.type?.isAllin == true -> { + currentPot += it.effectiveAmount + allinAtStreet = it.street + allinActions.add(it) + } + else -> { + Timber.d("unmanaged action type: ${it.type}") +// throw PAIllegalStateException("unmanaged action type: ${it.type}") + } + } + + } else { // Allin situation + + if (it.street != allinAtStreet) { + allinAtStreet = null + allinActions.clear() + } else { + when { + it.type == Action.Type.FOLD -> { + positions.remove(it.position) + } + it.type == Action.Type.CALL -> { + currentPot += it.effectiveAmount + allinActions.add(it) + } + it.type == Action.Type.CALL_ALLIN -> { + + } + + } + + + + } + + } + + } + + if (currentPot > 0.0) { + pots.add(Pot(currentPot, positions)) + } + + return pots + } + /*** * Defines which positions win the hand */ fun defineWinnerPositions() { val folds = this.sortedActions.filter { it.type == Action.Type.FOLD }.map { it.position } - val activePositions = (0 until this.numberOfPlayers).toMutableList() + val activePositions = this.positionIndexes.toMutableList() activePositions.removeAll(folds) - val winningPositions = when (activePositions.size) { + val wonPots = when (activePositions.size) { 0 -> listOf() // no winner, everyone has fold. Should not happen - 1 -> activePositions // One player has not fold, typically BET / FOLD - else -> this.compareHands(activePositions) // Several players remains, typically BET/FOLD or CHECKS + 1 -> { // One player has not fold, typically BET / FOLD + val pot = WonPot() + pot.position = activePositions.first() + pot.amount = potSizeForStreet(Street.SUMMARY) + listOf(pot) + } + else -> this.getWinningsByPosition(activePositions) // Several players remains, typically BET/FOLD or CHECKS } - this.winningPositions.clear() - this.winningPositions.addAll(winningPositions) + this.winnerPots.clear() + this.winnerPots.addAll(wonPots) } /*** * Compares the hands of the players at the given [positions] * Returns the list of winning hands by position + chips won */ - private fun getWinningsByPosition(positions: List): Map { + private fun getWinningsByPosition(positions: List): Collection { // get the total committed amounts for each position, same order - val committedAmounts = positions.map { position -> + val committedAmounts = this.positionIndexes.map { position -> this.actions.filter { it.position == position }.sumByDouble { it.effectiveAmount } }.toMutableList() // get the various committed levels, ascendly sorted val sortedPotLevels = committedAmounts.toSet().toList().sorted() - val wonAmounts = hashMapOf() + val wonPots = hashMapOf() var previousPotLevel = 0.0 // previous pot level, to remove from the next level // Iterate on each pot @@ -535,16 +616,19 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, // Distributes the pot for each winners val share = pot / winningPositions.size winningPositions.forEach { p -> - val winnings = wonAmounts[p] - if (winnings == null) { - wonAmounts[p] = share + val wp = wonPots[p] + if (wp == null) { + val wonPot = WonPot() + wonPot.position = p + wonPot.amount = share + wonPots[p] = wonPot } else { - wonAmounts[p] = share + winnings + wp.amount += share } } } - return wonAmounts + return wonPots.values } /*** diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/WonPot.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/WonPot.kt new file mode 100644 index 00000000..ee445be5 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/WonPot.kt @@ -0,0 +1,17 @@ +package net.pokeranalytics.android.model.realm.handhistory + +import io.realm.RealmObject + +open class WonPot: RealmObject() { + + /*** + * The position of the player + */ + var position: Int = 0 + + /*** + * The amount won + */ + var amount: Double = 0.0 + +} \ No newline at end of file