Merge pull request #142 from lucasnlm/small-improvements
Small improvements
This commit is contained in:
commit
40fd494962
61 changed files with 159 additions and 161 deletions
|
@ -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.viewmodel.GameViewModel
|
||||
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.preferences.IPreferencesRepository
|
||||
import dev.lucasnlm.antimine.history.HistoryActivity
|
||||
|
@ -57,7 +57,7 @@ class GameActivity : AppCompatActivity(R.layout.activity_game), DialogInterface.
|
|||
lateinit var preferencesRepository: IPreferencesRepository
|
||||
|
||||
@Inject
|
||||
lateinit var analyticsManager: AnalyticsManager
|
||||
lateinit var analyticsManager: IAnalyticsManager
|
||||
|
||||
@Inject
|
||||
lateinit var instantAppManager: InstantAppManager
|
||||
|
@ -117,7 +117,7 @@ class GameActivity : AppCompatActivity(R.layout.activity_game), DialogInterface.
|
|||
retryObserver.observe(
|
||||
this@GameActivity,
|
||||
Observer {
|
||||
GlobalScope.launch {
|
||||
lifecycleScope.launch {
|
||||
viewModel.retryGame(currentSaveId.toInt())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ package dev.lucasnlm.antimine
|
|||
|
||||
import androidx.multidex.MultiDexApplication
|
||||
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 javax.inject.Inject
|
||||
|
||||
@HiltAndroidApp
|
||||
open class MainApplication : MultiDexApplication() {
|
||||
@Inject
|
||||
lateinit var analyticsManager: AnalyticsManager
|
||||
lateinit var analyticsManager: IAnalyticsManager
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
|
|
@ -12,7 +12,7 @@ import dev.lucasnlm.antimine.R
|
|||
import dev.lucasnlm.antimine.about.models.AboutEvent
|
||||
import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel
|
||||
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
|
||||
|
||||
class AboutActivity : AppCompatActivity(R.layout.activity_empty) {
|
||||
|
@ -25,7 +25,7 @@ class AboutActivity : AppCompatActivity(R.layout.activity_empty) {
|
|||
Observer { event ->
|
||||
when (event) {
|
||||
AboutEvent.ThirdPartyLicenses -> {
|
||||
replaceFragment(ThirdPartiesFragment(), ThirdPartiesFragment.TAG)
|
||||
replaceFragment(ThirdPartyFragment(), ThirdPartyFragment.TAG)
|
||||
}
|
||||
AboutEvent.SourceCode -> {
|
||||
openSourceCode()
|
||||
|
|
|
@ -10,6 +10,10 @@ import dev.lucasnlm.antimine.about.models.TranslationInfo
|
|||
class AboutViewModel : ViewModel() {
|
||||
val eventObserver = MutableLiveData<AboutEvent>()
|
||||
|
||||
fun sendEvent(event: AboutEvent) {
|
||||
eventObserver.postValue(event)
|
||||
}
|
||||
|
||||
fun getTranslatorsList() = mapOf(
|
||||
"Arabic" to sequenceOf("Ahmad Alkurbi"),
|
||||
"Bulgarian" to sequenceOf("Georgi Eftimov"),
|
||||
|
|
|
@ -24,15 +24,15 @@ class AboutInfoFragment : Fragment(R.layout.fragment_about_info) {
|
|||
version.text = getString(R.string.version_s, BuildConfig.VERSION_NAME)
|
||||
|
||||
thirdsParties.setOnClickListener {
|
||||
aboutViewModel.eventObserver.postValue(AboutEvent.ThirdPartyLicenses)
|
||||
aboutViewModel.sendEvent(AboutEvent.ThirdPartyLicenses)
|
||||
}
|
||||
|
||||
sourceCode.setOnClickListener {
|
||||
aboutViewModel.eventObserver.postValue(AboutEvent.SourceCode)
|
||||
aboutViewModel.sendEvent(AboutEvent.SourceCode)
|
||||
}
|
||||
|
||||
translation.setOnClickListener {
|
||||
aboutViewModel.eventObserver.postValue(AboutEvent.Translators)
|
||||
aboutViewModel.sendEvent(AboutEvent.Translators)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,16 @@ package dev.lucasnlm.antimine.about.views.thirds
|
|||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import dev.lucasnlm.antimine.R
|
||||
|
||||
import dev.lucasnlm.antimine.text.TextActivity
|
||||
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>
|
||||
) : RecyclerView.Adapter<ThirdPartyViewHolder>() {
|
||||
|
||||
|
@ -32,3 +35,7 @@ class ThirdPartyAdapter(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ThirdPartyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val title: TextView = view.third_name
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import dev.lucasnlm.antimine.R
|
|||
import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel
|
||||
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()
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -30,6 +30,6 @@ class ThirdPartiesFragment : Fragment(R.layout.fragment_third_party) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
val TAG = ThirdPartiesFragment::class.simpleName!!
|
||||
val TAG = ThirdPartyFragment::class.simpleName!!
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -2,15 +2,18 @@ package dev.lucasnlm.antimine.about.views.translators
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dev.lucasnlm.antimine.R
|
||||
import dev.lucasnlm.antimine.about.viewmodel.AboutViewModel
|
||||
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()
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -32,3 +35,8 @@ class TranslatorsFragment : Fragment(R.layout.fragment_translators) {
|
|||
val TAG = TranslatorsFragment::class.simpleName!!
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatorsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val language: TextView = view.language
|
||||
val translators: TextView = view.translators
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -9,7 +9,9 @@ import androidx.appcompat.app.AppCompatDialogFragment
|
|||
import androidx.fragment.app.activityViewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
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.viewmodel.GameViewModel
|
||||
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
|
||||
import dev.lucasnlm.antimine.custom.viewmodel.CreateGameViewModel
|
||||
import javax.inject.Inject
|
||||
|
@ -19,6 +21,7 @@ class CustomLevelDialogFragment : AppCompatDialogFragment() {
|
|||
@Inject
|
||||
lateinit var preferencesRepository: IPreferencesRepository
|
||||
|
||||
private val viewModel by activityViewModels<GameViewModel>()
|
||||
private val createGameViewModel by activityViewModels<CreateGameViewModel>()
|
||||
|
||||
private fun getSelectedMinefield(): Minefield {
|
||||
|
@ -49,10 +52,8 @@ class CustomLevelDialogFragment : AppCompatDialogFragment() {
|
|||
setNegativeButton(R.string.cancel, null)
|
||||
setPositiveButton(R.string.start) { _, _ ->
|
||||
val minefield = getSelectedMinefield()
|
||||
createGameViewModel.run {
|
||||
updateCustomGameMode(minefield)
|
||||
startCustomGame()
|
||||
}
|
||||
createGameViewModel.updateCustomGameMode(minefield)
|
||||
viewModel.startNewGame(Difficulty.Custom)
|
||||
}
|
||||
}.create()
|
||||
}
|
||||
|
|
|
@ -1,32 +1,14 @@
|
|||
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.lifecycle.AndroidViewModel
|
||||
import dev.lucasnlm.antimine.DeepLink
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dev.lucasnlm.antimine.common.level.models.Minefield
|
||||
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
|
||||
|
||||
class CreateGameViewModel @ViewModelInject constructor(
|
||||
application: Application,
|
||||
private val preferencesRepository: IPreferencesRepository
|
||||
) : AndroidViewModel(application) {
|
||||
) : ViewModel() {
|
||||
fun updateCustomGameMode(minefield: 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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false"
|
||||
tools:context="dev.lucasnlm.antimine.about.views.thirds.ThirdPartiesFragment">
|
||||
tools:context="dev.lucasnlm.antimine.about.views.thirds.ThirdPartyFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
|
|
|
@ -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.SaveStatus
|
||||
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.MinefieldCreator
|
||||
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.Score
|
||||
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.GameControl
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
@ -22,9 +22,6 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.flow
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Controls a minesweeper logic.
|
||||
*/
|
||||
class GameController {
|
||||
private val minefield: Minefield
|
||||
private val startTime = System.currentTimeMillis()
|
||||
|
@ -33,7 +30,6 @@ class GameController {
|
|||
private var gameControl: GameControl = GameControl.Standard
|
||||
private var mines: Sequence<Area> = emptySequence()
|
||||
private var useQuestionMark = true
|
||||
private var useSolverAlgorithms = false
|
||||
|
||||
var hasMines = false
|
||||
private set
|
||||
|
@ -68,16 +64,14 @@ class GameController {
|
|||
private fun getArea(id: Int) = field.first { it.id == id }
|
||||
|
||||
private fun plantMinesExcept(safeId: Int) {
|
||||
if (useSolverAlgorithms) {
|
||||
do {
|
||||
field = minefieldCreator.create(safeId, false)
|
||||
val fieldCopy = field.map { it.copy() }.toMutableList()
|
||||
val minefieldHandler = MinefieldHandler(fieldCopy, false)
|
||||
minefieldHandler.openAt(safeId)
|
||||
} while (!BruteForceSolver(minefieldHandler.result().toMutableList()).isSolvable())
|
||||
} else {
|
||||
field = minefieldCreator.create(safeId, true)
|
||||
}
|
||||
val solver = LimitedBruteForceSolver()
|
||||
do {
|
||||
val useSafeZone = minefield.width > 9 && minefield.height > 9
|
||||
field = minefieldCreator.create(safeId, useSafeZone)
|
||||
val fieldCopy = field.map { it.copy() }.toMutableList()
|
||||
val minefieldHandler = MinefieldHandler(fieldCopy, false)
|
||||
minefieldHandler.openAt(safeId)
|
||||
} while (solver.keepTrying() && !solver.trySolve(minefieldHandler.result().toMutableList()))
|
||||
|
||||
mines = field.filter { it.hasMine }.asSequence()
|
||||
firstOpen = FirstOpen.Position(safeId)
|
||||
|
@ -269,8 +263,4 @@ class GameController {
|
|||
fun useQuestionMark(useQuestionMark: Boolean) {
|
||||
this.useQuestionMark = useQuestionMark
|
||||
}
|
||||
|
||||
fun useSolverAlgorithms(useSolverAlgorithms: Boolean) {
|
||||
this.useSolverAlgorithms = useSolverAlgorithms
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.models.Area
|
||||
|
||||
class BruteForceSolver(
|
||||
minefield: MutableList<Area>
|
||||
) : GameSolver(minefield) {
|
||||
private val minefieldHandler =
|
||||
MinefieldHandler(minefield, false)
|
||||
open class BruteForceSolver : GameSolver() {
|
||||
override fun trySolve(minefield: MutableList<Area>): Boolean {
|
||||
val minefieldHandler = MinefieldHandler(minefield, false)
|
||||
|
||||
override fun isSolvable(): Boolean {
|
||||
do {
|
||||
val initialMap = minefield.filter { !it.isCovered && it.minesAround != 0 }
|
||||
initialMap.forEach {
|
||||
|
|
|
@ -2,8 +2,15 @@ package dev.lucasnlm.antimine.common.level.solver
|
|||
|
||||
import dev.lucasnlm.antimine.common.level.models.Area
|
||||
|
||||
abstract class GameSolver(
|
||||
protected val minefield: MutableList<Area>
|
||||
) {
|
||||
abstract fun isSolvable(): Boolean
|
||||
abstract class GameSolver {
|
||||
/**
|
||||
* If true it may keep iterating on this algorithm.
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package dev.lucasnlm.antimine.common.level.view
|
|||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import androidx.core.content.ContextCompat
|
||||
import dev.lucasnlm.antimine.common.R
|
||||
|
@ -122,7 +123,7 @@ fun Area.paintOnCanvas(
|
|||
7 -> areaPalette.minesAround7
|
||||
else -> areaPalette.minesAround8
|
||||
}
|
||||
drawText(canvas, painter, minesAround.toString(), paintSettings)
|
||||
canvas.drawText(minesAround.toString(), paintSettings, painter)
|
||||
}
|
||||
|
||||
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 {
|
||||
val bounds = RectF(rectF).apply {
|
||||
right = paint.measureText(text, 0, text.length)
|
||||
bottom = paint.descent() - paint.ascent()
|
||||
left += (rectF.width() - right) / 2.0f
|
||||
top += (rectF.height() - bottom) / 2.0f
|
||||
}
|
||||
val bounds = Rect()
|
||||
paint.getTextBounds(text.toCharArray(), 0, 1, bounds)
|
||||
paint.textSize = rectF.height() * 0.45f
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.utils.Clock
|
||||
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.control.ActionResponse
|
||||
import dev.lucasnlm.antimine.core.control.GameControl
|
||||
|
@ -42,7 +42,7 @@ class GameViewModel @ViewModelInject constructor(
|
|||
private val hapticFeedbackManager: IHapticFeedbackManager,
|
||||
private val soundManager: ISoundManager,
|
||||
private val minefieldRepository: IMinefieldRepository,
|
||||
private val analyticsManager: AnalyticsManager,
|
||||
private val analyticsManager: IAnalyticsManager,
|
||||
private val clock: Clock
|
||||
) : ViewModel() {
|
||||
val eventObserver = MutableLiveData<Event>()
|
||||
|
@ -346,7 +346,6 @@ class GameViewModel @ViewModelInject constructor(
|
|||
|
||||
updateGameControl(gameControl)
|
||||
useQuestionMark(preferencesRepository.useQuestionMark())
|
||||
useSolverAlgorithms(preferencesRepository.useSolverAlgorithms())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.content.Context
|
|||
import android.util.Log
|
||||
import dev.lucasnlm.antimine.core.analytics.models.Analytics
|
||||
|
||||
class DebugAnalyticsManager : AnalyticsManager {
|
||||
class DebugAnalyticsManager : IAnalyticsManager {
|
||||
override fun setup(context: Context, userProperties: Map<String, String>) {
|
||||
Log.d(TAG, "Setup Analytics using $userProperties")
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package dev.lucasnlm.antimine.core.analytics
|
|||
import android.content.Context
|
||||
import dev.lucasnlm.antimine.core.analytics.models.Analytics
|
||||
|
||||
interface AnalyticsManager {
|
||||
interface IAnalyticsManager {
|
||||
fun setup(context: Context, userProperties: Map<String, String>)
|
||||
fun sentEvent(event: Analytics)
|
||||
}
|
|
@ -6,7 +6,7 @@ import dagger.Provides
|
|||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ApplicationComponent
|
||||
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.preferences.IPreferencesRepository
|
||||
import dev.lucasnlm.antimine.core.preferences.PreferencesManager
|
||||
|
@ -28,7 +28,7 @@ class CommonModule {
|
|||
): PreferencesManager = PreferencesManager(context)
|
||||
|
||||
@Provides
|
||||
fun provideAnalyticsManager(): AnalyticsManager = DebugAnalyticsManager()
|
||||
fun provideAnalyticsManager(): IAnalyticsManager = DebugAnalyticsManager()
|
||||
|
||||
@Provides
|
||||
fun provideSoundManager(
|
||||
|
|
|
@ -24,7 +24,6 @@ interface IPreferencesRepository {
|
|||
fun useAnimations(): Boolean
|
||||
fun useQuestionMark(): Boolean
|
||||
fun isSoundEffectsEnabled(): Boolean
|
||||
fun useSolverAlgorithms(): Boolean
|
||||
}
|
||||
|
||||
class PreferencesRepository(
|
||||
|
@ -78,9 +77,6 @@ class PreferencesRepository(
|
|||
override fun isSoundEffectsEnabled(): Boolean =
|
||||
getBoolean(PREFERENCE_SOUND_EFFECTS, false)
|
||||
|
||||
override fun useSolverAlgorithms(): Boolean =
|
||||
getBoolean(PREFERENCE_USE_SOLVER_ALGORITHMS, false)
|
||||
|
||||
override fun controlStyle(): ControlStyle {
|
||||
val index = getInt(PREFERENCE_CONTROL_STYLE, -1)
|
||||
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_SOUND_EFFECTS = "preference_sound"
|
||||
private const val PREFERENCE_STATS_BASE = "preference_stats_base"
|
||||
private const val PREFERENCE_USE_SOLVER_ALGORITHMS = "preference_use_solver_algorithms"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Verlaat</string>
|
||||
<string name="are_you_sure">Is jy seker?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">خروج</string>
|
||||
<string name="are_you_sure">هل أنت متأكد؟</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="total_time">مجموع الوقت</string>
|
||||
<string name="average_time">متوسط الوقت</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Изход</string>
|
||||
<string name="are_you_sure">Сигурни ли сте?</string>
|
||||
<string name="enable_automatic_flags">Позволява автоматично слагане на флагове</string>
|
||||
<string name="enable_no_guessing_maps">Намери решими карти</string>
|
||||
<string name="open_areas">Отворени площи</string>
|
||||
<string name="total_time">Общо време</string>
|
||||
<string name="average_time">Средно време</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Surt</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_no_guessing_maps">Find solvable maps</string>
|
||||
<string name="open_areas">Zones obertes</string>
|
||||
<string name="total_time">Temps total</string>
|
||||
<string name="average_time">Durada mitjana</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Ukončit</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_no_guessing_maps">Najít řešitelná minová pole</string>
|
||||
<string name="open_areas">Otevřené oblasti</string>
|
||||
<string name="total_time">Celkový čas</string>
|
||||
<string name="average_time">Průměrný čas</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Beenden</string>
|
||||
<string name="are_you_sure">Bist du sicher?</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="total_time">Gesamtzeit</string>
|
||||
<string name="average_time">Durchschnittliche Zeit</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Έξοδος</string>
|
||||
<string name="are_you_sure">Είσαι σίγουρος;</string>
|
||||
<string name="enable_automatic_flags">Ενεργοποίηση αυτόματης τοποθέτησης σημαιών</string>
|
||||
<string name="enable_no_guessing_maps">Find solvable maps</string>
|
||||
<string name="open_areas">Ανοιχτές περιοχές</string>
|
||||
<string name="total_time">Συνολικός Χρόνος</string>
|
||||
<string name="average_time">Μέσος χρόνος</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Salir</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_no_guessing_maps">Encontrar mapas solubles</string>
|
||||
<string name="open_areas">Abrir Áreas</string>
|
||||
<string name="total_time">Tiempo total</string>
|
||||
<string name="average_time">Tiempo promedio</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Lopeta</string>
|
||||
<string name="are_you_sure">Oletko varma?</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="total_time">Aika yhteensä</string>
|
||||
<string name="average_time">Keskimääräinen aika</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quitter</string>
|
||||
<string name="are_you_sure">Vraiment ?</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="total_time">Temps de jeu total</string>
|
||||
<string name="average_time">Temps de jeu moyen</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">समाप्त करें</string>
|
||||
<string name="are_you_sure">क्या आपको यकीन है?</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="total_time">कुल समय</string>
|
||||
<string name="average_time">औसत समय</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Kilépés</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_no_guessing_maps">Megoldható térképek keresése</string>
|
||||
<string name="open_areas">Nyílt területek</string>
|
||||
<string name="total_time">Teljes játékidő</string>
|
||||
<string name="average_time">Átlagos játékidő</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Keluar</string>
|
||||
<string name="are_you_sure">Anda yakin?</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="total_time">Total waktu</string>
|
||||
<string name="average_time">Waktu rata-rata</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Esci</string>
|
||||
<string name="are_you_sure">Sei sicuro?</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="total_time">Tempo Totale</string>
|
||||
<string name="average_time">Durata Media</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">終了</string>
|
||||
<string name="are_you_sure">本当によろしいですか?</string>
|
||||
<string name="enable_automatic_flags">旗を自動で立てる</string>
|
||||
<string name="enable_no_guessing_maps">解決可能なマップを検索</string>
|
||||
<string name="open_areas">開いたエリアの数</string>
|
||||
<string name="total_time">合計時間</string>
|
||||
<string name="average_time">平均時間</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Stoppen</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_no_guessing_maps">Find solvable maps</string>
|
||||
<string name="open_areas">Open gebieden</string>
|
||||
<string name="total_time">Totale Tijd</string>
|
||||
<string name="average_time">Gemiddelde Tijd</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Avslutt</string>
|
||||
<string name="are_you_sure">Er du sikker?</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="total_time">Total Tid</string>
|
||||
<string name="average_time">Gjennomsnittlig Tid</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Wyjdź</string>
|
||||
<string name="are_you_sure">Na pewno?</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="total_time">Całkowity czas gry</string>
|
||||
<string name="average_time">Średni czas gry</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Sair</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_no_guessing_maps">Calcular mapas solucionáveis</string>
|
||||
<string name="open_areas">Áreas abertas</string>
|
||||
<string name="total_time">Tempo total</string>
|
||||
<string name="average_time">Tempo médio</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</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_no_guessing_maps">Find solvable maps</string>
|
||||
<string name="open_areas">Open Areas</string>
|
||||
<string name="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Выход</string>
|
||||
<string name="are_you_sure">Вы уверены?</string>
|
||||
<string name="enable_automatic_flags">Включить авторазмещение флагов</string>
|
||||
<string name="enable_no_guessing_maps">Найти беспроигрышные поля</string>
|
||||
<string name="open_areas">Открытые зоны</string>
|
||||
<string name="total_time">Общее время</string>
|
||||
<string name="average_time">Среднее время</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Çık</string>
|
||||
<string name="are_you_sure">Emin misiniz?</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">Açık Alanlar</string>
|
||||
<string name="total_time">Toplam Süre</string>
|
||||
<string name="average_time">Ortalama Süre</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Вийти</string>
|
||||
<string name="are_you_sure">Ви впевнені?</string>
|
||||
<string name="enable_automatic_flags">Увімкнути автоматичне розміщення прапорців</string>
|
||||
<string name="enable_no_guessing_maps">Find solvable maps</string>
|
||||
<string name="open_areas">Відкриті області</string>
|
||||
<string name="total_time">Час перегляду</string>
|
||||
<string name="average_time">Середній час</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Thoát</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_no_guessing_maps">Find solvable maps</string>
|
||||
<string name="open_areas">Khu vực mở</string>
|
||||
<string name="total_time">Tổng thời gian</string>
|
||||
<string name="average_time">Thời gian bình quân</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">退出</string>
|
||||
<string name="are_you_sure">你确定吗?</string>
|
||||
<string name="enable_automatic_flags">启用旗标自动放置</string>
|
||||
<string name="enable_no_guessing_maps">查找可解决的地图</string>
|
||||
<string name="open_areas">开放区域</string>
|
||||
<string name="total_time">总用时</string>
|
||||
<string name="average_time">平均用时</string>
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
<string name="quit">Quit</string>
|
||||
<string name="are_you_sure">Are you sure?</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="total_time">Total Time</string>
|
||||
<string name="average_time">Average Time</string>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
@ -21,13 +21,6 @@
|
|||
android:title="@string/enable_automatic_flags"
|
||||
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
|
||||
|
@ -69,4 +62,4 @@
|
|||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -89,7 +89,7 @@ class GameControllerTest {
|
|||
withGameController { controller ->
|
||||
val lastMine = controller.field.last { it.hasMine }
|
||||
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()
|
||||
)
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ class MinefieldFactoryTest {
|
|||
preferencesRepository
|
||||
).run {
|
||||
assertEquals(49, width)
|
||||
assertEquals(97, height)
|
||||
assertEquals(96, height)
|
||||
assertEquals(950, mines)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,16 +26,14 @@ class BruteForceSolverTest {
|
|||
fun isSolvable() {
|
||||
handleMinefield { handler, minefield ->
|
||||
handler.openAt(40)
|
||||
val bruteForceSolver =
|
||||
BruteForceSolver(minefield.toMutableList())
|
||||
assertTrue(bruteForceSolver.isSolvable())
|
||||
val bruteForceSolver = BruteForceSolver()
|
||||
assertTrue(bruteForceSolver.trySolve(minefield.toMutableList()))
|
||||
}
|
||||
|
||||
handleMinefield { handler, minefield ->
|
||||
handler.openAt(0)
|
||||
val bruteForceSolver =
|
||||
BruteForceSolver(minefield.toMutableList())
|
||||
assertFalse(bruteForceSolver.isSolvable())
|
||||
val bruteForceSolver = BruteForceSolver()
|
||||
assertFalse(bruteForceSolver.trySolve(minefield.toMutableList()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue