Adds algo to get winners and their share

hh
Laurent 6 years ago
parent 570cacdffe
commit ee9a335f22
  1. 94
      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<Int>): Map<Int, Double> {
// 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<Int, Double>()
var previousPotLevel = 0.0 // previous pot level, to remove from the next level
// Iterate on each pot
sortedPotLevels.forEach { potLevel ->
val potEligiblePositions = mutableListOf<Int>()
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<Int>): List<Int> {
// 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)
}
}
Loading…
Cancel
Save