Skip to content

Commit

Permalink
Auto-end games when 1 player left, show end game message
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssaruth committed Apr 21, 2024
1 parent 59b29bc commit e31864e
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 16 deletions.
40 changes: 40 additions & 0 deletions src/main/kotlin/dartzee/screen/game/AbstractGameStatisticsPanel.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package dartzee.screen.game

import dartzee.core.bean.ScrollTable
import dartzee.core.bean.makeTransparentTextPane
import dartzee.core.util.MathsUtil
import dartzee.core.util.TableUtil
import dartzee.core.util.addUnique
import dartzee.core.util.alignCentrally
import dartzee.core.util.append
import dartzee.core.util.setFontSize
import dartzee.game.UniqueParticipantName
import dartzee.game.state.AbstractPlayerState
import dartzee.game.state.IWrappedParticipant
import dartzee.`object`.Dart
import dartzee.utils.InjectedThings
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Dimension
import javax.swing.JPanel
import javax.swing.UIManager
import javax.swing.border.EmptyBorder
Expand Down Expand Up @@ -67,6 +73,40 @@ abstract class AbstractGameStatisticsPanel<PlayerState : AbstractPlayerState<Pla
if (isSufficientData()) {
buildTableModel()
}

val activeCount = playerStates.count { it.wrappedParticipant.participant.isActive() }
if (InjectedThings.partyMode && activeCount <= 1) {
addGameOverMessage(playerStates)
}
}

private fun addGameOverMessage(playerStates: List<PlayerState>) {
val winner = playerStates.first { it.wrappedParticipant.participant.finishingPosition == 1 }
val heading =
makeTransparentTextPane().apply {
border = EmptyBorder(10, 0, 20, 0)
alignCentrally()
setFontSize(36)
append("Game Over!")
}

heading.preferredSize = Dimension(100, 65)
add(heading, BorderLayout.NORTH)

val textPane =
makeTransparentTextPane().apply {
alignCentrally()
setFontSize(18)

append("Congrats to ")
append(winner.wrappedParticipant.getParticipantName(), true)
append(" on the win!")
append("\n\n")
append("When you're done looking at the stats, this window can be closed.")
}

textPane.preferredSize = Dimension(100, 250)
add(textPane, BorderLayout.SOUTH)
}

private fun isSufficientData(): Boolean {
Expand Down
5 changes: 5 additions & 0 deletions src/main/kotlin/dartzee/screen/game/GamePanelPausable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dartzee.db.GameEntity
import dartzee.game.state.AbstractPlayerState
import dartzee.preferences.Preferences
import dartzee.screen.game.scorer.AbstractDartsScorerPausable
import dartzee.utils.InjectedThings
import dartzee.utils.InjectedThings.preferenceService
import javax.swing.SwingUtilities

Expand Down Expand Up @@ -78,6 +79,10 @@ abstract class GamePanelPausable<
) {
getCurrentScorer().toggleResume()
}

if (InjectedThings.partyMode) {
allPlayersFinished()
}
}

fun pauseLastPlayer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dartzee.game.state.IWrappedParticipant
import dartzee.logging.CODE_PLAYER_PAUSED
import dartzee.logging.CODE_PLAYER_UNPAUSED
import dartzee.screen.game.GamePanelPausable
import dartzee.utils.InjectedThings
import dartzee.utils.InjectedThings.logger
import dartzee.utils.ResourceCache.ICON_PAUSE
import dartzee.utils.ResourceCache.ICON_RESUME
Expand All @@ -24,7 +25,10 @@ abstract class AbstractDartsScorerPausable<PlayerState : AbstractPlayerState<Pla

