Refactoring + issue fix

hh
Laurent 6 years ago
parent 6a72abf674
commit f8ab6489c5
  1. 102
      app/src/main/java/net/pokeranalytics/android/model/handhistory/ComputedAction.kt
  2. 240
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HHBuilder.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  4. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt
  5. 9
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/CardSuitAdapter.kt
  6. 7
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/CardValueAdapter.kt
  7. 11
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/KeyboardCardView.kt
  8. 5
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/KeyboardContainer.kt

@ -1,6 +1,8 @@
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.ActionManager
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
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
@ -15,7 +17,8 @@ interface HandHistoryRow : RowRepresentable {
fun keyboardForCompletion() : HHKeyboard? fun keyboardForCompletion() : HHKeyboard?
} }
class ComputedAction(var action: Action, class ComputedAction(var manager: ActionManager,
var action: Action,
var totalPotSize: Double = 0.0, var totalPotSize: Double = 0.0,
var playerRemainingStack: Double? = null, var playerRemainingStack: Double? = null,
var position: Position) : HandHistoryRow { var position: Position) : HandHistoryRow {
@ -33,14 +36,49 @@ class ComputedAction(var action: Action,
} }
} }
fun setType(type: Action.Type): Boolean {
val typeChange = (this.action.type != null)
if (this.action.type != type) {
this.action.type = type
this.action.amount = null
}
// define action amounts if possible
when (type) {
Action.Type.CALL -> {
updateEffectiveAmount()
}
Action.Type.CALL_ALLIN -> {
this.setEffectiveAmount(this.playerRemainingStack!!)
}
Action.Type.STRADDLE -> {
// TODO
}
Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN, Action.Type.UNDEFINED_ALLIN -> {
this.action.amount = this.playerRemainingStack
}
else -> {}
}
if (typeChange) {
return this.manager.dropNextActions(this.action.index)
}
return false
}
/*** /***
* Sets the action amount * Sets the action amount
*/ */
fun setAmount(amount: Double, committedAmount: Double) { fun setAmount(amount: Double) {
val oldAmount = this.action.amount val oldAmount = this.action.amount
val remainingStack = this.playerRemainingStack val remainingStack = this.playerRemainingStack
val committedAmount = this.getPreviouslyCommittedAmount()
this.action.effectiveAmount = amount - committedAmount this.action.effectiveAmount = amount - committedAmount
if (oldAmount != null && remainingStack != null) { if (oldAmount != null && remainingStack != null) {
@ -56,6 +94,36 @@ class ComputedAction(var action: Action,
this.action.amount = amount this.action.amount = amount
} }
when (this.action.type) {
Action.Type.POST_BB, Action.Type.BET, Action.Type.RAISE, Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN -> {
getStreetNextCalls().forEach {
it.setEffectiveAmount(amount)
}
getPlayerNextActions().forEach {
it.updateEffectiveAmount()
}
// verify if the raise is not a call after all
if (this.action.type == Action.Type.RAISE_ALLIN) {
this.getStreetLastSignificantAction()?.action?.amount?.let { significantActionAmount ->
val askedAmount = significantActionAmount - committedAmount
this.playerRemainingStack?.let { remainingStack ->
if (remainingStack < askedAmount) {
this.manager.selectAction(this.action.index, Action.Type.CALL_ALLIN)
}
}
}
// getStreetLastSignificantAction(this.street, index - 1)?.action?.amount?.let {
// }
}
}
else -> {}
}
} }
/*** /***
@ -96,6 +164,36 @@ class ComputedAction(var action: Action,
} }
} }
/***
* Updates the effective amount
*/
private fun updateEffectiveAmount() {
val significantAction = getStreetLastSignificantAction()
?: throw PAIllegalStateException("There must be a previously set significant action for a call to be set")
val significantAmount = significantAction.action.amount
?: throw PAIllegalStateException("There must be a set amount on the action for the call to be set")
val committedAmount = getPreviouslyCommittedAmount()
this.setEffectiveAmount(significantAmount - committedAmount)
}
private fun getStreetLastSignificantAction(): ComputedAction? {
return this.manager.getStreetLastSignificantAction(this.street, this.action.index - 1)
}
private fun getPreviouslyCommittedAmount(): Double {
return this.manager.getPreviouslyCommittedAmount(this.action.index) ?: 0.0
}
private fun getStreetNextCalls(): List<ComputedAction> {
return this.manager.getStreetNextCalls(this.action.index)
}
private fun getPlayerNextActions(): List<ComputedAction> {
return this.manager.getPlayerNextStreetActions(this.action.index)
}
/*** /***
* Returns whether the action type can be edited * Returns whether the action type can be edited
* SB / BB cannot have their action type edited * SB / BB cannot have their action type edited

@ -6,6 +6,7 @@ import net.pokeranalytics.android.model.handhistory.*
import net.pokeranalytics.android.model.realm.handhistory.Action import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.Card import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.modules.handhistory.views.CardCentralizer
import net.pokeranalytics.android.ui.modules.handhistory.views.CardsRow import net.pokeranalytics.android.ui.modules.handhistory.views.CardsRow
import net.pokeranalytics.android.ui.modules.handhistory.views.PlayerCardsRow import net.pokeranalytics.android.ui.modules.handhistory.views.PlayerCardsRow
import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow
@ -21,7 +22,44 @@ enum class HHKeyboard {
CARD; CARD;
} }
class HHBuilder { interface ActionManager {
fun getStreetLastSignificantAction(street: Street, index: Int): ComputedAction?
fun getPreviouslyCommittedAmount(index: Int): Double?
fun selectAction(index: Int, actionType: Action.Type) : List<Int>?
fun getStreetNextCalls(index: Int): List<ComputedAction>
fun getPlayerNextStreetActions(index: Int): List<ComputedAction>
fun dropNextActions(index: Int): Boolean
}
class ActionList : ArrayList<ComputedAction>() {
/***
* Keep the first [n] elements
*/
fun keepFirst(n: Int) {
val cut = this.take(n)
this.clear()
this.addAll(cut)
}
/***
* Returns the first action of the given [street]
*/
fun firstStreetAction(street: Street): ComputedAction {
return this.first { it.street == street }
}
/***
* Returns the last action index of the street, for the action at [index]
*/
fun lastIndexOfStreet(index: Int): Int {
val street = this[index].street
return this.last { it.street == street }.action.index
}
}
class HHBuilder : CardCentralizer, ActionManager {
/*** /***
* The hand history * The hand history
@ -36,7 +74,7 @@ class HHBuilder {
/*** /***
* All actions sorted by index * All actions sorted by index
*/ */
private var sortedActions: MutableList<ComputedAction> = mutableListOf() private var sortedActions: ActionList = ActionList()
/*** /***
* The board cards sorted by position * The board cards sorted by position
@ -93,12 +131,13 @@ class HHBuilder {
var totalPotSize = 0.0 var totalPotSize = 0.0
// sorted actions // sorted actions
val computedActions = mutableListOf<ComputedAction>() val computedActions = ActionList()
val sortedActions = this.handHistory.actions.sortedBy { it.index } val sortedActions = this.handHistory.actions.sortedBy { it.index }
sortedActions.forEach { action -> sortedActions.forEach { action ->
totalPotSize += action.effectiveAmount totalPotSize += action.effectiveAmount
val position = this.positions.elementAt(action.position) val position = this.positions.elementAt(action.position)
val ca = ComputedAction( val ca = ComputedAction(
this,
action, action,
totalPotSize, totalPotSize,
action.positionRemainingStack, action.positionRemainingStack,
@ -121,11 +160,12 @@ class HHBuilder {
val computedAction = this.actionForIndex(index) val computedAction = this.actionForIndex(index)
val position = computedAction.position val position = computedAction.position
val lastSignificantAction: ComputedAction? = getStreetLastSignificantAction(computedAction.street, index) val lastSignificantAction: ComputedAction? = getStreetLastSignificantAction(computedAction.street, index)
val lastUserAction: ComputedAction? = getLastUserAction(index)
return if (lastSignificantAction != null) { return if (lastSignificantAction == null) {
setOf(Action.Type.CHECK, Action.Type.BET, Action.Type.UNDEFINED_ALLIN)
} else {
val remainingStack = lastUserAction?.playerRemainingStack val remainingStack = getLastPlayerAction(index)?.playerRemainingStack
val actionAmount = lastSignificantAction.action.amount val actionAmount = lastSignificantAction.action.amount
when (lastSignificantAction.action.type) { when (lastSignificantAction.action.type) {
@ -156,9 +196,6 @@ class HHBuilder {
throw PAIllegalStateException("We should not handle this action: ${lastSignificantAction.action.type}") throw PAIllegalStateException("We should not handle this action: ${lastSignificantAction.action.type}")
} }
} }
} else {
setOf(Action.Type.CHECK, Action.Type.BET, Action.Type.UNDEFINED_ALLIN)
} }
} }
@ -173,7 +210,7 @@ class HHBuilder {
* - null when actions have been deleted, requiring a whole table refresh, because streets might me lost * - null when actions have been deleted, requiring a whole table refresh, because streets might me lost
* - the list of modified action indexes that are not the action at [index] * - the list of modified action indexes that are not the action at [index]
*/ */
fun selectAction(index: Int, actionType: Action.Type) : List<Int>? { override 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)
@ -184,10 +221,10 @@ class HHBuilder {
if (significant != null) { if (significant != null) {
val betAmount = significant.action.amount val betAmount = significant.action.amount
val remainingStack = computedAction.playerRemainingStack val remainingStack = computedAction.playerRemainingStack
if (remainingStack != null && betAmount != null && remainingStack < betAmount) { type = if (remainingStack != null && betAmount != null && remainingStack < betAmount) {
type = Action.Type.CALL_ALLIN Action.Type.CALL_ALLIN
} else { } else {
type = Action.Type.RAISE_ALLIN Action.Type.RAISE_ALLIN
} }
} else { } else {
type = Action.Type.BET_ALLIN type = Action.Type.BET_ALLIN
@ -196,40 +233,7 @@ class HHBuilder {
Timber.d(">>> Sets $type at index: $index") Timber.d(">>> Sets $type at index: $index")
var structureModified = false var structureModified = computedAction.setType(type) // false
val actionPreviouslySet = (computedAction.action.type != null)
// set type + reset amount if type change
if (computedAction.action.type != type) {
computedAction.action.type = type
computedAction.action.amount = null
if (actionPreviouslySet) {
structureModified = dropNextActionsIfNecessary(index)
}
}
// define action amounts if possible
when (type) {
Action.Type.CALL -> {
val significantAction = getStreetLastSignificantAction(computedAction.street, index - 1)
?: throw PAIllegalStateException("There must be a previously set significant action for a call to be set")
val significantAmount = significantAction.action.amount
?: throw PAIllegalStateException("There must be a set amount on the action for the call to be set")
val committedAmount = getPreviouslyCommittedAmount(index) ?: 0.0
computedAction.setEffectiveAmount(significantAmount - committedAmount)
}
Action.Type.CALL_ALLIN -> {
computedAction.setEffectiveAmount(computedAction.playerRemainingStack!!)
}
Action.Type.STRADDLE -> {
// TODO
}
Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN, Action.Type.UNDEFINED_ALLIN -> {
computedAction.action.amount = computedAction.playerRemainingStack
}
else -> {}
}
// Automatically sets action for the previous empty actions // Automatically sets action for the previous empty actions
val modifiedActions = mutableListOf<ComputedAction>() val modifiedActions = mutableListOf<ComputedAction>()
@ -249,6 +253,15 @@ class HHBuilder {
return modifiedActions.map { this.rowRepresentables.indexOf(it) } return modifiedActions.map { this.rowRepresentables.indexOf(it) }
} }
/***
* Sets the amount for the action at the provided [index]
*/
fun setAmount(index: Int, amount: Double) {
val computedAction = this.actionForIndex(index)
Timber.d(">>> Sets $amount at index: $index, for action ${computedAction.action.type}")
computedAction.setAmount(amount)
}
/*** /***
* 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
@ -277,7 +290,9 @@ class HHBuilder {
* Recreates the actions after [index] * Recreates the actions after [index]
*/ */
private fun removeActionsIfNecessary(index: Int) { private fun removeActionsIfNecessary(index: Int) {
this.sortedActions = this.sortedActions.take(index + 1).toMutableList()
this.sortedActions.keepFirst(index + 1)
addsFollowupActionsIfNecessary(index) addsFollowupActionsIfNecessary(index)
} }
@ -291,7 +306,7 @@ class HHBuilder {
val street = this.actionForIndex(index).street val street = this.actionForIndex(index).street
val refAction = getStreetLastSignificantAction(street, index) val refAction = getStreetLastSignificantAction(street, index)
?: this.actionForIndex(this.firstIndexOfStreet(street)) ?: this.sortedActions.firstStreetAction(street)
val refIndex = refAction.action.index val refIndex = refAction.action.index
val refIndexPosition = refAction.position val refIndexPosition = refAction.position
@ -331,7 +346,7 @@ class HHBuilder {
action.position = position.ordinal action.position = position.ordinal
action.street = street action.street = street
val computedAction = val computedAction =
ComputedAction( ComputedAction(this,
action, action,
currentPotSize, currentPotSize,
remainingStack, remainingStack,
@ -366,7 +381,7 @@ class HHBuilder {
*/ */
private fun createNextStreetIfNecessary(index: Int) : Boolean { private fun createNextStreetIfNecessary(index: Int) : Boolean {
val nextStreet = isStreetActionClosed(index) val nextStreet = isStreetActionClosed(index)
if (nextStreet != null) { if (nextStreet != null && this.sortedActions.firstOrNull { it.street == nextStreet } == null) {
createStreet(nextStreet) createStreet(nextStreet)
return true return true
} }
@ -415,71 +430,30 @@ 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 { override fun dropNextActions(index: Int): Boolean {
val street = this.actionForIndex(index).street
val firstIndexOfStreet = this.firstIndexOfStreet(street)
val activePositions = activePositions(firstIndexOfStreet)
val defaultRowsCount = when (street) {
Street.PREFLOP -> activePositions.size + 2
else -> activePositions.size
}
val sizeBefore = this.sortedActions.size val sizeBefore = this.sortedActions.size
// val keptRowsIndex = max(index, firstIndexOfStreet + defaultRowsCount)
this.sortedActions = this.sortedActions.take(index + 1).toMutableList() this.sortedActions.keepFirst(index + 1)
this.updateFollowupActions(index) this.updateFollowupActions(index)
this.createRowRepresentation() this.createRowRepresentation()
val sizeAfter = this.sortedActions.size
val sizeAfter = this.sortedActions.size
return sizeAfter != sizeBefore return sizeAfter != sizeBefore
} }
private fun firstIndexOfStreet(street: Street): Int { override fun getPlayerNextStreetActions(index: Int): List<ComputedAction> {
return this.sortedActions.first { it.street == street }.action.index val computedAction = this.sortedActions[index]
} return this.sortedActions.drop(index + 1).filter {
it.street == computedAction.street && it.position == computedAction.position
/***
* Sets the amount for the action at the provided [index]
* In the case of a RAISE_ALLIN, check if it's a CALL_ALLIN
*/
fun setAmount(index: Int, amount: Double) {
val computedAction = this.actionForIndex(index)
Timber.d(">>> Sets $amount at index: $index, for action ${computedAction.action.type}")
val committedAmount = getPreviouslyCommittedAmount(index) ?: 0.0
computedAction.setAmount(amount, committedAmount)
when (computedAction.action.type) {
Action.Type.BET, Action.Type.RAISE, Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN -> {
getStreetNextCalls(index).forEach {
val playerCommittedAmount = getPreviouslyCommittedAmount(it.action.index) ?: 0.0
it.setEffectiveAmount(amount)
}
// verify if the raise is not a call after all
if (computedAction.action.type == Action.Type.RAISE_ALLIN) {
getStreetLastSignificantAction(computedAction.street, index - 1)?.action?.amount?.let { significantActionAmount ->
val askedAmount = significantActionAmount - committedAmount
computedAction.playerRemainingStack?.let { remainingStack ->
if (remainingStack < askedAmount) {
selectAction(index, Action.Type.CALL_ALLIN)
}
}
}
}
}
else -> {}
} }
} }
/*** /***
* 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? { override fun getPreviouslyCommittedAmount(index: Int): Double? {
val computedAction = this.actionForIndex(index) val computedAction = this.actionForIndex(index)
val position = computedAction.position val position = computedAction.position
val street = computedAction.action.street val street = computedAction.action.street
@ -501,45 +475,34 @@ class HHBuilder {
return null return null
} }
/***
* Returns the last significant player action, if any, for the action at the provided [index]
*/
override fun getStreetLastSignificantAction(street: Street, index: Int): ComputedAction? {
val previousActions = this.sortedActions.take(index + 1).filter { it.street == street }
return previousActions.lastOrNull { it.action.isActionSignificant }
}
/*** /***
* 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> { override fun getStreetNextCalls(index: Int): List<ComputedAction> {
val streetNextSignificantIndex = getStreetNextSignificantAction(index)?.action?.index ?: lastIndexOfStreet(index) val streetNextSignificantIndex = getStreetNextSignificantAction(index)?.action?.index ?: this.sortedActions.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)
&& (it.action.type?.isCall ?: false) && (it.action.type?.isCall ?: false)
} }
} }
/***
* Returns the last action index of the street, for the action at [index]
*/
private fun lastIndexOfStreet(index: Int): Int {
val street = this.actionForIndex(index).street
return this.sortedActions.last { it.street == street }.action.index
}
/*** /***
* Returns the last user action, if any, for the action at the provided [index] * Returns the last user action, if any, for the action at the provided [index]
*/ */
private fun getLastUserAction(index: Int): ComputedAction? { private fun getLastPlayerAction(index: Int): ComputedAction? {
val action = this.actionForIndex(index).action val action = this.actionForIndex(index).action
// Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}")
val previousActions = this.sortedActions.take(index) val previousActions = this.sortedActions.take(index)
// Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}")
return previousActions.lastOrNull { it.action.position == action.position } return previousActions.lastOrNull { it.action.position == action.position }
} }
/***
* Returns the last significant player action, if any, for the action at the provided [index]
*/
private fun getStreetLastSignificantAction(street: Street, index: Int): ComputedAction? {
// Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}")
val previousActions = this.sortedActions.take(index + 1).filter { it.street == street }
// Timber.d("**** this.sortedActions.size = ${this.sortedActions.size}")
return previousActions.lastOrNull { it.action.isActionSignificant }
}
/*** /***
* 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]
@ -565,10 +528,7 @@ class HHBuilder {
*/ */
fun setNumberOfPlayers(playerCount: Int) { fun setNumberOfPlayers(playerCount: Int) {
this.handHistory.numberOfPlayers = playerCount this.handHistory.numberOfPlayers = playerCount
this.positions = this.positions = Position.positionsPerPlayers(playerCount)
Position.positionsPerPlayers(
playerCount
)
} }
/*** /***
@ -618,6 +578,7 @@ 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) {
this.lastValue = value
val row = this.rowRepresentables[currentSelection.index] as CardsRow val row = this.rowRepresentables[currentSelection.index] as CardsRow
row.valueSelected(value) row.valueSelected(value)
} }
@ -639,10 +600,9 @@ class HHBuilder {
* Deletes all the card of the selected street * Deletes all the card of the selected street
*/ */
fun clearCards(currentSelection: HHSelection) { fun clearCards(currentSelection: HHSelection) {
this.lastValue = null
val row = this.rowRepresentables[currentSelection.index] as CardsRow val row = this.rowRepresentables[currentSelection.index] as CardsRow
row.clear() row.clear()
} }
/*** /***
@ -807,5 +767,25 @@ class HHBuilder {
} }
// Card Centralizer
private val usedCards: List<Card>
get() {
// TODO is my list always stored in the handHistory, or not?
return listOf()
}
private var lastValue: Card.Value? = null
override fun isValueAvailable(value: Card.Value): Boolean {
val usedValues = this.usedCards.filter { it.value == value.value }
return usedValues.size < 4
}
override fun isSuitAvailable(suit: Card.Suit, value: Card.Value?): Boolean {
val usedValues = this.usedCards.filter { it.value == value?.value }
return !usedValues.map { it.suit }.contains(suit)
}
} }

@ -74,7 +74,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
val handHistoryId = this.arguments?.getString(BundleKey.PRIMARY_KEY.value) val handHistoryId = this.arguments?.getString(BundleKey.PRIMARY_KEY.value)
val builder = handHistoryId?.let { val builder = handHistoryId?.let {
val handHistory = getRealm().findById<HandHistory>(it) ?: throw PAIllegalStateException("HandHistory not found") val handHistory = getRealm().findById<HandHistory>(it)
?: throw PAIllegalStateException("HandHistory not found")
HHBuilder( HHBuilder(
handHistory handHistory
) )
@ -130,6 +131,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL
} }
this.keyboard.keyboardListener = this this.keyboard.keyboardListener = this
this.keyboard.setCardCentralizer(this.model.cardCentralizer)
} }

@ -7,6 +7,7 @@ import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.realm.handhistory.Action import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.Card import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.modules.handhistory.views.CardCentralizer
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import timber.log.Timber import timber.log.Timber
@ -39,6 +40,11 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource {
return this.builder.indexOfComputedAction(currentSelection.index) return this.builder.indexOfComputedAction(currentSelection.index)
} }
val cardCentralizer: CardCentralizer
get() {
return this.builder
}
// Action // Action
fun actionSelected(action: Action.Type): List<Int>? { fun actionSelected(action: Action.Type): List<Int>? {

@ -14,13 +14,15 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.holder.RowViewHolder import net.pokeranalytics.android.ui.view.holder.RowViewHolder
import timber.log.Timber import timber.log.Timber
class CardSuitAdapter(var keyboardListener: KeyboardListener) : class CardSuitAdapter(private var keyboardListener: KeyboardListener) :
RecyclerView.Adapter<RecyclerView.ViewHolder>(), RecyclerView.Adapter<RecyclerView.ViewHolder>(),
RowRepresentableDataSource, RowRepresentableDelegate, RecyclerAdapter { RowRepresentableDataSource, RowRepresentableDelegate, RecyclerAdapter {
override var dataSource: RowRepresentableDataSource = this override var dataSource: RowRepresentableDataSource = this
override var delegate: RowRepresentableDelegate? = this override var delegate: RowRepresentableDelegate? = this
var centralizer: CardCentralizer? = null
private val suits = Card.Suit.displaySuits private val suits = Card.Suit.displaySuits
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -59,4 +61,9 @@ class CardSuitAdapter(var keyboardListener: KeyboardListener) :
keyboardListener.cardSuitSelected(this.suits[position]) keyboardListener.cardSuitSelected(this.suits[position])
} }
override fun isEnabled(row: RowRepresentable, tag: Int): Boolean {
val suit = row as Card.Suit
return this.centralizer?.isSuitAvailable(suit, null) ?: true
}
} }

@ -21,6 +21,8 @@ class CardValueAdapter(var keyboardListener: KeyboardListener) :
override var dataSource: RowRepresentableDataSource = this override var dataSource: RowRepresentableDataSource = this
override var delegate: RowRepresentableDelegate? = this override var delegate: RowRepresentableDelegate? = this
var centralizer: CardCentralizer? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_cell, parent, false) val layout = LayoutInflater.from(parent.context).inflate(R.layout.row_cell, parent, false)
return RowViewHolder(layout) return RowViewHolder(layout)
@ -57,4 +59,9 @@ class CardValueAdapter(var keyboardListener: KeyboardListener) :
keyboardListener.cardValueSelected(Card.Value.values[position]) keyboardListener.cardValueSelected(Card.Value.values[position])
} }
override fun isEnabled(row: RowRepresentable, tag: Int): Boolean {
val value = row as Card.Value
return this.centralizer?.isValueAvailable(value) ?: true
}
} }

@ -9,6 +9,12 @@ import kotlinx.android.synthetic.main.view_hand_keyboard_action.view.closeButton
import kotlinx.android.synthetic.main.view_hand_keyboard_card.view.* import kotlinx.android.synthetic.main.view_hand_keyboard_card.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.Card
interface CardCentralizer {
fun isValueAvailable(value: Card.Value): Boolean
fun isSuitAvailable(suit: Card.Suit, value: Card.Value?): Boolean
}
class KeyboardCardView(context: Context) : AbstractKeyboardView(context) { class KeyboardCardView(context: Context) : AbstractKeyboardView(context) {
@ -64,4 +70,9 @@ class KeyboardCardView(context: Context) : AbstractKeyboardView(context) {
} }
fun setCardCentralizer(centralizer: CardCentralizer) {
this.cardValueAdapter.centralizer = centralizer
this.cardSuitAdapter.centralizer = centralizer
}
} }

@ -111,6 +111,11 @@ class KeyboardContainer(context: Context, attrs: AttributeSet?) : FrameLayout(co
actionKeyboard.setAvailableActions(availableActions) actionKeyboard.setAvailableActions(availableActions)
} }
fun setCardCentralizer(centralizer: CardCentralizer) {
val cardKeyboard = this.keyboards[HHKeyboard.CARD] as KeyboardCardView
cardKeyboard.setCardCentralizer(centralizer)
}
// private fun loadView(layoutId: Int) { // private fun loadView(layoutId: Int) {
// val layoutInflater = LayoutInflater.from(context) // val layoutInflater = LayoutInflater.from(context)
// constraintLayout = layoutInflater.inflate(layoutId, this, false) as ConstraintLayout // constraintLayout = layoutInflater.inflate(layoutId, this, false) as ConstraintLayout

Loading…
Cancel
Save