From ee9a335f22c5e10e6894ad9cb3fbab369a20c54d Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 2 Apr 2020 10:59:40 +0200 Subject: [PATCH] Adds algo to get winners and their share --- .../model/realm/handhistory/HandHistory.kt | 94 +++++++++++++++---- 1 file changed, 78 insertions(+), 16 deletions(-) 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 dc3d3d33..8702626a 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 @@ -11,6 +11,7 @@ import io.realm.RealmObject import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.handhistory.HandSetup import net.pokeranalytics.android.model.handhistory.Position @@ -473,6 +474,83 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, return views } + /*** + * 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() + activePositions.removeAll(folds) + + val winningPositions = 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 + } + + this.winningPositions.clear() + this.winningPositions.addAll(winningPositions) + } + + /*** + * 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 { + + // get the total committed amounts for each position, same order + val committedAmounts = positions.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() + var previousPotLevel = 0.0 // previous pot level, to remove from the next level + + // Iterate on each pot + sortedPotLevels.forEach { potLevel -> + + val potEligiblePositions = mutableListOf() + var pot = 0.0 + val asked = potLevel - previousPotLevel + committedAmounts.forEachIndexed { index, playerAmount -> + + // if the player has the asked amount, he becomes eligible for the pot + if (playerAmount >= asked) { + potEligiblePositions.add(positions[index]) + committedAmounts[index] = playerAmount - asked + pot += asked + } else if (playerAmount != 0.0) { + throw PAIllegalStateException("Issue in pot calculations") + } + } + previousPotLevel = potLevel + + // get the winning positions + val winningPositions = compareHands(potEligiblePositions) + + // Distributes the pot for each winners + val share = pot / winningPositions.size + winningPositions.forEach { p -> + val winnings = wonAmounts[p] + if (winnings == null) { + wonAmounts[p] = share + } else { + wonAmounts[p] = share + winnings + } + } + } + + return wonAmounts + } + + /*** + * Compares the hands of the players at the given [activePositions] + * Returns the list of winning hands by position + */ private fun compareHands(activePositions: List): List { // Evaluate all hands @@ -499,20 +577,4 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, } - fun defineWinnerPositions() { - - val folds = this.sortedActions.filter { it.type == Action.Type.FOLD }.map { it.position } - val activePositions = (0 until this.numberOfPlayers).toMutableList() - activePositions.removeAll(folds) - - val winningPositions = 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 - } - - this.winningPositions.clear() - this.winningPositions.addAll(winningPositions) - } - } \ No newline at end of file