|
|
|
|
@ -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) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |