Fixes bug with checks

hh
Laurent 6 years ago
parent f456fbd3f2
commit b522dc80ff
  1. 13
      app/src/main/java/net/pokeranalytics/android/model/handhistory/ComputedAction.kt
  2. 158
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HHBuilder.kt
  3. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt

@ -1,6 +1,5 @@
package net.pokeranalytics.android.model.handhistory 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.Action
import net.pokeranalytics.android.ui.modules.handhistory.HHKeyboard import net.pokeranalytics.android.ui.modules.handhistory.HHKeyboard
import net.pokeranalytics.android.ui.modules.handhistory.HandRowType import net.pokeranalytics.android.ui.modules.handhistory.HandRowType
@ -65,9 +64,9 @@ class ComputedAction(var action: Action,
*/ */
fun setEffectiveAmount(amount: Double) { fun setEffectiveAmount(amount: Double) {
if (amount <= 0.0) { // if (amount <= 0.0) {
throw PAIllegalStateException("Something probably went wrong somewhere, attempting to make a call of $amount") // throw PAIllegalStateException("Something probably went wrong somewhere, attempting to make a call of $amount")
} // }
val oldEffective = this.action.effectiveAmount val oldEffective = this.action.effectiveAmount
@ -124,6 +123,12 @@ class ComputedAction(var action: Action,
// return amountCanBeEdited // return amountCanBeEdited
} }
/***
* Shortcut to return the action street
*/
val street: Street
get() { return this.action.street }
override val viewType: Int = HandRowType.ACTION.ordinal override val viewType: Int = HandRowType.ACTION.ordinal
} }