init {
btnResume.preferredSize = Dimension(30, 30)
panelSouth.add(btnResume, BorderLayout.EAST)
if (!InjectedThings.partyMode) {
panelSouth.add(btnResume, BorderLayout.EAST)
}

btnResume.isVisible = false
btnResume.icon = ICON_RESUME
btnResume.toolTipText = "Resume throwing"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import dartzee.game.X01Config
import dartzee.game.state.X01PlayerState
import dartzee.`object`.Dart
import dartzee.screen.game.AbstractGameStatisticsPanel
import dartzee.utils.InjectedThings
import dartzee.utils.calculateThreeDartAverage
import dartzee.utils.getScoringDarts
import dartzee.utils.isCheckoutDart
Expand All @@ -27,10 +28,12 @@ open class GameStatisticsPanelX01(gameParams: String) :
val nfSetupThreshold = NumberField()

init {
add(panel, BorderLayout.NORTH)
panel.add(lblSetupThreshold)
if (!InjectedThings.partyMode) {
add(panel, BorderLayout.NORTH)
panel.add(lblSetupThreshold)
panel.add(nfSetupThreshold)
}

panel.add(nfSetupThreshold)
nfSetupThreshold.columns = 10

nfSetupThreshold.value = 100
Expand Down
23 changes: 11 additions & 12 deletions src/test/kotlin/dartzee/e2e/TestPartyModeE2E.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,11 @@ import dartzee.bean.ScrollTableDartsGame
import dartzee.clickButton
import dartzee.drtDoubleTwenty
import dartzee.drtInnerFourteen
import dartzee.drtInnerOne
import dartzee.drtInnerSeven
import dartzee.drtMissTwelve
import dartzee.drtOuterFive
import dartzee.drtOuterFourteen
import dartzee.drtOuterNineteen
import dartzee.drtOuterOne
import dartzee.drtOuterSeven
import dartzee.drtOuterSixteen
import dartzee.drtOuterTwelve
import dartzee.drtOuterTwenty
import dartzee.drtTrebleFive
import dartzee.drtTrebleNineteen
Expand All @@ -31,11 +26,14 @@ import dartzee.screen.DartsApp
import dartzee.screen.ScreenCache
import dartzee.screen.game.DartsGamePanel
import dartzee.screen.game.DartsGameScreen
import dartzee.screen.game.x01.GameStatisticsPanelX01
import dartzee.waitForAssertionWithReturn
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldContain
import javax.swing.JButton
import javax.swing.JTextPane
import javax.swing.SwingUtilities
import org.junit.jupiter.api.Test

Expand Down Expand Up @@ -73,13 +71,14 @@ class TestPartyModeE2E : AbstractE2ETest() {
gamePanel.throwHumanRound(drtTrebleNineteen(), drtInnerFourteen(), drtOuterFourteen()) // 36
gamePanel.throwHumanRound(drtOuterTwenty(), drtDoubleTwenty(), drtOuterTwenty()) // 0

gamePanel.clickChild<JButton> { it.isVisible && it.toolTipText == "Resume throwing" }
gamePanel.throwHumanRound(drtOuterSixteen(), drtInnerOne(), drtOuterSeven()) // 12
gamePanel.throwHumanRound(drtMissTwelve(), drtOuterTwelve()) // 0

// Check game outcome
gameWindow.getScorer("Alice").lblResult.text shouldBe "12 Darts"
gameWindow.getScorer("Bob").lblResult.text shouldBe "14 Darts"
gameWindow.getScorer("Bob").lblResult.text shouldBe "Unfinished"

val statsPane = gameWindow.getChild<GameStatisticsPanelX01>()
statsPane.shouldBeVisible()
val extraMessage = statsPane.getChild<JTextPane> { it.text.contains("Congrats") }
extraMessage.text.shouldContain("Congrats to Alice on the win!")
gameWindow.dispose()

// Check leaderboard
Expand All @@ -90,15 +89,15 @@ class TestPartyModeE2E : AbstractE2ETest() {
leaderboardTable
.getRows()
.map { it.filterIndexed { index: Int, _ -> index != 1 } }
.shouldContainExactly(arrayOf(1, "Alice", 1L, 12), arrayOf(2, "Bob", 1L, 14))
.shouldContainExactly(arrayOf(1, "Alice", 1L, 12))

// Reload the game
SwingUtilities.invokeAndWait { GameLauncher().loadAndDisplayGame(gamePanel.getGameId()) }

val loadedWindow = ScreenCache.getDartsGameScreen(gamePanel.getGameId())!!
loadedWindow.shouldBeVisible()
loadedWindow.getScorer("Alice").lblResult.text shouldBe "12 Darts"
loadedWindow.getScorer("Bob").lblResult.text shouldBe "14 Darts"
loadedWindow.getScorer("Bob").lblResult.text shouldBe "Unfinished"
}

private fun launchApp(): DartsApp {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package dartzee.screen.game

import com.github.alyssaburlton.swingtest.findChild
import dartzee.core.util.getSqlDateNow
import dartzee.core.util.maxOrZero
import dartzee.game.state.X01PlayerState
import dartzee.helper.AbstractTest
Expand All @@ -9,8 +11,12 @@ import dartzee.helper.makeDart
import dartzee.helper.makeX01PlayerState
import dartzee.shouldHaveColours
import dartzee.utils.DartsColour
import dartzee.utils.InjectedThings
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import javax.swing.JComponent
import javax.swing.JTextPane
import org.junit.jupiter.api.Test

class TestAbstractGameStatisticsPanel : AbstractTest() {
Expand Down Expand Up @@ -266,6 +272,56 @@ class TestAbstractGameStatisticsPanel : AbstractTest() {
panel.getCellComponent(0, 3).shouldHaveColours(DartsColour.SECOND_COLOURS)
panel.getCellComponent(0, 4).shouldHaveColours(DartsColour.FOURTH_COLOURS)
}

@Test
fun `Should add game over text in party mode`() {
InjectedThings.partyMode = true

val alice = insertPlayer(name = "Alice")
val pt =
insertParticipant(
playerId = alice.rowId,
dtFinished = getSqlDateNow(),
finishingPosition = 1
)

val state1 =
makeX01PlayerState(
player = alice,
participant = pt,
completedRound = listOf(makeDart(), makeDart(), makeDart())
)
val state2 =
makeX01PlayerState(
player = insertPlayer(name = "Bob"),
completedRound = listOf(makeDart())
)

val panel = FakeGameStatisticsPanel()
panel.showStats(listOf(state1, state2))
panel.findChild<JTextPane> { it.text == "Game Over!" }.shouldNotBeNull()
panel.findChild<JTextPane> { it.text.contains("Congrats to Alice") }.shouldNotBeNull()
}

@Test
fun `Should not game over text in party mode if game is not finished yet`() {
InjectedThings.partyMode = true

val state1 =
makeX01PlayerState(
player = insertPlayer(name = "Alice"),
completedRound = listOf(makeDart(), makeDart(), makeDart())
)
val state2 =
makeX01PlayerState(
player = insertPlayer(name = "Bob"),
completedRound = listOf(makeDart())
)

val panel = FakeGameStatisticsPanel()
panel.showStats(listOf(state1, state2))
panel.findChild<JTextPane> { it.text == "Game Over!" }.shouldBeNull()
}
}

private class FakeGameStatisticsPanel(
Expand Down

0 comments on commit e31864e

Please sign in to comment.