Merge pull request #142 from lucasnlm/small-improvements

Small improvements
This commit is contained in:
Lucas Nunes 2020-08-07 01:57:42 +00:00 committed by GitHub
commit 40fd494962
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
61 changed files with 159 additions and 161 deletions

View file

@ -32,7 +32,7 @@ import dev.lucasnlm.antimine.common.level.models.Status
import dev.lucasnlm.antimine.common.level.repository.ISavesRepository import dev.lucasnlm.antimine.common.level.repository.ISavesRepository
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.control.ControlDialogFragment import dev.lucasnlm.antimine.control.ControlDialogFragment
import dev.lucasnlm.antimine.core.analytics.AnalyticsManager import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.analytics.models.Analytics
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.history.HistoryActivity import dev.lucasnlm.antimine.history.HistoryActivity
@ -57,7 +57,7 @@ class GameActivity : AppCompatActivity(R.layout.activity_game), DialogInterface.
lateinit var preferencesRepository: IPreferencesRepository lateinit var preferencesRepository: IPreferencesRepository
@Inject @Inject
lateinit var analyticsManager: AnalyticsManager lateinit var analyticsManager: IAnalyticsManager
@Inject @Inject
lateinit var instantAppManager: InstantAppManager lateinit var instantAppManager: InstantAppManager
@ -117,7 +117,7 @@ class GameActivity : AppCompatActivity(R.layout.activity_game), DialogInterface.
retryObserver.observe( retryObserver.observe(
this@GameActivity, this@GameActivity,
Observer { Observer {
GlobalScope.launch { lifecycleScope.launch {
viewModel.retryGame(currentSaveId.toInt()) viewModel.retryGame(currentSaveId.toInt())
} }
} }

View file

@ -2,14 +2,14 @@ package dev.lucasnlm.antimine
import androidx.multidex.MultiDexApplication import androidx.multidex.MultiDexApplication
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import dev.lucasnlm.antimine.core.analytics.AnalyticsManager import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.analytics.models.Analytics
import javax.inject.Inject import javax.inject.Inject
@HiltAndroidApp @HiltAndroidApp
open class MainApplication : MultiDexApplication() { open class MainApplication : MultiDexApplication() {
@Inject @Inject
lateinit var analyticsManager: AnalyticsManager lateinit var analyticsManager: IAnalyticsManager
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()

View file

@ -12,7 +12,7 @@ import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.about.models.AboutEvent import dev.lucasnlm.antimine.about.models.AboutEvent
import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel
import dev.lucasnlm.antimine.about.views.AboutInfoFragment import dev.lucasnlm.antimine.about.views.AboutInfoFragment
import dev.lucasnlm.antimine.about.views.thirds.ThirdPartiesFragment import dev.lucasnlm.antimine.about.views.thirds.ThirdPartyFragment
import dev.lucasnlm.antimine.about.views.translators.TranslatorsFragment import dev.lucasnlm.antimine.about.views.translators.TranslatorsFragment
class AboutActivity : AppCompatActivity(R.layout.activity_empty) { class AboutActivity : AppCompatActivity(R.layout.activity_empty) {
@ -25,7 +25,7 @@ class AboutActivity : AppCompatActivity(R.layout.activity_empty) {
Observer { event -> Observer { event ->
when (event) { when (event) {
AboutEvent.ThirdPartyLicenses -> { AboutEvent.ThirdPartyLicenses -> {
replaceFragment(ThirdPartiesFragment(), ThirdPartiesFragment.TAG) replaceFragment(ThirdPartyFragment(), ThirdPartyFragment.TAG)
} }
AboutEvent.SourceCode -> { AboutEvent.SourceCode -> {
openSourceCode() openSourceCode()

View file

@ -10,6 +10,10 @@ import dev.lucasnlm.antimine.about.models.TranslationInfo
class AboutViewModel : ViewModel() { class AboutViewModel : ViewModel() {
val eventObserver = MutableLiveData<AboutEvent>() val eventObserver = MutableLiveData<AboutEvent>()
fun sendEvent(event: AboutEvent) {
eventObserver.postValue(event)
}
fun getTranslatorsList() = mapOf( fun getTranslatorsList() = mapOf(
"Arabic" to sequenceOf("Ahmad Alkurbi"), "Arabic" to sequenceOf("Ahmad Alkurbi"),
"Bulgarian" to sequenceOf("Georgi Eftimov"), "Bulgarian" to sequenceOf("Georgi Eftimov"),

View file

@ -24,15 +24,15 @@ class AboutInfoFragment : Fragment(R.layout.fragment_about_info) {
version.text = getString(R.string.version_s, BuildConfig.VERSION_NAME) version.text = getString(R.string.version_s, BuildConfig.VERSION_NAME)
thirdsParties.setOnClickListener { thirdsParties.setOnClickListener {
aboutViewModel.eventObserver.postValue(AboutEvent.ThirdPartyLicenses) aboutViewModel.sendEvent(AboutEvent.ThirdPartyLicenses)
} }
sourceCode.setOnClickListener { sourceCode.setOnClickListener {
aboutViewModel.eventObserver.postValue(AboutEvent.SourceCode) aboutViewModel.sendEvent(AboutEvent.SourceCode)
} }
translation.setOnClickListener { translation.setOnClickListener {
aboutViewModel.eventObserver.postValue(AboutEvent.Translators) aboutViewModel.sendEvent(AboutEvent.Translators)
} }
} }
} }

View file

@ -2,13 +2,16 @@ package dev.lucasnlm.antimine.about.views.thirds
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.text.TextActivity import dev.lucasnlm.antimine.text.TextActivity
import dev.lucasnlm.antimine.about.models.ThirdParty import dev.lucasnlm.antimine.about.models.ThirdParty
import kotlinx.android.synthetic.main.view_third_party.view.*
class ThirdPartyAdapter( internal class ThirdPartyAdapter(
private val thirdParties: List<ThirdParty> private val thirdParties: List<ThirdParty>
) : RecyclerView.Adapter<ThirdPartyViewHolder>() { ) : RecyclerView.Adapter<ThirdPartyViewHolder>() {
@ -32,3 +35,7 @@ class ThirdPartyAdapter(
} }
} }
} }
class ThirdPartyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val title: TextView = view.third_name
}

View file

@ -10,7 +10,7 @@ import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel
import kotlinx.android.synthetic.main.fragment_third_party.* import kotlinx.android.synthetic.main.fragment_third_party.*
class ThirdPartiesFragment : Fragment(R.layout.fragment_third_party) { class ThirdPartyFragment : Fragment(R.layout.fragment_third_party) {
private val aboutViewModel: AboutViewModel by activityViewModels() private val aboutViewModel: AboutViewModel by activityViewModels()
override fun onResume() { override fun onResume() {
@ -30,6 +30,6 @@ class ThirdPartiesFragment : Fragment(R.layout.fragment_third_party) {
} }
companion object { companion object {
val TAG = ThirdPartiesFragment::class.simpleName!! val TAG = ThirdPartyFragment::class.simpleName!!
} }
} }

View file

@ -1,11 +0,0 @@
package dev.lucasnlm.antimine.about.views.thirds
import androidx.recyclerview.widget.RecyclerView
import android.view.View
import android.widget.TextView
import kotlinx.android.synthetic.main.view_third_party.view.*
class ThirdPartyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val title: TextView = view.third_name
}

View file

@ -2,15 +2,18 @@ package dev.lucasnlm.antimine.about.views.translators
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel
import kotlinx.android.synthetic.main.fragment_translators.* import kotlinx.android.synthetic.main.fragment_translators.*
import kotlinx.android.synthetic.main.view_translator.view.*
class TranslatorsFragment : Fragment(R.layout.fragment_translators) { internal class TranslatorsFragment : Fragment(R.layout.fragment_translators) {
private val aboutViewModel: AboutViewModel by activityViewModels() private val aboutViewModel: AboutViewModel by activityViewModels()
override fun onResume() { override fun onResume() {
@ -32,3 +35,8 @@ class TranslatorsFragment : Fragment(R.layout.fragment_translators) {
val TAG = TranslatorsFragment::class.simpleName!! val TAG = TranslatorsFragment::class.simpleName!!
} }
} }
class TranslatorsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val language: TextView = view.language
val translators: TextView = view.translators
}

View file

@ -1,11 +0,0 @@
package dev.lucasnlm.antimine.about.views.translators
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.view_translator.view.*
class TranslatorsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val language: TextView = view.language
val translators: TextView = view.translators
}

View file

@ -9,7 +9,9 @@ import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Minefield import dev.lucasnlm.antimine.common.level.models.Minefield
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.custom.viewmodel.CreateGameViewModel import dev.lucasnlm.antimine.custom.viewmodel.CreateGameViewModel
import javax.inject.Inject import javax.inject.Inject
@ -19,6 +21,7 @@ class CustomLevelDialogFragment : AppCompatDialogFragment() {
@Inject @Inject
lateinit var preferencesRepository: IPreferencesRepository lateinit var preferencesRepository: IPreferencesRepository
private val viewModel by activityViewModels<GameViewModel>()
private val createGameViewModel by activityViewModels<CreateGameViewModel>() private val createGameViewModel by activityViewModels<CreateGameViewModel>()
private fun getSelectedMinefield(): Minefield { private fun getSelectedMinefield(): Minefield {
@ -49,10 +52,8 @@ class CustomLevelDialogFragment : AppCompatDialogFragment() {
setNegativeButton(R.string.cancel, null) setNegativeButton(R.string.cancel, null)
setPositiveButton(R.string.start) { _, _ -> setPositiveButton(R.string.start) { _, _ ->
val minefield = getSelectedMinefield() val minefield = getSelectedMinefield()
createGameViewModel.run { createGameViewModel.updateCustomGameMode(minefield)
updateCustomGameMode(minefield) viewModel.startNewGame(Difficulty.Custom)
startCustomGame()
}
} }
}.create() }.create()
} }

View file

@ -1,32 +1,14 @@
package dev.lucasnlm.antimine.custom.viewmodel package dev.lucasnlm.antimine.custom.viewmodel
import android.app.Application
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION
import android.net.Uri
import androidx.hilt.lifecycle.ViewModelInject import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.ViewModel
import dev.lucasnlm.antimine.DeepLink
import dev.lucasnlm.antimine.common.level.models.Minefield import dev.lucasnlm.antimine.common.level.models.Minefield
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
class CreateGameViewModel @ViewModelInject constructor( class CreateGameViewModel @ViewModelInject constructor(
application: Application,
private val preferencesRepository: IPreferencesRepository private val preferencesRepository: IPreferencesRepository
) : AndroidViewModel(application) { ) : ViewModel() {
fun updateCustomGameMode(minefield: Minefield) { fun updateCustomGameMode(minefield: Minefield) {
preferencesRepository.updateCustomGameMode(minefield) preferencesRepository.updateCustomGameMode(minefield)
} }
fun startCustomGame() {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(DeepLink.CUSTOM_NEW_GAME)
addFlags(FLAG_ACTIVITY_NEW_TASK)
addFlags(FLAG_ACTIVITY_CLEAR_TASK)
addFlags(FLAG_ACTIVITY_NO_ANIMATION)
}
getApplication<Application>().startActivity(intent)
}
} }

View file

@ -6,7 +6,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="false" android:fitsSystemWindows="false"
tools:context="dev.lucasnlm.antimine.about.views.thirds.ThirdPartiesFragment"> tools:context="dev.lucasnlm.antimine.about.views.thirds.ThirdPartyFragment">
<TextView <TextView
android:id="@+id/description" android:id="@+id/description"

View file

@ -4,7 +4,6 @@ import dev.lucasnlm.antimine.common.level.database.models.FirstOpen
import dev.lucasnlm.antimine.common.level.database.models.Save import dev.lucasnlm.antimine.common.level.database.models.Save
import dev.lucasnlm.antimine.common.level.database.models.SaveStatus import dev.lucasnlm.antimine.common.level.database.models.SaveStatus
import dev.lucasnlm.antimine.common.level.database.models.Stats import dev.lucasnlm.antimine.common.level.database.models.Stats
import dev.lucasnlm.antimine.common.level.solver.BruteForceSolver
import dev.lucasnlm.antimine.common.level.logic.FlagAssistant import dev.lucasnlm.antimine.common.level.logic.FlagAssistant
import dev.lucasnlm.antimine.common.level.logic.MinefieldCreator import dev.lucasnlm.antimine.common.level.logic.MinefieldCreator
import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler
@ -15,6 +14,7 @@ import dev.lucasnlm.antimine.common.level.models.Mark
import dev.lucasnlm.antimine.common.level.models.Minefield import dev.lucasnlm.antimine.common.level.models.Minefield
import dev.lucasnlm.antimine.common.level.models.Score import dev.lucasnlm.antimine.common.level.models.Score
import dev.lucasnlm.antimine.common.level.models.StateUpdate import dev.lucasnlm.antimine.common.level.models.StateUpdate
import dev.lucasnlm.antimine.common.level.solver.LimitedBruteForceSolver
import dev.lucasnlm.antimine.core.control.ActionResponse import dev.lucasnlm.antimine.core.control.ActionResponse
import dev.lucasnlm.antimine.core.control.GameControl import dev.lucasnlm.antimine.core.control.GameControl
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -22,9 +22,6 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlin.random.Random import kotlin.random.Random
/**
* Controls a minesweeper logic.
*/
class GameController { class GameController {
private val minefield: Minefield private val minefield: Minefield
private val startTime = System.currentTimeMillis() private val startTime = System.currentTimeMillis()
@ -33,7 +30,6 @@ class GameController {
private var gameControl: GameControl = GameControl.Standard private var gameControl: GameControl = GameControl.Standard
private var mines: Sequence<Area> = emptySequence() private var mines: Sequence<Area> = emptySequence()
private var useQuestionMark = true private var useQuestionMark = true
private var useSolverAlgorithms = false
var hasMines = false var hasMines = false
private set private set
@ -68,16 +64,14 @@ class GameController {
private fun getArea(id: Int) = field.first { it.id == id } private fun getArea(id: Int) = field.first { it.id == id }
private fun plantMinesExcept(safeId: Int) { private fun plantMinesExcept(safeId: Int) {
if (useSolverAlgorithms) { val solver = LimitedBruteForceSolver()
do { do {
field = minefieldCreator.create(safeId, false) val useSafeZone = minefield.width > 9 && minefield.height > 9
val fieldCopy = field.map { it.copy() }.toMutableList() field = minefieldCreator.create(safeId, useSafeZone)
val minefieldHandler = MinefieldHandler(fieldCopy, false) val fieldCopy = field.map { it.copy() }.toMutableList()
minefieldHandler.openAt(safeId) val minefieldHandler = MinefieldHandler(fieldCopy, false)
} while (!BruteForceSolver(minefieldHandler.result().toMutableList()).isSolvable()) minefieldHandler.openAt(safeId)
} else { } while (solver.keepTrying() && !solver.trySolve(minefieldHandler.result().toMutableList()))
field = minefieldCreator.create(safeId, true)
}
mines = field.filter { it.hasMine }.asSequence() mines = field.filter { it.hasMine }.asSequence()
firstOpen = FirstOpen.Position(safeId) firstOpen = FirstOpen.Position(safeId)
@ -269,8 +263,4 @@ class GameController {
fun useQuestionMark(useQuestionMark: Boolean) { fun useQuestionMark(useQuestionMark: Boolean) {
this.useQuestionMark = useQuestionMark this.useQuestionMark = useQuestionMark
} }
fun useSolverAlgorithms(useSolverAlgorithms: Boolean) {
this.useSolverAlgorithms = useSolverAlgorithms
}
} }

View file

@ -3,13 +3,10 @@ package dev.lucasnlm.antimine.common.level.solver
import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.common.level.models.Area
class BruteForceSolver( open class BruteForceSolver : GameSolver() {
minefield: MutableList<Area> override fun trySolve(minefield: MutableList<Area>): Boolean {
) : GameSolver(minefield) { val minefieldHandler = MinefieldHandler(minefield, false)
private val minefieldHandler =
MinefieldHandler(minefield, false)
override fun isSolvable(): Boolean {
do { do {
val initialMap = minefield.filter { !it.isCovered && it.minesAround != 0 } val initialMap = minefield.filter { !it.isCovered && it.minesAround != 0 }
initialMap.forEach { initialMap.forEach {

View file

@ -2,8 +2,15 @@ package dev.lucasnlm.antimine.common.level.solver
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.common.level.models.Area
abstract class GameSolver( abstract class GameSolver {
protected val minefield: MutableList<Area> /**
) { * If true it may keep iterating on this algorithm.
abstract fun isSolvable(): Boolean */
open fun keepTrying() = true
/**
* Try solve the given [minefield].
* Returns true if it's solvable or false otherwise.
*/
abstract fun trySolve(minefield: MutableList<Area>): Boolean
} }

View file

@ -0,0 +1,16 @@
package dev.lucasnlm.antimine.common.level.solver
class LimitedBruteForceSolver(
private val maxAttemptTime: Long = DEFAULT_BRUTE_FORCE_TIMEOUT
) : BruteForceSolver() {
private val initialTime = System.currentTimeMillis()
override fun keepTrying(): Boolean {
return (System.currentTimeMillis() - initialTime) <= maxAttemptTime
}
companion object {
const val DEFAULT_BRUTE_FORCE_TIMEOUT = 1000L
}
}

View file

@ -3,6 +3,7 @@ package dev.lucasnlm.antimine.common.level.view
import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF import android.graphics.RectF
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.common.R
@ -122,7 +123,7 @@ fun Area.paintOnCanvas(
7 -> areaPalette.minesAround7 7 -> areaPalette.minesAround7
else -> areaPalette.minesAround8 else -> areaPalette.minesAround8
} }
drawText(canvas, painter, minesAround.toString(), paintSettings) canvas.drawText(minesAround.toString(), paintSettings, painter)
} }
if (highlighted) { if (highlighted) {
@ -170,15 +171,15 @@ fun Area.paintOnCanvas(
} }
} }
private fun drawText(canvas: Canvas, paint: Paint, text: String, paintSettings: AreaPaintSettings) { private fun Canvas.drawText(text: String, paintSettings: AreaPaintSettings, paint: Paint) {
paintSettings.run { paintSettings.run {
val bounds = RectF(rectF).apply { val bounds = Rect()
right = paint.measureText(text, 0, text.length) paint.getTextBounds(text.toCharArray(), 0, 1, bounds)
bottom = paint.descent() - paint.ascent() paint.textSize = rectF.height() * 0.45f
left += (rectF.width() - right) / 2.0f
top += (rectF.height() - bottom) / 2.0f
}
canvas.drawText(text, rectF.width() * 0.5f, bounds.top - paint.ascent(), paint) val xPos = rectF.width() * 0.5f
val yPos = (bounds.height() + rectF.height()) * 0.5f
drawText(text, xPos, yPos, paint)
} }
} }

View file

@ -18,7 +18,7 @@ import dev.lucasnlm.antimine.common.level.repository.ISavesRepository
import dev.lucasnlm.antimine.common.level.repository.IStatsRepository import dev.lucasnlm.antimine.common.level.repository.IStatsRepository
import dev.lucasnlm.antimine.common.level.utils.Clock import dev.lucasnlm.antimine.common.level.utils.Clock
import dev.lucasnlm.antimine.common.level.utils.IHapticFeedbackManager import dev.lucasnlm.antimine.common.level.utils.IHapticFeedbackManager
import dev.lucasnlm.antimine.core.analytics.AnalyticsManager import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.analytics.models.Analytics
import dev.lucasnlm.antimine.core.control.ActionResponse import dev.lucasnlm.antimine.core.control.ActionResponse
import dev.lucasnlm.antimine.core.control.GameControl import dev.lucasnlm.antimine.core.control.GameControl
@ -42,7 +42,7 @@ class GameViewModel @ViewModelInject constructor(
private val hapticFeedbackManager: IHapticFeedbackManager, private val hapticFeedbackManager: IHapticFeedbackManager,
private val soundManager: ISoundManager, private val soundManager: ISoundManager,
private val minefieldRepository: IMinefieldRepository, private val minefieldRepository: IMinefieldRepository,
private val analyticsManager: AnalyticsManager, private val analyticsManager: IAnalyticsManager,
private val clock: Clock private val clock: Clock
) : ViewModel() { ) : ViewModel() {
val eventObserver = MutableLiveData<Event>() val eventObserver = MutableLiveData<Event>()
@ -346,7 +346,6 @@ class GameViewModel @ViewModelInject constructor(
updateGameControl(gameControl) updateGameControl(gameControl)
useQuestionMark(preferencesRepository.useQuestionMark()) useQuestionMark(preferencesRepository.useQuestionMark())
useSolverAlgorithms(preferencesRepository.useSolverAlgorithms())
} }
} }
} }

View file

@ -4,7 +4,7 @@ import android.content.Context
import android.util.Log import android.util.Log
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.analytics.models.Analytics
class DebugAnalyticsManager : AnalyticsManager { class DebugAnalyticsManager : IAnalyticsManager {
override fun setup(context: Context, userProperties: Map<String, String>) { override fun setup(context: Context, userProperties: Map<String, String>) {
Log.d(TAG, "Setup Analytics using $userProperties") Log.d(TAG, "Setup Analytics using $userProperties")
} }

View file

@ -3,7 +3,7 @@ package dev.lucasnlm.antimine.core.analytics
import android.content.Context import android.content.Context
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.analytics.models.Analytics
interface AnalyticsManager { interface IAnalyticsManager {
fun setup(context: Context, userProperties: Map<String, String>) fun setup(context: Context, userProperties: Map<String, String>)
fun sentEvent(event: Analytics) fun sentEvent(event: Analytics)
} }

View file

@ -6,7 +6,7 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.components.ApplicationComponent import dagger.hilt.android.components.ApplicationComponent
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dev.lucasnlm.antimine.core.analytics.AnalyticsManager import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.core.preferences.PreferencesManager import dev.lucasnlm.antimine.core.preferences.PreferencesManager
@ -28,7 +28,7 @@ class CommonModule {
): PreferencesManager = PreferencesManager(context) ): PreferencesManager = PreferencesManager(context)
@Provides @Provides
fun provideAnalyticsManager(): AnalyticsManager = DebugAnalyticsManager() fun provideAnalyticsManager(): IAnalyticsManager = DebugAnalyticsManager()
@Provides @Provides
fun provideSoundManager( fun provideSoundManager(

View file

@ -24,7 +24,6 @@ interface IPreferencesRepository {
fun useAnimations(): Boolean fun useAnimations(): Boolean
fun useQuestionMark(): Boolean fun useQuestionMark(): Boolean
fun isSoundEffectsEnabled(): Boolean fun isSoundEffectsEnabled(): Boolean
fun useSolverAlgorithms(): Boolean
} }
class PreferencesRepository( class PreferencesRepository(
@ -78,9 +77,6 @@ class PreferencesRepository(
override fun isSoundEffectsEnabled(): Boolean = override fun isSoundEffectsEnabled(): Boolean =
getBoolean(PREFERENCE_SOUND_EFFECTS, false) getBoolean(PREFERENCE_SOUND_EFFECTS, false)
override fun useSolverAlgorithms(): Boolean =
getBoolean(PREFERENCE_USE_SOLVER_ALGORITHMS, false)
override fun controlStyle(): ControlStyle { override fun controlStyle(): ControlStyle {
val index = getInt(PREFERENCE_CONTROL_STYLE, -1) val index = getInt(PREFERENCE_CONTROL_STYLE, -1)
return ControlStyle.values().getOrNull(index) ?: ControlStyle.Standard return ControlStyle.values().getOrNull(index) ?: ControlStyle.Standard
@ -120,6 +116,5 @@ class PreferencesRepository(
private const val PREFERENCE_CUSTOM_GAME_MINES = "preference_custom_game_mines" private const val PREFERENCE_CUSTOM_GAME_MINES = "preference_custom_game_mines"
private const val PREFERENCE_SOUND_EFFECTS = "preference_sound" private const val PREFERENCE_SOUND_EFFECTS = "preference_sound"
private const val PREFERENCE_STATS_BASE = "preference_stats_base" private const val PREFERENCE_STATS_BASE = "preference_stats_base"
private const val PREFERENCE_USE_SOLVER_ALGORITHMS = "preference_use_solver_algorithms"
} }
} }

View file

@ -48,7 +48,6 @@
<string name="quit">Verlaat</string> <string name="quit">Verlaat</string>
<string name="are_you_sure">Is jy seker?</string> <string name="are_you_sure">Is jy seker?</string>
<string name="enable_automatic_flags">Aktiveer outomatiese plasing van vlaggies</string> <string name="enable_automatic_flags">Aktiveer outomatiese plasing van vlaggies</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">خروج</string> <string name="quit">خروج</string>
<string name="are_you_sure">هل أنت متأكد؟</string> <string name="are_you_sure">هل أنت متأكد؟</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">فتح المناطق</string> <string name="open_areas">فتح المناطق</string>
<string name="total_time">مجموع الوقت</string> <string name="total_time">مجموع الوقت</string>
<string name="average_time">متوسط الوقت</string> <string name="average_time">متوسط الوقت</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Изход</string> <string name="quit">Изход</string>
<string name="are_you_sure">Сигурни ли сте?</string> <string name="are_you_sure">Сигурни ли сте?</string>
<string name="enable_automatic_flags">Позволява автоматично слагане на флагове</string> <string name="enable_automatic_flags">Позволява автоматично слагане на флагове</string>
<string name="enable_no_guessing_maps">Намери решими карти</string>
<string name="open_areas">Отворени площи</string> <string name="open_areas">Отворени площи</string>
<string name="total_time">Общо време</string> <string name="total_time">Общо време</string>
<string name="average_time">Средно време</string> <string name="average_time">Средно време</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Surt</string> <string name="quit">Surt</string>
<string name="are_you_sure">Esteu segurs?</string> <string name="are_you_sure">Esteu segurs?</string>
<string name="enable_automatic_flags">Activa la col·locació automàtica de banderes</string> <string name="enable_automatic_flags">Activa la col·locació automàtica de banderes</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Zones obertes</string> <string name="open_areas">Zones obertes</string>
<string name="total_time">Temps total</string> <string name="total_time">Temps total</string>
<string name="average_time">Durada mitjana</string> <string name="average_time">Durada mitjana</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Ukončit</string> <string name="quit">Ukončit</string>
<string name="are_you_sure">Jste si jisti?</string> <string name="are_you_sure">Jste si jisti?</string>
<string name="enable_automatic_flags">Povolit automatické umísťování vlajek</string> <string name="enable_automatic_flags">Povolit automatické umísťování vlajek</string>
<string name="enable_no_guessing_maps">Najít řešitelná minová pole</string>
<string name="open_areas">Otevřené oblasti</string> <string name="open_areas">Otevřené oblasti</string>
<string name="total_time">Celkový čas</string> <string name="total_time">Celkový čas</string>
<string name="average_time">Průměrný čas</string> <string name="average_time">Průměrný čas</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Beenden</string> <string name="quit">Beenden</string>
<string name="are_you_sure">Bist du sicher?</string> <string name="are_you_sure">Bist du sicher?</string>
<string name="enable_automatic_flags">Automatische Markierungen aktivieren</string> <string name="enable_automatic_flags">Automatische Markierungen aktivieren</string>
<string name="enable_no_guessing_maps">Lösbare Karten finden</string>
<string name="open_areas">Offene Flächen</string> <string name="open_areas">Offene Flächen</string>
<string name="total_time">Gesamtzeit</string> <string name="total_time">Gesamtzeit</string>
<string name="average_time">Durchschnittliche Zeit</string> <string name="average_time">Durchschnittliche Zeit</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Έξοδος</string> <string name="quit">Έξοδος</string>
<string name="are_you_sure">Είσαι σίγουρος;</string> <string name="are_you_sure">Είσαι σίγουρος;</string>
<string name="enable_automatic_flags">Ενεργοποίηση αυτόματης τοποθέτησης σημαιών</string> <string name="enable_automatic_flags">Ενεργοποίηση αυτόματης τοποθέτησης σημαιών</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Ανοιχτές περιοχές</string> <string name="open_areas">Ανοιχτές περιοχές</string>
<string name="total_time">Συνολικός Χρόνος</string> <string name="total_time">Συνολικός Χρόνος</string>
<string name="average_time">Μέσος χρόνος</string> <string name="average_time">Μέσος χρόνος</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Salir</string> <string name="quit">Salir</string>
<string name="are_you_sure">¿Estás seguro?</string> <string name="are_you_sure">¿Estás seguro?</string>
<string name="enable_automatic_flags">Activar situación automática de banderas</string> <string name="enable_automatic_flags">Activar situación automática de banderas</string>
<string name="enable_no_guessing_maps">Encontrar mapas solubles</string>
<string name="open_areas">Abrir Áreas</string> <string name="open_areas">Abrir Áreas</string>
<string name="total_time">Tiempo total</string> <string name="total_time">Tiempo total</string>
<string name="average_time">Tiempo promedio</string> <string name="average_time">Tiempo promedio</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Lopeta</string> <string name="quit">Lopeta</string>
<string name="are_you_sure">Oletko varma?</string> <string name="are_you_sure">Oletko varma?</string>
<string name="enable_automatic_flags">Kytke lippujen automaattinen asettaminen päälle</string> <string name="enable_automatic_flags">Kytke lippujen automaattinen asettaminen päälle</string>
<string name="enable_no_guessing_maps">Etsi ratkaistavia karttoja</string>
<string name="open_areas">Avaa alueita</string> <string name="open_areas">Avaa alueita</string>
<string name="total_time">Aika yhteensä</string> <string name="total_time">Aika yhteensä</string>
<string name="average_time">Keskimääräinen aika</string> <string name="average_time">Keskimääräinen aika</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quitter</string> <string name="quit">Quitter</string>
<string name="are_you_sure">Vraiment ?</string> <string name="are_you_sure">Vraiment ?</string>
<string name="enable_automatic_flags">Activer le placement automatique de drapeaux</string> <string name="enable_automatic_flags">Activer le placement automatique de drapeaux</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Zones ouvertes</string> <string name="open_areas">Zones ouvertes</string>
<string name="total_time">Temps de jeu total</string> <string name="total_time">Temps de jeu total</string>
<string name="average_time">Temps de jeu moyen</string> <string name="average_time">Temps de jeu moyen</string>

View file

@ -48,7 +48,6 @@
<string name="quit">समाप्त करें</string> <string name="quit">समाप्त करें</string>
<string name="are_you_sure">क्या आपको यकीन है?</string> <string name="are_you_sure">क्या आपको यकीन है?</string>
<string name="enable_automatic_flags">फ्लैग के स्वचालित रखे जाने को सक्रिय क</string> <string name="enable_automatic_flags">फ्लैग के स्वचालित रखे जाने को सक्रिय क</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">कुल समय</string> <string name="total_time">कुल समय</string>
<string name="average_time">औसत समय</string> <string name="average_time">औसत समय</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Kilépés</string> <string name="quit">Kilépés</string>
<string name="are_you_sure">Biztos vagy benne?</string> <string name="are_you_sure">Biztos vagy benne?</string>
<string name="enable_automatic_flags">A zászlók automatikus elhelyezésének engedélyezése</string> <string name="enable_automatic_flags">A zászlók automatikus elhelyezésének engedélyezése</string>
<string name="enable_no_guessing_maps">Megoldható térképek keresése</string>
<string name="open_areas">Nyílt területek</string> <string name="open_areas">Nyílt területek</string>
<string name="total_time">Teljes játékidő</string> <string name="total_time">Teljes játékidő</string>
<string name="average_time">Átlagos játékidő</string> <string name="average_time">Átlagos játékidő</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Keluar</string> <string name="quit">Keluar</string>
<string name="are_you_sure">Anda yakin?</string> <string name="are_you_sure">Anda yakin?</string>
<string name="enable_automatic_flags">Aktifkan penempatan bendera otomatis</string> <string name="enable_automatic_flags">Aktifkan penempatan bendera otomatis</string>
<string name="enable_no_guessing_maps">Cari bidang ranjau yang dapat dipecahkan</string>
<string name="open_areas">Buka</string> <string name="open_areas">Buka</string>
<string name="total_time">Total waktu</string> <string name="total_time">Total waktu</string>
<string name="average_time">Waktu rata-rata</string> <string name="average_time">Waktu rata-rata</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Esci</string> <string name="quit">Esci</string>
<string name="are_you_sure">Sei sicuro?</string> <string name="are_you_sure">Sei sicuro?</string>
<string name="enable_automatic_flags">Abilita il posizionamento automatico delle bandiere</string> <string name="enable_automatic_flags">Abilita il posizionamento automatico delle bandiere</string>
<string name="enable_no_guessing_maps">Trova le mappe risolvibili</string>
<string name="open_areas">Aree Aperte</string> <string name="open_areas">Aree Aperte</string>
<string name="total_time">Tempo Totale</string> <string name="total_time">Tempo Totale</string>
<string name="average_time">Durata Media</string> <string name="average_time">Durata Media</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">終了</string> <string name="quit">終了</string>
<string name="are_you_sure">本当によろしいですか?</string> <string name="are_you_sure">本当によろしいですか?</string>
<string name="enable_automatic_flags">旗を自動で立てる</string> <string name="enable_automatic_flags">旗を自動で立てる</string>
<string name="enable_no_guessing_maps">解決可能なマップを検索</string>
<string name="open_areas">開いたエリアの数</string> <string name="open_areas">開いたエリアの数</string>
<string name="total_time">合計時間</string> <string name="total_time">合計時間</string>
<string name="average_time">平均時間</string> <string name="average_time">平均時間</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Stoppen</string> <string name="quit">Stoppen</string>
<string name="are_you_sure">Weet je het zeker?</string> <string name="are_you_sure">Weet je het zeker?</string>
<string name="enable_automatic_flags">Schakel automatisch plaatsen van vlaggen in</string> <string name="enable_automatic_flags">Schakel automatisch plaatsen van vlaggen in</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open gebieden</string> <string name="open_areas">Open gebieden</string>
<string name="total_time">Totale Tijd</string> <string name="total_time">Totale Tijd</string>
<string name="average_time">Gemiddelde Tijd</string> <string name="average_time">Gemiddelde Tijd</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Avslutt</string> <string name="quit">Avslutt</string>
<string name="are_you_sure">Er du sikker?</string> <string name="are_you_sure">Er du sikker?</string>
<string name="enable_automatic_flags">Aktiver automatisk plassering av flagg</string> <string name="enable_automatic_flags">Aktiver automatisk plassering av flagg</string>
<string name="enable_no_guessing_maps">Finn løsbare kart</string>
<string name="open_areas">Åpne områder</string> <string name="open_areas">Åpne områder</string>
<string name="total_time">Total Tid</string> <string name="total_time">Total Tid</string>
<string name="average_time">Gjennomsnittlig Tid</string> <string name="average_time">Gjennomsnittlig Tid</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Wyjdź</string> <string name="quit">Wyjdź</string>
<string name="are_you_sure">Na pewno?</string> <string name="are_you_sure">Na pewno?</string>
<string name="enable_automatic_flags">Włącz automatyczne umieszczanie flag</string> <string name="enable_automatic_flags">Włącz automatyczne umieszczanie flag</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Odkryte pola</string> <string name="open_areas">Odkryte pola</string>
<string name="total_time">Całkowity czas gry</string> <string name="total_time">Całkowity czas gry</string>
<string name="average_time">Średni czas gry</string> <string name="average_time">Średni czas gry</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Sair</string> <string name="quit">Sair</string>
<string name="are_you_sure">Tem certeza?</string> <string name="are_you_sure">Tem certeza?</string>
<string name="enable_automatic_flags">Ativar colocação automática de bandeiras</string> <string name="enable_automatic_flags">Ativar colocação automática de bandeiras</string>
<string name="enable_no_guessing_maps">Calcular mapas solucionáveis</string>
<string name="open_areas">Áreas abertas</string> <string name="open_areas">Áreas abertas</string>
<string name="total_time">Tempo total</string> <string name="total_time">Tempo total</string>
<string name="average_time">Tempo médio</string> <string name="average_time">Tempo médio</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Activar colocação automática de bandeiras</string> <string name="enable_automatic_flags">Activar colocação automática de bandeiras</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Выход</string> <string name="quit">Выход</string>
<string name="are_you_sure">Вы уверены?</string> <string name="are_you_sure">Вы уверены?</string>
<string name="enable_automatic_flags">Включить авторазмещение флагов</string> <string name="enable_automatic_flags">Включить авторазмещение флагов</string>
<string name="enable_no_guessing_maps">Найти беспроигрышные поля</string>
<string name="open_areas">Открытые зоны</string> <string name="open_areas">Открытые зоны</string>
<string name="total_time">Общее время</string> <string name="total_time">Общее время</string>
<string name="average_time">Среднее время</string> <string name="average_time">Среднее время</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Çık</string> <string name="quit">Çık</string>
<string name="are_you_sure">Emin misiniz?</string> <string name="are_you_sure">Emin misiniz?</string>
<string name="enable_automatic_flags">Bayrakları Otomatik Yerleştir</string> <string name="enable_automatic_flags">Bayrakları Otomatik Yerleştir</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">ık Alanlar</string> <string name="open_areas">ık Alanlar</string>
<string name="total_time">Toplam Süre</string> <string name="total_time">Toplam Süre</string>
<string name="average_time">Ortalama Süre</string> <string name="average_time">Ortalama Süre</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Вийти</string> <string name="quit">Вийти</string>
<string name="are_you_sure">Ви впевнені?</string> <string name="are_you_sure">Ви впевнені?</string>
<string name="enable_automatic_flags">Увімкнути автоматичне розміщення прапорців</string> <string name="enable_automatic_flags">Увімкнути автоматичне розміщення прапорців</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Відкриті області</string> <string name="open_areas">Відкриті області</string>
<string name="total_time">Час перегляду</string> <string name="total_time">Час перегляду</string>
<string name="average_time">Середній час</string> <string name="average_time">Середній час</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Thoát</string> <string name="quit">Thoát</string>
<string name="are_you_sure">Bạn chắc chứ?</string> <string name="are_you_sure">Bạn chắc chứ?</string>
<string name="enable_automatic_flags">Bật tự động để cờ</string> <string name="enable_automatic_flags">Bật tự động để cờ</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Khu vực mở</string> <string name="open_areas">Khu vực mở</string>
<string name="total_time">Tổng thời gian</string> <string name="total_time">Tổng thời gian</string>
<string name="average_time">Thời gian bình quân</string> <string name="average_time">Thời gian bình quân</string>

View file

@ -48,7 +48,6 @@
<string name="quit">退出</string> <string name="quit">退出</string>
<string name="are_you_sure">你确定吗?</string> <string name="are_you_sure">你确定吗?</string>
<string name="enable_automatic_flags">启用旗标自动放置</string> <string name="enable_automatic_flags">启用旗标自动放置</string>
<string name="enable_no_guessing_maps">查找可解决的地图</string>
<string name="open_areas">开放区域</string> <string name="open_areas">开放区域</string>
<string name="total_time">总用时</string> <string name="total_time">总用时</string>
<string name="average_time">平均用时</string> <string name="average_time">平均用时</string>

View file

@ -48,7 +48,6 @@
<string name="quit">Quit</string> <string name="quit">Quit</string>
<string name="are_you_sure">Are you sure?</string> <string name="are_you_sure">Are you sure?</string>
<string name="enable_automatic_flags">Enable automatic placing of flags</string> <string name="enable_automatic_flags">Enable automatic placing of flags</string>
<string name="enable_no_guessing_maps">Find solvable maps</string>
<string name="open_areas">Open Areas</string> <string name="open_areas">Open Areas</string>
<string name="total_time">Total Time</string> <string name="total_time">Total Time</string>
<string name="average_time">Average Time</string> <string name="average_time">Average Time</string>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen <PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
@ -21,13 +21,6 @@
android:title="@string/enable_automatic_flags" android:title="@string/enable_automatic_flags"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:checked="false"
android:defaultValue="false"
android:key="preference_use_solver_algorithms"
android:title="@string/enable_no_guessing_maps"
app:iconSpaceReserved="false" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
@ -69,4 +62,4 @@
</PreferenceCategory> </PreferenceCategory>
</androidx.preference.PreferenceScreen> </PreferenceScreen>

View file

@ -89,7 +89,7 @@ class GameControllerTest {
withGameController { controller -> withGameController { controller ->
val lastMine = controller.field.last { it.hasMine } val lastMine = controller.field.last { it.hasMine }
assertEquals( assertEquals(
listOf(92, 91, 81, 70, 86, 41, 87, 67, 33, 36, 13, 59, 38, 27, 49, 4, 39, 5, 29, 19), listOf(95, 85, 74, 73, 65, 88, 55, 91, 45, 52, 90, 47, 59, 42, 36, 32, 39, 28, 4, 3),
controller.takeExplosionRadius(lastMine).map { it.id }.toList() controller.takeExplosionRadius(lastMine).map { it.id }.toList()
) )

View file

@ -83,7 +83,7 @@ class MinefieldFactoryTest {
preferencesRepository preferencesRepository
).run { ).run {
assertEquals(49, width) assertEquals(49, width)
assertEquals(97, height) assertEquals(96, height)
assertEquals(950, mines) assertEquals(950, mines)
} }
} }

View file

@ -26,16 +26,14 @@ class BruteForceSolverTest {
fun isSolvable() { fun isSolvable() {
handleMinefield { handler, minefield -> handleMinefield { handler, minefield ->
handler.openAt(40) handler.openAt(40)
val bruteForceSolver = val bruteForceSolver = BruteForceSolver()
BruteForceSolver(minefield.toMutableList()) assertTrue(bruteForceSolver.trySolve(minefield.toMutableList()))
assertTrue(bruteForceSolver.isSolvable())
} }
handleMinefield { handler, minefield -> handleMinefield { handler, minefield ->
handler.openAt(0) handler.openAt(0)
val bruteForceSolver = val bruteForceSolver = BruteForceSolver()
BruteForceSolver(minefield.toMutableList()) assertFalse(bruteForceSolver.trySolve(minefield.toMutableList()))
assertFalse(bruteForceSolver.isSolvable())
} }
} }
} }

View file

@ -0,0 +1,55 @@
package dev.lucasnlm.antimine.common.level.solver
import dev.lucasnlm.antimine.common.level.logic.MinefieldCreator
import dev.lucasnlm.antimine.common.level.logic.MinefieldHandler
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.Minefield
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import java.lang.Thread.sleep
import kotlin.random.Random
class LimitedBruteForceSolverTest {
private fun handleMinefield(block: (MinefieldHandler, MutableList<Area>) -> Unit) {
val creator = MinefieldCreator(
Minefield(9, 9, 12),
Random(200)
)
val minefield = creator.create(40, true).toMutableList()
val minefieldHandler =
MinefieldHandler(minefield, false)
block(minefieldHandler, minefield)
}
@Test
fun isSolvable() {
handleMinefield { handler, minefield ->
handler.openAt(40)
val bruteForceSolver = LimitedBruteForceSolver()
assertTrue(bruteForceSolver.trySolve(minefield.toMutableList()))
}
handleMinefield { handler, minefield ->
handler.openAt(0)
val bruteForceSolver = LimitedBruteForceSolver()
assertFalse(bruteForceSolver.trySolve(minefield.toMutableList()))
}
}
@Test
fun shouldntKeepTryingAfterTimout() {
handleMinefield { handler, _ ->
handler.openAt(40)
val bruteForceSolver = LimitedBruteForceSolver(1000L)
assertTrue(bruteForceSolver.keepTrying())
}
handleMinefield { handler, _ ->
handler.openAt(0)
val bruteForceSolver = LimitedBruteForceSolver(50)
sleep(100)
assertFalse(bruteForceSolver.keepTrying())
}
}
}