@ -21,8 +21,6 @@ enum class HHKeyboard {
CARD; CARD;
} }
class HHSelection(var index: Int, var keyboard: HHKeyboard)
class HHBuilder { class HHBuilder {
/*** /***
@ -120,8 +118,9 @@ class HHBuilder {
*/ */
fun availableActions(index: Int) : Set<Action.Type> { fun availableActions(index: Int) : Set<Action.Type> {
val position = this.actionForIndex(index).position val computedAction = this.actionForIndex(index)
val lastSignificantAction: ComputedAction? = getStreetLastSignificantAction(index - 1) val position = computedAction.position
val lastSignificantAction: ComputedAction? = getStreetLastSignificantAction(computedAction.street, index)
val lastUserAction: ComputedAction? = getLastUserAction(index) val lastUserAction: ComputedAction? = getLastUserAction(index)
return if (lastSignificantAction != null) { return if (lastSignificantAction != null) {
@ -177,12 +176,11 @@ class HHBuilder {
fun selectAction(index: Int, actionType: Action.Type) : List<Int>? { fun selectAction(index: Int, actionType: Action.Type) : List<Int>? {
var type = actionType var type = actionType
val computedAction = this.actionForIndex(index) val computedAction = this.actionForIndex(index)
// define allin type // define allin type
if (type == Action.Type.UNDEFINED_ALLIN) { if (type == Action.Type.UNDEFINED_ALLIN) {
val significant = getStreetLastSignificantAction(index - 1) val significant = getStreetLastSignificantAction(computedAction.street, index - 1)
if (significant != null) { if (significant != null) {
val betAmount = significant.action.amount val betAmount = significant.action.amount
val remainingStack = computedAction.playerRemainingStack val remainingStack = computedAction.playerRemainingStack
@ -214,7 +212,7 @@ class HHBuilder {
// define action amounts if possible // define action amounts if possible
when (type) { when (type) {
Action.Type.CALL -> { Action.Type.CALL -> {
val significantAction = getStreetLastSignificantAction(index - 1) val significantAction = getStreetLastSignificantAction(computedAction.street, index - 1)
?: throw PAIllegalStateException("There must be a previously set significant action for a call to be set") ?: throw PAIllegalStateException("There must be a previously set significant action for a call to be set")
val significantAmount = significantAction.action.amount val significantAmount = significantAction.action.amount
?: throw PAIllegalStateException("There must be a set amount on the action for the call to be set") ?: throw PAIllegalStateException("There must be a set amount on the action for the call to be set")
@ -237,7 +235,7 @@ class HHBuilder {
val modifiedActions = mutableListOf<ComputedAction>() val modifiedActions = mutableListOf<ComputedAction>()
getPreviousEmptyActions(index).forEach { getPreviousEmptyActions(index).forEach {
modifiedActions.add(it) modifiedActions.add(it)
val lastSignificant = getStreetLastSignificantAction(index - 1) val lastSignificant = getStreetLastSignificantAction(computedAction.street, index - 1)
it.action.type = if (lastSignificant != null) { it.action.type = if (lastSignificant != null) {
Action.Type.FOLD Action.Type.FOLD
} else { } else {
@ -254,26 +252,25 @@ class HHBuilder {
/*** /***
* Adds, if necessary, new ComputedAction for players that needs to act * Adds, if necessary, new ComputedAction for players that needs to act
* Also adds, if necessary, the Street separators and board selectors * Also adds, if necessary, the Street separators and board selectors
* Returns true if the action list has been modified
*/ */
private fun updateFollowupActions(index: Int) : Boolean { private fun updateFollowupActions(index: Int) : Boolean {
val computedAction = this.actionForIndex(index) val computedAction = this.actionForIndex(index)
val type = computedAction.action.type val type = computedAction.action.type
val f = addsFollowupActionsIfNecessary(index) var actionsChanged = addsFollowupActionsIfNecessary(index)
return when (type?.isSignificant) {
true -> { // opens the action and requires action from other when (type?.isSignificant) {
// addsFollowupActionsIfNecessary(index)
f
}
false -> { // closes the action, pass to next street if necessary false -> { // closes the action, pass to next street if necessary
if (type == Action.Type.CALL_ALLIN) { // sometimes we can go from RAISE_ALLIN to CALL_IN, changing the actions required if (type == Action.Type.CALL_ALLIN) { // sometimes we can go from RAISE_ALLIN to CALL_IN, changing the actions required
removeActionsIfNecessary(index) removeActionsIfNecessary(index)
} }
createNextStreetIfNecessary(index) actionsChanged = createNextStreetIfNecessary(index) || actionsChanged
} }
else -> false else -> {}
} }
return actionsChanged
} }
/*** /***
@ -291,13 +288,16 @@ class HHBuilder {
*/ */
private fun addsFollowupActionsIfNecessary(index: Int) : Boolean { private fun addsFollowupActionsIfNecessary(index: Int) : Boolean {
val refAction = getStreetLastSignificantAction(index) ?: this.actionForIndex(index) val street = this.actionForIndex(index).street
val refIndex = refAction.action.index
val refAction = getStreetLastSignificantAction(street, index)
?: this.actionForIndex(this.firstIndexOfStreet(street))
val indexPosition = refAction.position val refIndex = refAction.action.index
val refIndexPosition = refAction.position
val activePositions = activePositions(refIndex) val activePositions = activePositions(refIndex)
activePositions.remove(indexPosition) activePositions.remove(refIndexPosition)
// We want to remove positions that already have an action after [refIndex] // We want to remove positions that already have an action after [refIndex]
for (i in refIndex + 1 until this.sortedActions.size) { for (i in refIndex + 1 until this.sortedActions.size) {
@ -306,10 +306,10 @@ class HHBuilder {
} }
// Circularly adds an action for missing positions // Circularly adds an action for missing positions
val firstPositionAfterCurrent = max(0, activePositions.indexOfFirst { it.ordinal > indexPosition.ordinal }) val firstPositionAfterCurrent = max(0, activePositions.indexOfFirst { it.ordinal > refIndexPosition.ordinal })
for (i in 0 until activePositions.size) { for (i in 0 until activePositions.size) {
val position = activePositions[(firstPositionAfterCurrent + i) % activePositions.size] val position = activePositions[(firstPositionAfterCurrent + i) % activePositions.size]
this.addNewEmptyAction(position, refAction.action.street, refAction.totalPotSize, lastRemainingStack(position, index)) this.addNewEmptyAction(position, refAction.street, refAction.totalPotSize, lastRemainingStack(position, index))
} }
return activePositions.isNotEmpty() return activePositions.isNotEmpty()
@ -406,8 +406,8 @@ class HHBuilder {
* Returns the list of empty actions before the action at the given [index] * Returns the list of empty actions before the action at the given [index]
*/ */
private fun getPreviousEmptyActions(index: Int) : List<ComputedAction> { private fun getPreviousEmptyActions(index: Int) : List<ComputedAction> {
val street = this.actionForIndex(index).action.street val street = this.actionForIndex(index).street
return this.sortedActions.take(index).filter { it.action.street == street && it.action.type == null } return this.sortedActions.take(index).filter { it.street == street && it.action.type == null }
} }
/*** /***
@ -415,10 +415,10 @@ class HHBuilder {
* following an action change. * following an action change.
* We want drop all non-auto added rows after the index * We want drop all non-auto added rows after the index
*/ */
private fun dropNextActionsIfNecessary(index: Int) : Boolean { private fun dropNextActionsIfNecessary(index: Int): Boolean {
val street = this.actionForIndex(index).action.street val street = this.actionForIndex(index).street
val firstIndexOfStreet = this.sortedActions.first { it.action.street == street }.action.index val firstIndexOfStreet = this.firstIndexOfStreet(street)
val activePositions = activePositions(firstIndexOfStreet) val activePositions = activePositions(firstIndexOfStreet)
val defaultRowsCount = when (street) { val defaultRowsCount = when (street) {
Street.PREFLOP -> activePositions.size + 2 Street.PREFLOP -> activePositions.size + 2
@ -434,6 +434,10 @@ class HHBuilder {
return sizeAfter != sizeBefore return sizeAfter != sizeBefore
} }
private fun firstIndexOfStreet(street: Street): Int {
return this.sortedActions.first { it.street == street }.action.index
}
/*** /***
* Sets the amount for the action at the provided [index] * Sets the amount for the action at the provided [index]
* In the case of a RAISE_ALLIN, check if it's a CALL_ALLIN * In the case of a RAISE_ALLIN, check if it's a CALL_ALLIN
@ -457,7 +461,7 @@ class HHBuilder {
// verify if the raise is not a call after all // verify if the raise is not a call after all
if (computedAction.action.type == Action.Type.RAISE_ALLIN) { if (computedAction.action.type == Action.Type.RAISE_ALLIN) {
getStreetLastSignificantAction(index - 1)?.action?.amount?.let { significantActionAmount -> getStreetLastSignificantAction(computedAction.street, index - 1)?.action?.amount?.let { significantActionAmount ->
val askedAmount = significantActionAmount - committedAmount val askedAmount = significantActionAmount - committedAmount
computedAction.playerRemainingStack?.let { remainingStack -> computedAction.playerRemainingStack?.let { remainingStack ->
@ -475,21 +479,21 @@ class HHBuilder {
/*** /***
* Returns the committed amount by the player for the street at the current [index] * Returns the committed amount by the player for the street at the current [index]
*/ */
private fun getPreviouslyCommittedAmount(index: Int) : Double? { private fun getPreviouslyCommittedAmount(index: Int): Double? {
val action = this.actionForIndex(index).action val action = this.actionForIndex(index).action
val position = action.position val position = action.position
val street = action.street val street = action.street
val previousActions = this.sortedActions.take(index) val previousActions = this.sortedActions.take(index)
val previousComputedAction = previousActions.lastOrNull { val previousComputedAction = previousActions.lastOrNull {
it.action.position == position && it.action.street == street it.action.position == position && it.street == street
} }
previousComputedAction?.action?.let { previousAction -> previousComputedAction?.action?.let { previousAction ->
return when (previousAction.type) { return when (previousAction.type) {
Action.Type.POST_BB, Action.Type.POST_SB, Action.Type.STRADDLE, Action.Type.BET, Action.Type.RAISE -> previousAction.amount Action.Type.POST_BB, Action.Type.POST_SB, Action.Type.STRADDLE, Action.Type.BET, Action.Type.RAISE -> previousAction.amount
Action.Type.CALL -> getStreetLastSignificantAction(previousAction.index)?.action?.amount Action.Type.CALL -> getStreetLastSignificantAction(previousAction.street, previousAction.index)?.action?.amount
else -> null else -> null
} }
} }
@ -500,7 +504,7 @@ class HHBuilder {
/*** /***
* Returns all "CALL" ComputedAction between the [index] and the next significant action * Returns all "CALL" ComputedAction between the [index] and the next significant action
*/ */
private fun getStreetNextCalls(index: Int) : List<ComputedAction> { private fun getStreetNextCalls(index: Int): List<ComputedAction> {
val streetNextSignificantIndex = getStreetNextSignificantAction(index)?.action?.index ?: lastIndexOfStreet(index) val streetNextSignificantIndex = getStreetNextSignificantAction(index)?.action?.index ?: lastIndexOfStreet(index)
return this.sortedActions.filter { return this.sortedActions.filter {
it.action.index in ((index + 1) until streetNextSignificantIndex) it.action.index in ((index + 1) until streetNextSignificantIndex)
@ -511,9 +515,9 @@ class HHBuilder {
/*** /***
* Returns the last action index of the street, for the action at [index] * Returns the last action index of the street, for the action at [index]
*/ */
private fun lastIndexOfStreet(index: Int) : Int { private fun lastIndexOfStreet(index: Int): Int {
val street = this.actionForIndex(index).action.street val street = this.actionForIndex(index).street
return this.sortedActions.last { it.action.street == street }.action.index return this.sortedActions.last { it.street == street }.action.index
} }
/*** /***
@ -530,10 +534,9 @@ class HHBuilder {
/*** /***
* Returns the last significant player action, if any, for the action at the provided [index] * Returns the last significant player action, if any, for the action at the provided [index]
*/ */
private fun getStreetLastSignificantAction(index: Int): ComputedAction? { private fun getStreetLastSignificantAction(street: Street, index: Int): ComputedAction? {
val street = this.actionForIndex(index).action.street
// Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}") // Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}")
val previousActions = this.sortedActions.take(index + 1).filter { it.action.street == street } val previousActions = this.sortedActions.take(index + 1).filter { it.street == street }
// Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}") // Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}")
return previousActions.lastOrNull { it.action.isActionSignificant } return previousActions.lastOrNull { it.action.isActionSignificant }
} }
@ -542,8 +545,8 @@ class HHBuilder {
* Returns the next significant player action in the street, if any, for the action at the provided [index] * Returns the next significant player action in the street, if any, for the action at the provided [index]
*/ */
private fun getStreetNextSignificantAction(index: Int): ComputedAction? { private fun getStreetNextSignificantAction(index: Int): ComputedAction? {
val street = this.actionForIndex(index).action.street val street = this.actionForIndex(index).street
val nextActions = this.sortedActions.drop(index + 1).filter { it.action.street == street } val nextActions = this.sortedActions.drop(index + 1).filter { it.street == street }
return nextActions.firstOrNull { it.action.isActionSignificant } return nextActions.firstOrNull { it.action.isActionSignificant }
} }
@ -551,8 +554,8 @@ class HHBuilder {
* Returns a list of positions at the provided [index] * Returns a list of positions at the provided [index]
*/ */
fun positionsAtIndex(index: Int): List<Position> { fun positionsAtIndex(index: Int): List<Position> {
val currentStreet = this.actionForIndex(index).action.street val currentStreet = this.actionForIndex(index).street
val streetActions = this.sortedActions.filter { it.action.street == currentStreet } val streetActions = this.sortedActions.filter { it.street == currentStreet }
return streetActions.drop(index + 1).map { it.position } return streetActions.drop(index + 1).map { it.position }
} }
@ -587,10 +590,7 @@ class HHBuilder {
if (index >= startIndex && rowRepresentable is HandHistoryRow) { if (index >= startIndex && rowRepresentable is HandHistoryRow) {
val foundKeyboard = rowRepresentable.keyboardForCompletion() val foundKeyboard = rowRepresentable.keyboardForCompletion()
if (foundKeyboard != null) { if (foundKeyboard != null) {
return HHSelection( return HHSelection(index, foundKeyboard)
index,
foundKeyboard
)
} }
} }
} }
@ -618,21 +618,8 @@ class HHBuilder {
* Adds a card with the selected [value] * Adds a card with the selected [value]
*/ */
fun cardValueSelected(value: Card.Value, currentSelection: HHSelection) { fun cardValueSelected(value: Card.Value, currentSelection: HHSelection) {
val row = this.rowRepresentables[currentSelection.index] as CardsRow val row = this.rowRepresentables[currentSelection.index] as CardsRow
row.valueSelected(value) row.valueSelected(value)
// when (val row = this.rowRepresentables[currentSelection.index]) {
// is CardsRow -> {
// val card = Card.newInstance(value.value)
// row.add(card)
// }
// is PlayerCardsRow -> {
// val positionIndex = this.positions.indexOf(row.position)
// val playerSetup = this.handHistory.playerSetupForPosition(positionIndex)
// playerSetup.cardValueSelected(value)
// }
// }
} }
/*** /***
@ -646,29 +633,6 @@ class HHBuilder {
// TODO do we want to store the information right now ? // TODO do we want to store the information right now ?
// when (val row = this.rowRepresentables[currentSelection.index]) {
// is StreetCardsRow -> {
//
// val addNewCard = this.boardManager.lastCard(row.street)?.let {
// if (it.suit != null) {
// true
// } else {
// it.suit = suit
// false
// }
// } ?: true
//
// if (addNewCard) {
// val card = Card.newInstance(suit = suit)
// this.boardManager.add(card)
// }
// }
// is PlayerCardsRow -> {
// val positionIndex = this.positions.indexOf(row.position)
// val playerSetup = this.handHistory.playerSetupForPosition(positionIndex)
// playerSetup.cardSuitSelected(suit)
// }
// }
} }
/*** /***
@ -679,12 +643,6 @@ class HHBuilder {
val row = this.rowRepresentables[currentSelection.index] as CardsRow val row = this.rowRepresentables[currentSelection.index] as CardsRow
row.clear() row.clear()
// when (val row = this.rowRepresentables[currentSelection.index]) {
// is StreetCardsRow -> {
// this.boardManager.clearStreet(row.street)
// }
// }
} }
/*** /***
@ -693,21 +651,8 @@ class HHBuilder {
* so we delete the whole card if both information are null * so we delete the whole card if both information are null
*/ */
fun deleteLastCardProperty(currentSelection: HHSelection) { fun deleteLastCardProperty(currentSelection: HHSelection) {
val row = this.rowRepresentables[currentSelection.index] as CardsRow val row = this.rowRepresentables[currentSelection.index] as CardsRow
row.deleteLastCardProperty() row.deleteLastCardProperty()
// when (val row = this.rowRepresentables[currentSelection.index]) {
// is StreetCardsRow -> {
// this.boardManager.lastCard(row.street)?.let { card ->
// if (card.value != null && card.suit != null) {
// card.suit = null
// } else {
// this.boardManager.remove(card)
// }
// }
// }
// }
} }
/*** /***
@ -752,7 +697,7 @@ class HHBuilder {
Street.values().forEach { street -> Street.values().forEach { street ->
val actions = this.sortedActions.filter { it.action.street == street } val actions = this.sortedActions.filter { it.street == street }
when (street) { when (street) {
Street.SUMMARY -> { Street.SUMMARY -> {
@ -788,9 +733,9 @@ class HHBuilder {
*/ */
private fun isStreetActionClosed(index: Int) : Street? { private fun isStreetActionClosed(index: Int) : Street? {
val currentStreet = this.actionForIndex(index).action.street val currentStreet = this.actionForIndex(index).street
getStreetLastSignificantAction(index)?.let { significantAction -> getStreetLastSignificantAction(currentStreet, index)?.let { significantAction ->
val activePositions = activePositions(index) val activePositions = activePositions(index)
val activePlayerCount = activePositions.size // don't move this line because of removes val activePlayerCount = activePositions.size // don't move this line because of removes
@ -821,7 +766,7 @@ class HHBuilder {
} }
val allPassive = this.sortedActions val allPassive = this.sortedActions
.filter { it.action.street == currentStreet } .filter { it.street == currentStreet }
.all { it.action.type?.isPassive ?: false } .all { it.action.type?.isPassive ?: false }
if (allPassive) { if (allPassive) {
@ -840,7 +785,8 @@ class HHBuilder {
*/ */
private fun addStreetHeader(rowRepresentables: MutableList<RowRepresentable>, street: Street) { private fun addStreetHeader(rowRepresentables: MutableList<RowRepresentable>, street: Street) {
val firstIndexOfStreet = this.sortedActions.firstOrNull { it.action.street == street }?.action?.index ?: this.sortedActions.size val firstIndexOfStreet = this.sortedActions.firstOrNull { it.street == street }?.action?.index
?: this.sortedActions.size
val potSize = this.sortedActions.take(firstIndexOfStreet).sumByDouble { it.action.effectiveAmount } val potSize = this.sortedActions.take(firstIndexOfStreet).sumByDouble { it.action.effectiveAmount }
val potString = if (potSize > 0) potSize.formatted() else null val potString = if (potSize > 0) potSize.formatted() else null

@ -10,6 +10,8 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import timber.log.Timber import timber.log.Timber
class HHSelection(var index: Int, var keyboard: HHKeyboard)
class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource { class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource {
private var builderLiveData = MutableLiveData<HHBuilder>() private var builderLiveData = MutableLiveData<HHBuilder>()

Loading…
Cancel
Save