Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
meikpiep committed Jan 29, 2024
1 parent a665d10 commit 9a5de47
Show file tree
Hide file tree
Showing 23 changed files with 413 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package org.piepmeyer.gauguin.preferences

import android.content.SharedPreferences
import androidx.core.content.edit
import org.piepmeyer.gauguin.Utils
import org.piepmeyer.gauguin.grid.Grid
import kotlin.time.Duration
import kotlin.time.Duration.Companion.ZERO
import kotlin.time.Duration.Companion.milliseconds

Expand Down Expand Up @@ -34,27 +34,31 @@ class StatisticsManagerImpl(
}
}

override fun storeStatisticsAfterFinishedGame(grid: Grid): String? {
val gridsize = grid.gridSize

// assess hint penalty - gridsize^2/2 seconds for each cell
val penalty = grid.countCheated().toLong() * 500 * gridsize.surfaceArea
grid.playTime = grid.playTime + penalty.milliseconds
override fun storeStatisticsAfterFinishedGame(grid: Grid) {
val key = getBestTimeKey(grid)
val solvetime = grid.playTime

val timestat = stats.getLong("solvedtime$gridsize", 0).milliseconds
val editor = stats.edit()
val recordTime =
if (timestat == ZERO || timestat > solvetime) {
editor.putLong("solvedtime$gridsize", solvetime.inWholeMilliseconds)
Utils.displayableGameDuration(solvetime)
val bestTime = stats.getLong(key, 0).milliseconds

if (bestTime == ZERO || bestTime > solvetime) {
stats.edit { putLong(key, solvetime.inWholeMilliseconds) }

if (bestTime == ZERO) {
grid.solvedFirstTimeOfKind = true
} else {
null
grid.solvedBestTimeOfKind = true
}
editor.apply()
return recordTime
}
}

override fun getBestTime(grid: Grid): Duration {
val key = getBestTimeKey(grid)

return stats.getLong(key, 0).milliseconds
}

private fun getBestTimeKey(grid: Grid) = "solvedtime${grid.gridSize}"

override fun storeStreak(isSolved: Boolean) {
val solvedStreak = currentStreak()
val longestStreak = longestStreak()
Expand Down Expand Up @@ -84,4 +88,22 @@ class StatisticsManagerImpl(
override fun clearStatistics() {
stats.edit { clear() }
}

override fun typeOfSolution(grid: Grid): TypeOfSolution {
if (totalSolved() == 1) {
return TypeOfSolution.FirstGame
}

if (grid.solvedFirstTimeOfKind) {
return TypeOfSolution.FirstGameOfKind
}

if (grid.solvedBestTimeOfKind) {
println("-> " + getBestTime(grid))
println(grid.playTime)
return TypeOfSolution.BestTimeOfKind
}

return TypeOfSolution.Regular
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package org.piepmeyer.gauguin.ui.main

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.piepmeyer.gauguin.R
import org.piepmeyer.gauguin.Utils
import org.piepmeyer.gauguin.databinding.FragmentMainGameSolvedBinding
import org.piepmeyer.gauguin.game.Game
import org.piepmeyer.gauguin.game.GameSolvedListener
import org.piepmeyer.gauguin.game.GridCreationListener
import org.piepmeyer.gauguin.preferences.StatisticsManager
import org.piepmeyer.gauguin.preferences.TypeOfSolution
import org.piepmeyer.gauguin.ui.MainDialogs
import org.piepmeyer.gauguin.ui.StatisticsActivity

class GameSolvedFragment :
Fragment(R.layout.fragment_main_game_solved),
KoinComponent,
GameSolvedListener,
GridCreationListener {
private val game: Game by inject()
private val statisticsManager: StatisticsManager by inject()

private lateinit var binding: FragmentMainGameSolvedBinding

override fun onCreateView(
inflater: LayoutInflater,
parent: ViewGroup?,
savedInstanceState: Bundle?,
): View {
binding = FragmentMainGameSolvedBinding.inflate(inflater, parent, false)
return binding.root
}

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
binding.showStatisticsButton.setOnClickListener {
requireActivity().startActivity(
Intent(
requireActivity(),
StatisticsActivity::class.java,
),
)
}

binding.playGameWithSameConfig.setOnClickListener {
(this.activity as MainActivity).postNewGame(startedFromMainActivityWithSameVariant = true)
}

binding.playGameWithOtherConfig.setOnClickListener {
MainDialogs(this.activity as MainActivity).newGameGridDialog()
}

game.addGameSolvedHandler(this)
game.addGridCreationListener(this)
}

override fun puzzleSolved(troughReveal: Boolean) {
binding.detailsIcon

if (!troughReveal) {
val icon =
when (statisticsManager.typeOfSolution(game.grid)) {
TypeOfSolution.FirstGame -> R.drawable.trophy_variant_outline
TypeOfSolution.FirstGameOfKind -> R.drawable.trophy_variant_outline
TypeOfSolution.BestTimeOfKind -> R.drawable.podium_gold
TypeOfSolution.Regular -> null
}

val text =
when (statisticsManager.typeOfSolution(game.grid)) {
TypeOfSolution.FirstGame -> getString(R.string.puzzle_solved_type_of_solution_first_game_solved)
TypeOfSolution.FirstGameOfKind -> getString(R.string.puzzle_solved_type_of_solution_first_game_of_kind_solved)
TypeOfSolution.BestTimeOfKind -> getString(R.string.puzzle_solved_type_of_solution_best_time_of_kind_solved)
TypeOfSolution.Regular ->
getString(
R.string.puzzle_solved_type_of_solution_regular_display_best_time,
Utils.displayableGameDuration(statisticsManager.getBestTime(game.grid)),
)
}

if (icon != null) {
binding.detailsIcon.setImageResource(icon)
binding.detailsIcon.visibility = View.VISIBLE
} else {
binding.detailsIcon.visibility = View.INVISIBLE
}

binding.detailsText.text = text
binding.detailsText.visibility = View.VISIBLE
} else {
binding.detailsIcon.visibility = View.INVISIBLE
binding.detailsText.visibility = View.INVISIBLE
}

binding.gameSolvedCardView.visibility = View.VISIBLE
}

override fun freshGridWasCreated() {
binding.gameSolvedCardView.visibility = View.GONE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ class MainActivity : AppCompatActivity(), GridCreationListener {
private lateinit var binding: ActivityMainBinding
private lateinit var bottomAppBarService: MainBottomAppBarService

private var gameEndedSnackbar: Snackbar? = null

private lateinit var specialListener: OnSharedPreferenceChangeListener

public override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -70,6 +68,7 @@ class MainActivity : AppCompatActivity(), GridCreationListener {
topFragment = GameTopFragment()
ft.replace(R.id.keypadFrame, KeyPadFragment())
ft.replace(R.id.fastFinishingModeFrame, FastFinishingModeFragment())
ft.replace(R.id.gameSolvedFrame, GameSolvedFragment())
ft.replace(R.id.gameTopFrame, topFragment)
ft.commit()

Expand All @@ -79,7 +78,7 @@ class MainActivity : AppCompatActivity(), GridCreationListener {
binding.gridview.invalidate()
}

game.setSolvedHandler { reveal -> gameSolved(reveal) }
game.addGameSolvedHandler { reveal -> gameSolved(reveal) }

registerForContextMenu(binding.gridview)

Expand Down Expand Up @@ -146,20 +145,12 @@ class MainActivity : AppCompatActivity(), GridCreationListener {
private fun gameSolved(reveal: Boolean) {
gameLifecycle.gameSolved()

gameEndedSnackbar = showSnackbar(getString(R.string.puzzle_solved))

bottomAppBarService.updateAppBarState()

binding.hintOrNewGame.hide()
binding.hintOrNewGame.show()

statisticsManager.storeStreak(!reveal)
topFragment.setGameTime(game.grid.playTime)

val recordTime = statisticsManager.storeStatisticsAfterFinishedGame(game.grid)

if (!reveal) {
recordTime?.let { gameEndedSnackbar = showSnackbar("${getString(R.string.puzzle_record_time)} $it") }
val konfettiView = binding.konfettiView

val emitterConfig = Emitter(8L, TimeUnit.SECONDS).perSecond(150)
Expand Down Expand Up @@ -285,10 +276,7 @@ class MainActivity : AppCompatActivity(), GridCreationListener {
MainDialogs(this).newGameGridDialog()
}

private fun postNewGame(startedFromMainActivityWithSameVariant: Boolean = false) {
gameEndedSnackbar?.dismiss()
gameEndedSnackbar = null

fun postNewGame(startedFromMainActivityWithSameVariant: Boolean = false) {
if (game.grid.isActive && game.grid.startedToBePlayed) {
statisticsManager.storeStreak(false)
}
Expand Down Expand Up @@ -353,9 +341,7 @@ class MainActivity : AppCompatActivity(), GridCreationListener {
}

fun checkProgressOrStartNewGame() {
if (game.grid.isSolved()) {
postNewGame(startedFromMainActivityWithSameVariant = true)
} else {
if (!game.grid.isSolved()) {
checkProgress()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class MainBottomAppBarService(

game.undoManager = undoList

binding.hintOrNewGame.setOnClickListener { mainActivity.checkProgressOrStartNewGame() }
binding.hint.setOnClickListener { mainActivity.checkProgressOrStartNewGame() }
undoButton.setOnClickListener { game.undoOneStep() }
eraserButton?.setOnClickListener { game.eraseSelectedCell() }

Expand All @@ -55,14 +55,13 @@ class MainBottomAppBarService(

fun updateAppBarState() {
if (game.grid.isSolved()) {
binding.hintOrNewGame.isEnabled = true
binding.hintOrNewGame.setImageResource(R.drawable.outline_add_24)
binding.hint.hide()

undoButton.visibility = View.GONE
eraserButton?.visibility = View.GONE
} else {
binding.hintOrNewGame.isEnabled = true
binding.hintOrNewGame.setImageResource(R.drawable.baseline_question_mark_24)
binding.hint.isEnabled = true
binding.hint.show()

undoButton.visibility = View.VISIBLE
undoButton.isEnabled = false
Expand Down
1 change: 1 addition & 0 deletions gauguin-app/src/main/res/drawable/cog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- drawable/cog.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" /></vector>
1 change: 1 addition & 0 deletions gauguin-app/src/main/res/drawable/flag_checkered.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- drawable/flag_checkered.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M14.4,6H20V16H13L12.6,14H7V21H5V4H14L14.4,6M14,14H16V12H18V10H16V8H14V10L13,8V6H11V8H9V6H7V8H9V10H7V12H9V10H11V12H13V10L14,12V14M11,10V8H13V10H11M14,10H16V12H14V10Z" /></vector>
1 change: 1 addition & 0 deletions gauguin-app/src/main/res/drawable/human_handsup.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- drawable/human_handsup.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M5,1C5,3.7 6.56,6.16 9,7.32V22H11V15H13V22H15V7.31C17.44,6.16 19,3.7 19,1H17A5,5 0 0,1 12,6A5,5 0 0,1 7,1M12,1C10.89,1 10,1.89 10,3C10,4.11 10.89,5 12,5C13.11,5 14,4.11 14,3C14,1.89 13.11,1 12,1Z" /></vector>
1 change: 1 addition & 0 deletions gauguin-app/src/main/res/drawable/play.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- drawable/play.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M8,5.14V19.14L19,12.14L8,5.14Z" /></vector>
1 change: 1 addition & 0 deletions gauguin-app/src/main/res/drawable/podium_gold.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- drawable/podium_gold.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M12,7.09L14.45,8.58L13.8,5.77L16,3.89L13.11,3.64L12,1L10.87,3.64L8,3.89L10.18,5.77L9.5,8.58L12,7.09M15,23H9V10H15V23M1,17V23H7V17H1M5,21H3V19H5V21M17,13V23H23V13H17M21,21H19V15H21V21Z" /></vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- drawable/trophy_variant_outline.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M17 4V2H7V4H2V11C2 12.1 2.9 13 4 13H7.1C7.5 14.96 9.04 16.5 11 16.9V19.08C8 19.54 8 22 8 22H16C16 22 16 19.54 13 19.08V16.9C14.96 16.5 16.5 14.96 16.9 13H20C21.1 13 22 12.1 22 11V4H17M4 11V6H7V11L4 11M15 12C15 13.65 13.65 15 12 15S9 13.65 9 12V4H15V12M20 11L17 11V6H20L20 11Z" /></vector>
17 changes: 15 additions & 2 deletions gauguin-app/src/main/res/layout-land/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="72dp"
android:layout_marginBottom="84dp"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/gridview"
app:layout_constraintTop_toBottomOf="@id/gameTopFrame"
Expand All @@ -78,6 +78,18 @@
app:layout_constraintEnd_toEndOf="@id/keypadFrame"
/>

<FrameLayout
android:id="@+id/gameSolvedFrame"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="@id/gridview"
app:layout_constraintTop_toBottomOf="@id/gameTopFrame"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp"
android:layout_marginBottom="84dp"
/>

<ImageView
android:id="@+id/pendingNextGridCalculation"
android:layout_width="wrap_content"
Expand Down Expand Up @@ -105,10 +117,11 @@
app:menu="@menu/bottom_app_bar" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/hintOrNewGame"
android:id="@+id/hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/MainFab"
android:src="@drawable/baseline_question_mark_24"
app:layout_anchor="@id/mainBottomAppBar"
android:text=""
/>
Expand Down
12 changes: 11 additions & 1 deletion gauguin-app/src/main/res/layout-sw600dp-land/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@
app:layout_constraintTop_toBottomOf="@id/gameTopFrame"
app:layout_constraintBottom_toBottomOf="parent"/>

<FrameLayout
android:id="@+id/gameSolvedFrame"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="@id/gridview"
app:layout_constraintEnd_toEndOf="@id/gameTopFrame"
app:layout_constraintTop_toBottomOf="@id/gameTopFrame"
app:layout_constraintBottom_toBottomOf="parent"/>

<FrameLayout
android:id="@+id/fastFinishingModeFrame"
android:layout_width="wrap_content"
Expand All @@ -104,9 +113,10 @@
app:menu="@menu/bottom_app_bar" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/hintOrNewGame"
android:id="@+id/hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/baseline_question_mark_24"
style="@style/MainFab"
app:layout_anchor="@id/mainBottomAppBar"
/>
Expand Down
Loading

0 comments on commit 9a5de47

Please sign in to comment.