hh
Laurent 6 years ago
parent 301ba027f9
commit 0961a74c15
  1. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt
  2. 60
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt
  3. 126
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt

@ -309,7 +309,7 @@ class ComputedAction(var manager: ActionManager,
get() { return this.action.position }
override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) {
TableDrawer.drawAction(this, configuration, canvas, context)
TableDrawer.drawAction(this.positionIndex, this, configuration, canvas, context)
}
override fun frames(

@ -3,10 +3,18 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer
import android.graphics.RectF
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList
import timber.log.Timber
class ReplayerConfiguration(var handHistory: HandHistory) {
var actionList: ActionList = ActionList(null)
private set
init {
this.actionList.load(this.handHistory)
}
data class Size(var width: Float, var height: Float)
data class Circle(var x: Float, var y: Float, var radius: Float)
data class TextPoint(var x: Float, var y: Float, var fontSize: Float)
@ -25,8 +33,12 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
private var playerCircles = mutableListOf<Circle>()
private var playerNamePoints = mutableListOf<TextPoint>()
private var playerStackPoints = mutableListOf<TextPoint>()
private var playerActionPoints = mutableListOf<TextPoint>()
private var playerCardRects = mutableListOf<List<RectF>>()
private var chipCircles = mutableListOf<Circle>()
private var chipTextPoints = mutableListOf<TextPoint>()
val dealerCircle: Circle
get() {
val rect = this.playerStackRects.last()
@ -59,7 +71,7 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
val playerPerColumn = if (portrait) 4 else 3
val playerPerRow = 12 / playerPerColumn // 3 or 4
this.tableHPadding = width / playerPerRow / 2
this.tableHPadding = width / playerPerRow / 2 * 0.9f
this.tableVPadding = height / playerPerColumn * 0.8f
this.tableRect = RectF(tableHPadding, tableVPadding, width - tableHPadding, height - tableVPadding)
@ -69,7 +81,7 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
val pzWidth = width / playerPerRow
this.playerItemsHeight = pzHeight / 3
this.playerItemsWidth = pzWidth * this.paddingPercentage
this.playerItemsWidth = this.tableHPadding * 2 * this.paddingPercentage
val cardWidth = pzWidth * this.cardsPaddingPercentage / this.maxCards
this.cardSpecs = Size(cardWidth, cardWidth * 1.75f)
@ -94,37 +106,59 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
}
if (portrait && playerCount > 4) { repartition.reverse() } // adjustment for portrait vs landscape
val chipsVerticalOffsetFromStackCenter = this.playerItemsHeight * 0.9f
val chipsHorizontalOffsetFromStackCenter = pzWidth / 2f
var pIndex = -1
repartition.forEachIndexed { index, count ->
val x = width / (count + 1)
val y = height / (count + 1)
var rectCenterX = x
var rectCenterY = y
var rectCenterX: Float
var rectCenterY: Float
var chipXOffset: Float
var chipYOffset: Float
var circleOffset = playerItemsHeight * 1.75f
for (i in 1..count) {
pIndex += 1
Timber.d("Creating dimensions for player $pIndex")
// when the position is in a corner, because we have 3/4 players
// we need an additional offset direction to display the chips
val cornerDirection = when {
count > 2 && i == 1 -> { 1 }
count > 2 && i == count -> { - 1 }
else -> { 0 }
}
when (index) {
0 -> { // bottom
rectCenterX = x * i
rectCenterY = height - this.tableVPadding
circleOffset *= -1
chipXOffset = cornerDirection * chipsHorizontalOffsetFromStackCenter
chipYOffset = -1.25f * chipsVerticalOffsetFromStackCenter
}
1 -> { // left
rectCenterX = this.tableHPadding
rectCenterY = height - y * i
chipXOffset = 1 * chipsHorizontalOffsetFromStackCenter
chipYOffset = cornerDirection * -1 * chipsVerticalOffsetFromStackCenter
}
2 -> { // top
rectCenterX = x * i
rectCenterY = this.tableVPadding
chipXOffset = cornerDirection * -1 * chipsHorizontalOffsetFromStackCenter
chipYOffset = 1 * chipsVerticalOffsetFromStackCenter
}
3 -> { // right
rectCenterX = width - this.tableHPadding
rectCenterY = y * i
chipXOffset = -1 * chipsHorizontalOffsetFromStackCenter
chipYOffset = cornerDirection * chipsVerticalOffsetFromStackCenter
}
else -> throw PAIllegalStateException("can't happen")
}
@ -135,6 +169,11 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
val bottom = rectCenterY + this.playerItemsHeight / 2
this.playerStackRects.add(RectF(left, top, right, bottom))
val chipRadius = this.playerItemsHeight / 4
this.chipCircles.add(Circle(rectCenterX + chipXOffset, rectCenterY + chipYOffset, chipRadius))
val chipTextSize = chipRadius
this.chipTextPoints.add(TextPoint(rectCenterX + chipXOffset, rectCenterY + chipYOffset + 2 * chipTextSize, chipTextSize))
// we give each text zone 1/3rd of the box height, leaving 1/3 for space
// the y given is the bottom of the text rect, giving 1/18th as the offset
// 1 / (3_total_space * 3_each_space * 2_center)
@ -143,6 +182,7 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
val fontSize = this.playerItemsHeight / 3
this.playerNamePoints.add(TextPoint(rectCenterX, rectCenterY - bottomOffset, fontSize))
this.playerStackPoints.add(TextPoint(rectCenterX, rectCenterY + this.playerItemsHeight / 3, fontSize))
this.playerActionPoints.add(TextPoint(rectCenterX, rectCenterY + this.playerItemsHeight / 6, fontSize))
this.playerCircles.add(Circle(rectCenterX, rectCenterY - circleOffset, this.playerItemsHeight / 2))
@ -179,6 +219,14 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
return this.playerCircles[i]
}
fun chipCircle(i: Int): Circle {
return this.chipCircles[i]
}
fun chipText(i: Int): TextPoint {
return this.chipTextPoints[i]
}
fun pointForPlayerName(i: Int): TextPoint {
return this.playerNamePoints[i]
}
@ -187,6 +235,10 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
return this.playerStackPoints[i]
}
fun pointForPlayerAction(i: Int): TextPoint {
return this.playerActionPoints[i]
}
fun cardRects(i: Int): List<RectF> {
return this.playerCardRects[i]
}

@ -4,10 +4,13 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.Action
import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
import net.pokeranalytics.android.util.RANDOM_PLAYER
@ -65,40 +68,30 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
cardTextPaint.textSize = config.cardSpecs.height * .38f
val hh = config.handHistory
val positions = Position.positionsPerPlayers(hh.numberOfPlayers)
for (i in 0 until hh.numberOfPlayers) {
val isHero = (hh.heroIndex == i)
Timber.d("Getting player $i setup ")
val playerSetup = hh.playerSetupForPosition(i)
// Stack zone
val rect = config.stackRectForPlayer(i)
val radius = (rect.bottom - rect.top) / 4
fillPaint.color = context.getColor(R.color.green_darker)
canvas.drawRoundRect(config.stackRectForPlayer(i), radius, radius, this.fillPaint)
strokePaint.color = context.getColor(R.color.green)
canvas.drawRoundRect(config.stackRectForPlayer(i), radius, radius, this.strokePaint)
drawPlayerRectangle(i, playerSetup?.stack, false, config, canvas, context)
// Player portrait zone
val circle = config.circleForPlayer(i)
canvas.drawCircle(circle.x, circle.y, circle.radius, this.fillPaint)
canvas.drawCircle(circle.x, circle.y, circle.radius, this.strokePaint)
val radius = circle.radius
canvas.drawCircle(circle.x, circle.y, radius, this.fillPaint)
canvas.drawCircle(circle.x, circle.y, radius, this.strokePaint)
val playerInitials = playerSetup?.player?.initials ?: RANDOM_PLAYER
this.textPaint.textSize = circle.radius
canvas.drawText(playerInitials, circle.x, circle.y + circle.radius * 0.4f, this.textPaint)
// Player name
val name = playerSetup?.player?.name ?: positions.elementAt(i).value
val pnPoint = config.pointForPlayerName(i)
this.textPaint.textSize = pnPoint.fontSize
canvas.drawText(name, pnPoint.x, pnPoint.y, this.textPaint)
// Player stack
playerSetup?.stack?.formatted?.let { stack ->
val psPoint = config.pointForPlayerStack(i)
this.textPaint.textSize = psPoint.fontSize
canvas.drawText(stack, psPoint.x, psPoint.y, this.textPaint)
this.textPaint.textSize = radius
canvas.drawText(playerInitials, circle.x, circle.y + radius * 0.4f, this.textPaint)
// Player picture
playerSetup?.player?.picture?.let { picturePath ->
val pictureBitmap = RoundedBitmapDrawableFactory.create(context.resources, picturePath)
pictureBitmap.setAntiAlias(true)
pictureBitmap.cornerRadius = circle.radius
pictureBitmap.bitmap?.let { bitmap ->
val pictureRect = RectF(circle.x - radius, circle.y - radius, circle.x + radius, circle.y + radius)
canvas.drawBitmap(bitmap, null, pictureRect, null)
}
}
// Dealer button
@ -107,10 +100,35 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
canvas.drawCircle(dealerCircle.x, dealerCircle.y, dealerCircle.radius, fillPaint)
this.strokePaint.color = context.getColor(R.color.white)
canvas.drawCircle(dealerCircle.x, dealerCircle.y, dealerCircle.radius, strokePaint)
this.textPaint.textSize = dealerCircle.radius
canvas.drawText("D", dealerCircle.x, dealerCircle.y + this.textPaint.textSize / 3, this.textPaint)
val cardRects = config.cardRects(i)
drawCards(i, config, canvas, context)
// val blinds = config.actionList.filter { it.action.type?.isBlind ?: false }
// blinds.forEach { action ->
// drawAction(i, action, config, canvas, context)
// }
val chipCircle = config.chipCircle(i)
this.fillPaint.color = context.getColor(R.color.green)
canvas.drawCircle(chipCircle.x, chipCircle.y, chipCircle.radius, this.fillPaint)
val chipText = config.chipText(i)
this.textPaint.textSize = chipText.fontSize
this.textPaint.color = context.getColor(R.color.white)
canvas.drawText("2000", chipText.x, chipText.y, this.textPaint)
}
}
private fun drawCards(playerIndex: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
val playerSetup = config.handHistory.playerSetupForPosition(playerIndex)
val cardRects = config.cardRects(playerIndex)
val cards = playerSetup?.cards
val isHero = (config.handHistory.heroIndex == playerIndex)
cardRects.forEachIndexed { j, cardRect ->
if (j < cards?.size ?: 0 && (config.showVillainHands || isHero)) { // show card
@ -138,13 +156,63 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
}
fun drawAction(i: Int, action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
// show that action is on the player by highlighting
drawPlayerRectangle(i, null, true, config, canvas, context)
// show action name : call, bet, check...
drawAction(i, action.action.type!!, config, canvas, context)
// show chips image + text, if applicable
// show pot updates, if applicable
}
/***
* [i] is the player position in the hand
*/
private fun drawPlayerRectangle(i: Int, stack: Double?, highlighted: Boolean, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
val rect = config.stackRectForPlayer(i)
val rectRadius = (rect.bottom - rect.top) / 4
val color = if (highlighted) R.color.green_diamond_dark else R.color.green_darker
fillPaint.color = context.getColor(color)
canvas.drawRoundRect(config.stackRectForPlayer(i), rectRadius, rectRadius, this.fillPaint)
strokePaint.color = context.getColor(R.color.green)
canvas.drawRoundRect(config.stackRectForPlayer(i), rectRadius, rectRadius, this.strokePaint)
drawPositionAndStack(i, stack, config, canvas, context)
}
fun drawStreet(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
private fun drawPositionAndStack(i: Int, stack: Double?, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
val hh = config.handHistory
// Player position
val positions = Position.positionsPerPlayers(hh.numberOfPlayers)
val name = positions.elementAt(i).value
val pnPoint = config.pointForPlayerName(i)
this.textPaint.textSize = pnPoint.fontSize
canvas.drawText(name, pnPoint.x, pnPoint.y, this.textPaint)
// Player stack
val psPoint = config.pointForPlayerStack(i)
this.textPaint.textSize = psPoint.fontSize
val stackFormatted = stack?.formatted ?: ""
canvas.drawText(stackFormatted, psPoint.x, psPoint.y, this.textPaint)
}
private fun drawAction(i: Int, type: Action.Type, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
val pnPoint = config.pointForPlayerAction(i)
this.textPaint.textSize = pnPoint.fontSize
canvas.drawText(type.name, pnPoint.x, pnPoint.y, this.textPaint)
}
fun drawAction(action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
fun drawStreet(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
}

Loading…
Cancel
Save