More and more progress

hh
Laurent 6 years ago
parent 9ba73dc7c1
commit 7082ef7c23
  1. 307
      app/src/main/java/net/pokeranalytics/android/model/handhistory/HHBuilder.kt
  2. 4
      app/src/main/java/net/pokeranalytics/android/model/handhistory/HandSetup.kt
  3. 29
      app/src/main/java/net/pokeranalytics/android/model/realm/Game.kt
  4. 14
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/Action.kt
  5. 14
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt
  6. 8
      app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/PlayerSetup.kt
  7. 14
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryAdapter.kt
  8. 12
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt
  9. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryViewModel.kt
  10. 129
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/CardsRow.kt
  11. 12
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/PlayerCardsRow.kt
  12. 23
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/views/StreetCardView.kt
  13. 3
      app/src/main/res/values/strings.xml

@ -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<Position> = linkedSetOf()
/***
* The maximum number of cards in a player's hand
*/
private var playerHandMaxCards: Int? = null
set(value) {
field = value
this.rowRepresentables.filterIsInstance<PlayerCardsRow>().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<Int>? {
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<ComputedAction>()
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)
}
/***
@ -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 ->
// verify if the raise is not a call after all
if (computedAction.action.type == Action.Type.RAISE_ALLIN) {
getStreetLastSignificantAction(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 {
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<ComputedAction> {
val nextSignificantIndex = getNextSignificantAction(index)?.action?.index ?: lastIndexOfStreet(index)
private fun getStreetNextCalls(index: Int) : List<ComputedAction> {
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<StreetCardView>().forEach {
it.cards = this.boardManager.allCards
// BoardChangedListener
/***
* Called when the board has changed
*/
fun boardChanged(cards: List<Card>) {
this.rowRepresentables.filterIsInstance<StreetCardsRow>().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<RowRepresentable>, 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)
}

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

@ -30,7 +30,6 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc
val rowRepresentation : List<RowRepresentable> by lazy {
val rows = ArrayList<RowRepresentable>()
rows.add(SimpleRow.NAME)
// rows.addAll(GameRow.values())
rows
}
}
@ -62,7 +61,7 @@ open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSourc
}
override fun adapterRows(): List<RowRepresentable>? {
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<Session>().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")
}
}

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

@ -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<Card> {
return this.playerSetups.first { it.position == position }.cards
return this.playerSetups.firstOrNull { it.position == position }?.cards ?: listOf()
}
}

@ -26,4 +26,12 @@ open class PlayerSetup : RealmObject() {
*/
var cards: RealmList<Card> = RealmList()
fun cardValueSelected(value: Card.Value) {
}
fun cardSuitSelected(suit: Card.Suit) {
}
}

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

@ -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() {

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

@ -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<Card>) : HandHistoryRow {
var cards: MutableList<Card> = 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<Card>) : 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<Card> = listOf(), var maxCards: Int? = null) : CardsRow(cards) {
override val viewType: Int = HandRowType.PLAYER_SUMMARY.ordinal
override fun cardLimit() : Int? {
return this.maxCards
}
}

@ -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<Card> = listOf()) : RowRepresentable {
override val viewType: Int = HandRowType.PLAYER_SUMMARY.ordinal
}

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

@ -787,6 +787,9 @@
<string name="bet">bet</string>
<string name="raise">raise</string>
<string name="allin">allin</string>
<string name="ballin">b_allin</string>
<string name="callin">c_allin</string>
<string name="rallin">r_allin</string>
<string name="backspace"></string>
</resources>

Loading…
Cancel
Save