diff --git a/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt b/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt index d930fc10..7473668d 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt @@ -6,8 +6,9 @@ import net.pokeranalytics.android.model.realm.handhistory.Action import net.pokeranalytics.android.model.realm.handhistory.Card import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.ui.modules.handhistory.HandRowType +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.StreetCardView +import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.util.extensions.formatted @@ -22,7 +23,7 @@ enum class HHKeyboard { class HHSelection(var index: Int, var keyboard: HHKeyboard) -class HHBuilder : BoardChangedListener { +class HHBuilder { /*** * The hand history @@ -42,13 +43,24 @@ class HHBuilder : BoardChangedListener { /*** * The board cards sorted by position */ - private lateinit var boardManager: BoardManager +// private lateinit var boardManager: BoardManager /*** * A LinkedHashSet containing the sorted positions at the table */ var positions: LinkedHashSet = linkedSetOf() + /*** + * The maximum number of cards in a player's hand + */ + private var playerHandMaxCards: Int? = null + set(value) { + field = value + this.rowRepresentables.filterIsInstance().forEach { + it.maxCards = value + } + } + /*** * Creates a builder using a [handSetup] * Also creates a new Hand History and configures it according to the [handSetup] @@ -56,6 +68,7 @@ class HHBuilder : BoardChangedListener { constructor(handSetup: HandSetup) { val handHistory = HandHistory() handHistory.configure(handSetup) + this.playerHandMaxCards = handSetup.game?.playerHandMaxCards this.handHistory = handHistory } @@ -92,7 +105,7 @@ class HHBuilder : BoardChangedListener { } this.sortedActions = computedActions - this.boardManager = BoardManager(this.handHistory.board, this) +// this.boardManager = BoardManager(this.handHistory.board, this) this.createRowRepresentation() } @@ -143,6 +156,7 @@ class HHBuilder : BoardChangedListener { /*** * Selects an action type for the action at the provided [index] + * In case of UNDEFINED_ALLIN, we define which type of allin it is. * If the user changes the current action, * for convenience we remove all the following actions to avoid managing complex cases * Also calculates the player effective amounts in proper cases @@ -152,15 +166,43 @@ class HHBuilder : BoardChangedListener { */ fun selectAction(index: Int, actionType: Action.Type) : List? { - Timber.d(">>> Sets $actionType at index: $index") + var type = actionType val computedAction = this.actionForIndex(index) - if (computedAction.action.type != actionType) { - computedAction.action.type = actionType + + // define allin type + if (type == Action.Type.UNDEFINED_ALLIN) { + val significant = getStreetLastSignificantAction(index) + if (significant != null) { + val betAmount = significant.action.amount + val remainingStack = computedAction.playerRemainingStack + if (remainingStack != null && betAmount != null && remainingStack < betAmount) { + type = Action.Type.CALL_ALLIN + } else { + type = Action.Type.RAISE_ALLIN + } + } else { + type = Action.Type.BET_ALLIN + } + } + + Timber.d(">>> Sets $type at index: $index") + + var structureModified = 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) + } } - when (actionType) { + // define action amounts if possible + when (type) { Action.Type.CALL -> { val significantAction = getStreetLastSignificantAction(index) ?: throw PAIllegalStateException("There must be a previously set significant action for a call to be set") @@ -175,26 +217,28 @@ class HHBuilder : BoardChangedListener { Action.Type.STRADDLE -> { // TODO } + Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN, Action.Type.UNDEFINED_ALLIN -> { + computedAction.action.amount = computedAction.playerRemainingStack + } else -> {} } - val dropedIndex = dropNextActionsIfNecessary(index) - val structureModified = this.updateFollowupActions(index) + structureModified = this.updateFollowupActions(index) || structureModified // Automatically sets action for the previous empty actions val modifiedActions = mutableListOf() getPreviousEmptyActions(index).forEach { modifiedActions.add(it) val lastSignificant = getStreetLastSignificantAction(index) - if (lastSignificant != null) { - it.action.type = Action.Type.FOLD + it.action.type = if (lastSignificant != null) { + Action.Type.FOLD } else { - it.action.type = Action.Type.CHECK + Action.Type.CHECK } } - if (dropedIndex != null || structureModified) return null + if (structureModified) return null return modifiedActions.map { this.rowRepresentables.indexOf(it) } } @@ -212,11 +256,21 @@ class HHBuilder : BoardChangedListener { addsFollowupActionsIfNecessary(index) } 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 + removeActionsIfNecessary(index) + } createNextStreetIfNecessary(index) } else -> false } + } + /*** + * Recreates the actions after [index] + */ + private fun removeActionsIfNecessary(index: Int) { + this.sortedActions = this.sortedActions.take(index + 1).toMutableList() + addsFollowupActionsIfNecessary(index) } /*** @@ -266,16 +320,16 @@ class HHBuilder : BoardChangedListener { this.rowRepresentables.add(computedAction) } - /*** - * Returns the list of position still in play before the given [index] - */ - private fun activePositions(index: Int) : MutableList { - val oustedPositions = this.sortedActions.take(index + 1) - .filter { it.action.type?.isPullOut ?: false } - .map { it.position } + /*** + * Returns the list of position still in play before the given [index] + */ + private fun activePositions(index: Int): MutableList { + val oustedPositions = this.sortedActions.take(index + 1) + .filter { it.action.type?.isPullOut ?: false } + .map { it.position } - val allPositions = this.positions - allPositions.removeAll(oustedPositions) + val allPositions = this.positions + allPositions.removeAll(oustedPositions) return allPositions.toMutableList() } @@ -284,56 +338,12 @@ class HHBuilder : BoardChangedListener { * Returns true if a street has been created */ private fun createNextStreetIfNecessary(index: Int) : Boolean { - val nextStreet = isStreetActionClosed(index) if (nextStreet != null) { createStreet(nextStreet) return true } return false - -// val computedAction = this.actionForIndex(index) -// val currentStreet = this.actionForIndex(index).action.street -// -// getStreetLastSignificantAction(index)?.let { significantAction -> -// -// val activePositions = activePositions(index) -// val activePlayerCount = activePositions.size // don't move this line because of removes -// -// activePositions.remove(significantAction.position) -// -// val significantIndex = significantAction.action.index -// for (i in significantIndex + 1 until this.sortedActions.size) { -// val ca = this.sortedActions[i] -// val type = ca.action.type -// if (type != null && !type.isSignificant) { // Calls and folds -// activePositions.remove(ca.position) -// } -// } -// -// if (activePositions.isEmpty()) { -// -// if (activePlayerCount >= 2 && currentStreet != Street.RIVER) { -// createStreet(currentStreet.next) -// } else { -// createStreet(Street.SUMMARY) -// } -// return true -// } -// -// } -// -// val allCheck = this.sortedActions.filter { it.action.street == currentStreet }.all { it.action.type == Action.Type.CHECK } -// if (allCheck) { -// if (currentStreet != Street.RIVER) { -// createStreet(currentStreet.next) -// } else { -// createStreet(Street.SUMMARY) -// } -// return true -// } -// -// return false } /*** @@ -377,15 +387,25 @@ class HHBuilder : BoardChangedListener { * following an action change. * We want drop all non-auto added rows after the index */ - private fun dropNextActionsIfNecessary(index: Int) : Int? { -// val dropIndex = index + 1 // TODO determine dropIndex -// this.sortedActions = this.sortedActions.take(dropIndex) - return null + private fun dropNextActionsIfNecessary(index: Int) : Boolean { + + val street = this.actionForIndex(index).action.street + val firstIndexOfStreet = this.sortedActions.first { it.action.street == street }.action.index + val activePositions = activePositions(firstIndexOfStreet) + val defaultRowsCount = when (street) { + Street.PREFLOP -> activePositions.size + 2 + else -> activePositions.size + } + val sizeBefore = this.sortedActions.size + this.sortedActions = this.sortedActions.take(index + defaultRowsCount).toMutableList() + val sizeAfter = this.sortedActions.size + + return sizeAfter != sizeBefore } /*** * Sets the amount for the action at the provided [index] - * In the case of an UNDEFINED_ALLIN, define if it's a RAISE_ALLIN or a CALL_ALLIN + * In the case of a RAISE_ALLIN, check if it's a CALL_ALLIN */ fun setAmount(index: Int, amount: Double) { @@ -397,36 +417,27 @@ class HHBuilder : BoardChangedListener { when (computedAction.action.type) { Action.Type.BET, Action.Type.RAISE, Action.Type.BET_ALLIN, Action.Type.RAISE_ALLIN -> { - getNextCalls(index).forEach { + getStreetNextCalls(index).forEach { it.setEffectiveAmount(amount) } - } - Action.Type.UNDEFINED_ALLIN -> { - getStreetLastSignificantAction(index)?.action?.amount?.let { significantActionAmount -> - - val committedAmount = getPreviousCommittedAmount(index) ?: 0.0 - val askedAmount = significantActionAmount - committedAmount + // verify if the raise is not a call after all + if (computedAction.action.type == Action.Type.RAISE_ALLIN) { - computedAction.playerRemainingStack?.let { remainingStack -> + getStreetLastSignificantAction(index)?.action?.amount?.let { significantActionAmount -> + val committedAmount = getPreviousCommittedAmount(index) ?: 0.0 + val askedAmount = significantActionAmount - committedAmount - if (remainingStack > askedAmount) { - selectAction(index, Action.Type.RAISE_ALLIN) - } else { - selectAction(index, Action.Type.CALL_ALLIN) + computedAction.playerRemainingStack?.let { remainingStack -> + if (remainingStack < askedAmount) { + selectAction(index, Action.Type.CALL_ALLIN) + } } - - } ?: run { - selectAction(index, Action.Type.RAISE_ALLIN) } - - } ?: run { - selectAction(index, Action.Type.RAISE_ALLIN) } } else -> {} } - } /*** @@ -467,11 +478,11 @@ class HHBuilder : BoardChangedListener { /*** * Returns all "CALL" ComputedAction between the [index] and the next significant action */ - private fun getNextCalls(index: Int) : List { - val nextSignificantIndex = getNextSignificantAction(index)?.action?.index ?: lastIndexOfStreet(index) + private fun getStreetNextCalls(index: Int) : List { + val streetNextSignificantIndex = getStreetNextSignificantAction(index)?.action?.index ?: lastIndexOfStreet(index) return this.sortedActions.filter { - it.action.index in (index + 1) until nextSignificantIndex && - (it.action.type == Action.Type.CALL || it.action.type == Action.Type.CALL_ALLIN) + it.action.index in ((index + 1) until streetNextSignificantIndex) + && (it.action.type?.isCall ?: false) } } @@ -508,7 +519,7 @@ class HHBuilder : BoardChangedListener { /*** * Returns the next significant player action in the street, if any, for the action at the provided [index] */ - private fun getNextSignificantAction(index: Int): ComputedAction? { + private fun getStreetNextSignificantAction(index: Int): ComputedAction? { val street = this.actionForIndex(index).action.street val nextActions = this.sortedActions.drop(index + 1).filter { it.action.street == street } return nextActions.firstOrNull { it.action.isActionSignificant } @@ -544,7 +555,7 @@ class HHBuilder : BoardChangedListener { * Finds the index of the first incomplete action, if existing * If the same selection is the same than current, pass to the next row */ - fun findIndexForEdition(startIndex: Int, keyboard: HHKeyboard? = null): HHSelection? { + fun findIndexForEdition(startIndex: Int): HHSelection? { this.rowRepresentables.forEachIndexed { index, rowRepresentable -> @@ -579,12 +590,21 @@ class HHBuilder : BoardChangedListener { * Adds a card with the selected [value] */ fun cardValueSelected(value: Card.Value, currentSelection: HHSelection) { - when (this.rowRepresentables[currentSelection.index]) { - is StreetCardView -> { - val card = Card.newInstance(value.value) - this.boardManager.add(card) - } - } + + val row = this.rowRepresentables[currentSelection.index] as CardsRow + 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) +// } +// } } /*** @@ -593,36 +613,49 @@ class HHBuilder : BoardChangedListener { */ fun cardSuitSelected(suit: Card.Suit, currentSelection: HHSelection) { - when (val row = this.rowRepresentables[currentSelection.index]) { - is StreetCardView -> { - - val addNewCard = this.boardManager.lastCard(row.street)?.let { - if (it.suit != null) { - true - } else { - it.suit = suit - false - } - } ?: true + val row = this.rowRepresentables[currentSelection.index] as CardsRow + row.suitSelected(suit) - if (addNewCard) { - val card = Card.newInstance(suit = suit) - this.boardManager.add(card) - } + // 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) +// } +// } } /*** * Deletes all the card of the selected street */ fun clearCards(currentSelection: HHSelection) { - when (val row = this.rowRepresentables[currentSelection.index]) { - is StreetCardView -> { - this.boardManager.clearStreet(row.street) - } - } + + val row = this.rowRepresentables[currentSelection.index] as CardsRow + row.clear() + +// when (val row = this.rowRepresentables[currentSelection.index]) { +// is StreetCardsRow -> { +// this.boardManager.clearStreet(row.street) +// } +// } } @@ -633,22 +666,41 @@ class HHBuilder : BoardChangedListener { */ fun deleteLastCardProperty(currentSelection: HHSelection) { - when (val row = this.rowRepresentables[currentSelection.index]) { - is StreetCardView -> { - this.boardManager.lastCard(row.street)?.let { card -> - if (card.value != null && card.suit != null) { - card.suit = null - } else { - this.boardManager.remove(card) - } - } - } + val row = this.rowRepresentables[currentSelection.index] as CardsRow + 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) +// } +// } +// } +// } + } + + /*** + * When a card selection is ended, + * sets the playerHandMaxCards with the number of cards set to the player + */ + fun cardSelectionEnded(index: Int) { + val cardsRow = this.rowRepresentables[index] as CardsRow + if (cardsRow is PlayerCardsRow) { + this.playerHandMaxCards = cardsRow.cards.size } } - override fun boardChanged() { - this.rowRepresentables.filterIsInstance().forEach { - it.cards = this.boardManager.allCards + // BoardChangedListener + + /*** + * Called when the board has changed + */ + fun boardChanged(cards: List) { + this.rowRepresentables.filterIsInstance().forEach { +// it.cards = cards } } @@ -684,7 +736,7 @@ class HHBuilder : BoardChangedListener { activePositions(lastActionIndex).forEach { val positionIndex = this.positions.indexOf(it) - val playerCardsRow = PlayerCardsRow(it, this.handHistory.cardsForPosition(positionIndex)) + val playerCardsRow = PlayerCardsRow(it, this.handHistory.cardsForPosition(positionIndex), this.playerHandMaxCards) this.rowRepresentables.add(playerCardsRow) } } @@ -758,11 +810,12 @@ class HHBuilder : BoardChangedListener { * Adds a [street] header to a [rowRepresentables] list with a given [potSize] */ private fun addStreetHeader(rowRepresentables: MutableList, street: Street, potSize: Double) { - val headerView = CustomizableRowRepresentable(customViewType = HandRowType.HEADER, resId = street.resId, value = potSize.formatted()) + val potString = if (potSize > 0) potSize.formatted() else null + val headerView = CustomizableRowRepresentable(customViewType = HandRowType.HEADER, resId = street.resId, value = potString) rowRepresentables.add(headerView) if (street.totalBoardCards > 0) { - val boardView = StreetCardView(street, this.handHistory.cardsForStreet(street)) + val boardView = StreetCardsRow(street, this.handHistory.cardsForStreet(street)) rowRepresentables.add(boardView) } diff --git a/app/src/main/java/net/pokeranalytics/android/model/handhistory/HandSetup.kt b/app/src/main/java/net/pokeranalytics/android/model/handhistory/HandSetup.kt index a5e09487..a9ec75b9 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/handhistory/HandSetup.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/handhistory/HandSetup.kt @@ -1,5 +1,7 @@ package net.pokeranalytics.android.model.handhistory +import net.pokeranalytics.android.model.realm.Game + class HandSetup { var smallBlind: Double? = null @@ -12,4 +14,6 @@ class HandSetup { var bigBlindAnte: Boolean = false + var game: Game? = null + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt index da713f05..951f1c6f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt @@ -30,7 +30,6 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc val rowRepresentation : List by lazy { val rows = ArrayList() rows.add(SimpleRow.NAME) -// rows.addAll(GameRow.values()) rows } } @@ -62,7 +61,7 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc } override fun adapterRows(): List? { - return Game.rowRepresentation + return rowRepresentation } override fun stringForRow(row: RowRepresentable): String { @@ -103,4 +102,30 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc override fun isValidForDelete(realm: Realm): Boolean { return realm.where().equalTo("game.id", id).findAll().isEmpty() } + + val playerHandMaxCards: Int? + get() { + return when { + isHoldem -> 2 + isOmaha5 -> 5 + isOmaha4 -> 4 + else -> null + } + } + + private val isHoldem: Boolean + get() { + return name.contains("texas", ignoreCase = true) || name.contains("holdem", ignoreCase = true) || name.contains("hold'em", ignoreCase = true) || name.contains("HE") + } + + private val isOmaha4: Boolean + get() { + return name.contains("omaha", ignoreCase = true) || name.contains("PLO", ignoreCase = true) + } + + private val isOmaha5: Boolean + get() { + return name.contains("5") + } + } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Action.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Action.kt index 0e24aecc..6bba2086 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Action.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Action.kt @@ -21,9 +21,9 @@ open class Action : RealmObject() { BET(R.string.bet), RAISE(R.string.raise), UNDEFINED_ALLIN(R.string.allin), - CALL_ALLIN(R.string.allin), - BET_ALLIN(R.string.allin), - RAISE_ALLIN(R.string.allin); + CALL_ALLIN(R.string.callin), + BET_ALLIN(R.string.ballin), + RAISE_ALLIN(R.string.rallin); val isSignificant: Boolean get() { @@ -53,6 +53,14 @@ open class Action : RealmObject() { } } + val isCall: Boolean + get() { + return when (this) { + CALL, CALL_ALLIN -> true + else -> false + } + } + val requiresOpponentDecision: Boolean get() { return when(this) { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt index 96939d7d..a4d80765 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt @@ -105,7 +105,7 @@ open class HandHistory : RealmObject(), RowRepresentable, Identifiable, Filterab handSetup.bigBlind?.let { this.bigBlind = it } this.addAction(0, 0, Action.Type.POST_SB, this.smallBlind) -// this.addAction(1, 1, Action.Type.POST_BB, this.bigBlind) + this.addAction(1, 1, Action.Type.POST_BB, this.bigBlind) val totalActions = this.actions.size @@ -128,8 +128,18 @@ open class HandHistory : RealmObject(), RowRepresentable, Identifiable, Filterab return this.board.sortedBy { it.index }.take(street.totalBoardCards).toMutableList() } + fun playerSetupForPosition(position: Int) : PlayerSetup { + this.playerSetups.firstOrNull { it.position == position }?.let { + return it + } + + val ps = PlayerSetup() + ps.position = position + return ps + } + fun cardsForPosition(position: Int): List { - return this.playerSetups.first { it.position == position }.cards + return this.playerSetups.firstOrNull { it.position == position }?.cards ?: listOf() } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/PlayerSetup.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/PlayerSetup.kt index b29d772d..078d94ea 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/PlayerSetup.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/PlayerSetup.kt @@ -26,4 +26,12 @@ open class PlayerSetup : RealmObject() { */ var cards: RealmList = RealmList() + fun cardValueSelected(value: Card.Value) { + + } + + fun cardSuitSelected(suit: Card.Suit) { + + } + } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt index 1b9104b4..af276750 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt @@ -23,7 +23,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.extensions.hideKeyboard import net.pokeranalytics.android.ui.modules.handhistory.views.PlayerCardsRow -import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardView +import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.holder.RowViewHolder import net.pokeranalytics.android.ui.view.rowrepresentable.ViewIdentifier @@ -258,7 +258,7 @@ class HandHistoryAdapter( this.currentPosition = position - val streetCardView = row as StreetCardView + val streetCardView = row as StreetCardsRow val street = streetCardView.street itemView.findViewById(R.id.flopEditText)?.let { flopEditText -> @@ -269,6 +269,10 @@ class HandHistoryAdapter( val flop = streetCardView.cards.take(3) val text = flop.formatted(itemView.context) flopEditText.setText(text) + + val selected = adapter.dataSource.isSelected(position, row, Street.FLOP.ordinal) + if (!selected) flopEditText.clearFocus() + } itemView.findViewById(R.id.turnEditText)?.let { turnEditText -> @@ -281,6 +285,9 @@ class HandHistoryAdapter( } else { turnEditText.text = null } + + val selected = adapter.dataSource.isSelected(position, row, Street.FLOP.ordinal) + if (!selected) turnEditText.clearFocus() } itemView.findViewById(R.id.riverEditText)?.let { riverEditText -> @@ -293,6 +300,9 @@ class HandHistoryAdapter( } else { riverEditText.text = null } + + val selected = adapter.dataSource.isSelected(position, row, Street.FLOP.ordinal) + if (!selected) riverEditText.clearFocus() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt index a7db02b2..408f5d21 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt @@ -17,7 +17,8 @@ import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.modules.handhistory.views.KeyboardListener -import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardView +import net.pokeranalytics.android.ui.modules.handhistory.views.PlayerCardsRow +import net.pokeranalytics.android.ui.modules.handhistory.views.StreetCardsRow import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.util.extensions.findById @@ -199,7 +200,7 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL else -> throw PAIllegalStateException("Unmanaged tag value: $tag") } } - is StreetCardView -> { + is StreetCardsRow, is PlayerCardsRow -> { HHKeyboard.CARD } else -> throw PAIllegalStateException("unmanaged row type: $row") @@ -240,16 +241,12 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL override fun cardValueSelected(value: Card.Value) { this.model.cardValueSelected(value) this.handHistoryAdapter.notifyItemChanged(this.model.currentSelection.index) - - // TODO add test about number of cards before selecting next action? this.findNextActionToEdit() } override fun cardSuitSelected(suit: Card.Suit) { this.model.cardSuitSelected(suit) this.handHistoryAdapter.notifyItemChanged(this.model.currentSelection.index) - - // TODO add test about number of cards? this.findNextActionToEdit() } @@ -259,7 +256,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL } override fun cardSelectionEnded() { -// TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + this.model.cardSelectionEnded() + this.findNextActionToEdit() } override fun cardBackSpaceSelected() { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt index 43dbb394..f10a3541 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt @@ -83,7 +83,7 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource { } fun findIndexForEdition(index: Int): HHKeyboard? { - val selection = this.builder.findIndexForEdition(index, this.selectionLiveData.value?.keyboard) + val selection = this.builder.findIndexForEdition(index) this.selectionLiveData.value = selection return selection?.keyboard } @@ -125,4 +125,8 @@ class HandHistoryViewModel : ViewModel(), RowRepresentableDataSource { return isSelectedIndex && isSelectedAction } + fun cardSelectionEnded() { + this.builder.cardSelectionEnded(this.currentSelection.index) + } + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/CardsRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/CardsRow.kt new file mode 100644 index 00000000..08b33377 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/CardsRow.kt @@ -0,0 +1,129 @@ +package net.pokeranalytics.android.ui.modules.handhistory.views + +import net.pokeranalytics.android.exceptions.PAIllegalStateException +import net.pokeranalytics.android.model.handhistory.HHKeyboard +import net.pokeranalytics.android.model.handhistory.HandHistoryRow +import net.pokeranalytics.android.model.handhistory.Position +import net.pokeranalytics.android.model.handhistory.Street +import net.pokeranalytics.android.model.realm.handhistory.Card +import net.pokeranalytics.android.ui.modules.handhistory.HandRowType + +abstract class CardsRow(cards: List) : HandHistoryRow { + + var cards: MutableList = cards.toMutableList() + private set + + private val MAX_CARDS: Int = 7 + + abstract fun cardLimit() : Int? + + override fun keyboardForCompletion(): HHKeyboard? { + return if (cards.size < cardLimit() ?: MAX_CARDS) { + HHKeyboard.CARD + } else if (cards.last().suit == null) { + HHKeyboard.CARD + } else { + null + } + } + + fun valueSelected(value: Card.Value) { + val card = Card.newInstance(value.value) + this.add(card) + } + + fun suitSelected(suit: Card.Suit) { + + val addNewCard = this.lastCard()?.let { + if (it.suit != null) { + true + } else { + it.suit = suit + false + } + } ?: true + + if (addNewCard) { + val card = Card.newInstance(suit = suit) + this.add(card) + } + } + + protected open fun lastCard() : Card? { + return this.cards.lastOrNull() + } + + /*** + * Adds a card to the board, notifies the listener + */ + private fun add(card: Card) { + + this.cards.lastOrNull()?.let { + if (it.suit == null) { + it.suit = Card.Suit.UNDEFINED + } + } + + if (this.cards.size == 5) { + throw PAIllegalStateException("Can't add anymore cards") + } + + card.index = this.cards.size + + this.cards.add(card) + } + + open fun clear() { + this.cards.clear() + } + + /*** + * Remove the given [card], notifies the listener + */ + private fun remove(card: Card) { + this.cards.remove(card) + } + + /*** + * Delete the last card property + */ + fun deleteLastCardProperty() { + this.lastCard()?.let { card -> + if (card.value != null && card.suit != null) { + card.suit = null + } else { + this.remove(card) + } + } + } + +} + +class StreetCardsRow(var street: Street, cards: List) : CardsRow(cards) { + + override val viewType: Int = HandRowType.STREET.ordinal + + override fun cardLimit() : Int { + return this.street.totalBoardCards + } + + override fun lastCard(): Card? { + return this.cards.lastOrNull { it.street == this.street } + } + + override fun clear() { + this.cards.removeAll { it.street == this.street } + } + + +} + +class PlayerCardsRow(var position: Position, cards: List = listOf(), var maxCards: Int? = null) : CardsRow(cards) { + + override val viewType: Int = HandRowType.PLAYER_SUMMARY.ordinal + + override fun cardLimit() : Int? { + return this.maxCards + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/PlayerCardsRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/PlayerCardsRow.kt deleted file mode 100644 index 1c8d91ad..00000000 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/PlayerCardsRow.kt +++ /dev/null @@ -1,12 +0,0 @@ -package net.pokeranalytics.android.ui.modules.handhistory.views - -import net.pokeranalytics.android.model.handhistory.Position -import net.pokeranalytics.android.model.realm.handhistory.Card -import net.pokeranalytics.android.ui.modules.handhistory.HandRowType -import net.pokeranalytics.android.ui.view.RowRepresentable - -class PlayerCardsRow(var position: Position, var cards: List = listOf()) : RowRepresentable { - - override val viewType: Int = HandRowType.PLAYER_SUMMARY.ordinal - -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt deleted file mode 100644 index ec089d9b..00000000 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt +++ /dev/null @@ -1,23 +0,0 @@ -package net.pokeranalytics.android.ui.modules.handhistory.views - -import net.pokeranalytics.android.model.handhistory.HHKeyboard -import net.pokeranalytics.android.model.handhistory.HandHistoryRow -import net.pokeranalytics.android.model.handhistory.Street -import net.pokeranalytics.android.model.realm.handhistory.Card -import net.pokeranalytics.android.ui.modules.handhistory.HandRowType - -class StreetCardView(var street: Street, var cards: List) : HandHistoryRow { - - override val viewType: Int = HandRowType.STREET.ordinal - - override fun keyboardForCompletion(): HHKeyboard? { - return if (cards.size < street.totalBoardCards) { - HHKeyboard.CARD - } else if (cards.last().suit == null) { - HHKeyboard.CARD - } else { - null - } - } - -} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 60572385..41fe8495 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -787,6 +787,9 @@ bet raise allin + b_allin + c_allin + r_allin