Added more hand history case management

hh
Laurent 6 years ago
parent 9da80a7222
commit 8dcf26815d
  1. 116
      app/src/main/java/net/pokeranalytics/android/model/handhistory/Builder.kt
  2. 18
      app/src/main/java/net/pokeranalytics/android/model/handhistory/ComputedAction.kt
  3. 12
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Action.kt
  4. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt

@ -3,6 +3,7 @@ package net.pokeranalytics.android.model.handhistory
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import kotlin.math.min
class Builder {
@ -23,10 +24,10 @@ class Builder {
/***
* All actions sorted by index
*/
private val sortedActions: List<ComputedAction>
get() {
return actionsPerStreet.flatMap { it.value }
}
private var sortedActions: List<ComputedAction> = listOf()
// get() {
// return actionsPerStreet.flatMap { it.value }
// }
/***
* Creates a builder using a [handSetup]
@ -52,7 +53,7 @@ class Builder {
*/
private fun load() {
var potSize = 0.0
// var potSize = 0.0
var totalPotSize = 0.0
// on veut sortir:
@ -61,16 +62,24 @@ class Builder {
// => ne pas oublier flop / turn / river / résumé
// sorted actions
val computedActions = mutableListOf<ComputedAction>()
val sortedActions = this.handHistory.actions.sortedBy { it.index }
Street.values().forEach { street ->
val filteredActions = sortedActions.filter { it.street == street.ordinal }
val computedActions = filteredActions.map { action ->
sortedActions.forEach { action ->
totalPotSize += action.effectiveAmount
ComputedAction(action, potSize, totalPotSize, action.positionRemainingStack)
}
this.actionsPerStreet[street] = computedActions
potSize = totalPotSize
val ca = ComputedAction(action, totalPotSize, action.positionRemainingStack)
computedActions.add(ca)
}
this.sortedActions = computedActions
// Street.values().forEach { street ->
// val filteredActions = sortedActions.filter { it.street == street.ordinal }
// val computedActions = filteredActions.map { action ->
// totalPotSize += action.effectiveAmount
// ComputedAction(action, potSize, totalPotSize, action.positionRemainingStack)
// }
// this.actionsPerStreet[street] = computedActions
// potSize = totalPotSize
// }
}
/***
@ -88,13 +97,13 @@ class Builder {
when (lastSignificantAction.action.type) {
Action.Type.POST_BB, Action.Type.STRADDLE -> {
setOf(Action.Type.STRADDLE, Action.Type.FOLD, Action.Type.CALL, Action.Type.BET, Action.Type.BET_ALLIN)
setOf(Action.Type.STRADDLE, Action.Type.FOLD, Action.Type.CALL, Action.Type.BET, Action.Type.UNDEFINED_ALLIN)
}
Action.Type.BET, Action.Type.RAISE -> {
if (remainingStack != null && actionAmount != null && remainingStack <= actionAmount) {
setOf(Action.Type.FOLD, Action.Type.CALL_ALLIN)
} else {
setOf(Action.Type.FOLD, Action.Type.CALL, Action.Type.RAISE, Action.Type.RAISE_ALLIN)
setOf(Action.Type.FOLD, Action.Type.CALL, Action.Type.RAISE, Action.Type.UNDEFINED_ALLIN)
}
}
Action.Type.RAISE_ALLIN, Action.Type.BET_ALLIN -> {
@ -103,7 +112,7 @@ class Builder {
} else if (this.remainingPlayerCount(index) == 2 && remainingStack != null && actionAmount != null && remainingStack > actionAmount) {
setOf(Action.Type.FOLD, Action.Type.CALL)
} else {
setOf(Action.Type.FOLD, Action.Type.CALL, Action.Type.RAISE, Action.Type.RAISE_ALLIN)
setOf(Action.Type.FOLD, Action.Type.CALL, Action.Type.RAISE, Action.Type.UNDEFINED_ALLIN)
}
}
else -> {
@ -129,15 +138,90 @@ class Builder {
* If the user changes the current action,
* for convenience we remove all the following actions to avoid managing complex cases
*/
private fun selectAction(index: Int, actionType: Action.Type) {
private fun selectAction(index: Int, actionType: Action.Type) : Boolean {
// if the selected action is different from current, remove any action after the index
val computedAction = this.sortedActions.first { it.action.index == index }
computedAction.action.type = actionType
dropIfNecessary(index)
// remaining stack + effective amount
when (actionType) {
Action.Type.CALL -> {
val significantAmount = getLastSignificantAction(index)?.action?.amount ?: throw PAIllegalStateException("Cannot happen")
val committedAmount = getPreviousCommittedAmount(index) ?: 0.0
computedAction.setEffectiveAmount(significantAmount - committedAmount)
}
Action.Type.CALL_ALLIN -> {
computedAction.setEffectiveAmount(computedAction.playerRemainingStack!!)
}
Action.Type.STRADDLE -> {
// TODO
}
}
return computedAction.requireAmount
}
private fun dropIfNecessary(index: Int) {
this.sortedActions.drop(index + 1)
}
/***
* Sets the amount for the action at the provided [index]
*/
private fun setAmount(index: Int, amount: Double) {
val computedAction = this.sortedActions.first { it.action.index == index }
val adjustedAmount = computedAction.playerRemainingStack?.let { min(it, amount) } ?: amount
computedAction.action.amount = adjustedAmount
when (computedAction.action.type) {
Action.Type.UNDEFINED_ALLIN -> {
getLastSignificantAction(index)?.action?.amount?.let { significantActionAmount ->
val committedAmount = getPreviousCommittedAmount(index) ?: 0.0
val askedAmount = significantActionAmount - committedAmount
computedAction.playerRemainingStack?.let { remainingStack ->
if (remainingStack > askedAmount) {
selectAction(index, Action.Type.RAISE_ALLIN)
} else {
selectAction(index, Action.Type.CALL_ALLIN)
}
} ?: run {
selectAction(index, Action.Type.RAISE_ALLIN)
}
} ?: run {
selectAction(index, Action.Type.RAISE_ALLIN)
}
}
else -> {}
}
}
private fun getPreviousCommittedAmount(index: Int) : Double? {
val computedAction = this.sortedActions.first { it.action.index == index }
val position = computedAction.action.position
val previousActions = this.sortedActions.drop(index)
val previousComputedAction = previousActions.lastOrNull { it.action.position == position }
previousComputedAction?.action?.let { action ->
return when (action.type) {
Action.Type.POST_BB, Action.Type.POST_SB, Action.Type.STRADDLE, Action.Type.BET, Action.Type.RAISE -> action.amount
Action.Type.CALL -> getLastSignificantAction(action.index)?.action?.amount
else -> null
}
}
return null
}
/***

@ -3,7 +3,6 @@ package net.pokeranalytics.android.model.handhistory
import net.pokeranalytics.android.model.realm.handhistory.Action
class ComputedAction(var action: Action,
var potSize: Double = 0.0,
var totalPotSize: Double = 0.0,
var playerRemainingStack: Double? = null) {
@ -16,4 +15,21 @@ class ComputedAction(var action: Action,
//
// var playerRemainingStack = 0.0
val requireAmount: Boolean
get() {
return when(this.action.type) {
Action.Type.BET, Action.Type.RAISE -> true
Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN -> (this.playerRemainingStack == null)
else -> false
}
}
fun setEffectiveAmount(amount: Double) {
this.action.effectiveAmount = amount
this.playerRemainingStack?.let {
this.playerRemainingStack = it - amount
}
}
}

@ -1,6 +1,7 @@
package net.pokeranalytics.android.model.realm.handhistory
import io.realm.RealmObject
import net.pokeranalytics.android.exceptions.PAIllegalStateException
open class Action : RealmObject() {
@ -13,6 +14,7 @@ open class Action : RealmObject() {
CALL,
BET,
RAISE,
UNDEFINED_ALLIN,
CALL_ALLIN,
BET_ALLIN,
RAISE_ALLIN;
@ -21,9 +23,11 @@ open class Action : RealmObject() {
get() {
return when (this) {
POST_BB, STRADDLE, BET, RAISE, BET_ALLIN, RAISE_ALLIN -> true
UNDEFINED_ALLIN -> throw PAIllegalStateException("Can't ask for UNDEFINED_ALLIN")
else -> false
}
}
}
/***
@ -44,9 +48,12 @@ open class Action : RealmObject() {
/***
* The type of action: check, fold, raise...
*/
var typeIdentifier: Int? = null
private var typeIdentifier: Int? = null
val type: Type?
var type: Type?
set(value) {
this.typeIdentifier = value?.ordinal
}
get() {
return typeIdentifier?.let { Type.values()[it] }
}
@ -57,7 +64,6 @@ open class Action : RealmObject() {
var amount: Double? = null
var effectiveAmount: Double = 0.0
private set
var positionRemainingStack: Double? = null

@ -85,11 +85,11 @@ open class HandHistory : RealmObject() {
action.position = i
when (i) {
0 -> {
action.typeIdentifier = Action.Type.POST_SB.ordinal
action.type = Action.Type.POST_SB
action.amount = this.smallBlind
}
1 -> {
action.typeIdentifier = Action.Type.POST_BB.ordinal
action.type = Action.Type.POST_BB
action.amount = this.bigBlind
}
else -> {

Loading…
Cancel
Save