Move code to modules

This commit is contained in:
Lucas Lima 2020-12-31 17:18:47 -03:00 committed by Lucas Nunes
parent 93812c1b50
commit 8e96da3996
93 changed files with 597 additions and 278 deletions

View file

@ -105,6 +105,8 @@ dependencies {
implementation project(':about') implementation project(':about')
implementation project(':ui') implementation project(':ui')
implementation project(':preferences') implementation project(':preferences')
implementation project(':themes')
implementation project(':purchases')
implementation project(':core') implementation project(':core')
googleImplementation project(':proprietary') googleImplementation project(':proprietary')

View file

@ -85,16 +85,6 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:label="@string/themes"
android:name="dev.lucasnlm.antimine.theme.ThemeActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="dev.lucasnlm.antimine.GameActivity" />
</activity>
<activity <activity
android:name="dev.lucasnlm.antimine.stats.StatsActivity" android:name="dev.lucasnlm.antimine.stats.StatsActivity"
android:label="@string/events" android:label="@string/events"

View file

@ -26,15 +26,16 @@ import androidx.lifecycle.Transformations
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Event import dev.lucasnlm.antimine.common.level.models.Event
import dev.lucasnlm.antimine.common.level.models.Score import dev.lucasnlm.antimine.core.models.Score
import dev.lucasnlm.antimine.common.level.models.Status 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.IAnalyticsManager import dev.lucasnlm.antimine.core.cloud.CloudSaveManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.preferences.models.ControlStyle import dev.lucasnlm.antimine.preferences.models.ControlStyle
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.custom.CustomLevelDialogFragment import dev.lucasnlm.antimine.custom.CustomLevelDialogFragment
@ -44,11 +45,11 @@ import dev.lucasnlm.antimine.gameover.model.GameResult
import dev.lucasnlm.antimine.level.view.LevelFragment import dev.lucasnlm.antimine.level.view.LevelFragment
import dev.lucasnlm.antimine.playgames.PlayGamesDialogFragment import dev.lucasnlm.antimine.playgames.PlayGamesDialogFragment
import dev.lucasnlm.antimine.preferences.PreferencesActivity import dev.lucasnlm.antimine.preferences.PreferencesActivity
import dev.lucasnlm.antimine.purchases.SupportAppDialogFragment
import dev.lucasnlm.antimine.share.ShareManager import dev.lucasnlm.antimine.share.ShareManager
import dev.lucasnlm.antimine.splash.SplashActivity import dev.lucasnlm.antimine.splash.SplashActivity
import dev.lucasnlm.antimine.stats.StatsActivity import dev.lucasnlm.antimine.stats.StatsActivity
import dev.lucasnlm.antimine.support.SupportAppDialogFragment import dev.lucasnlm.antimine.themes.ThemeActivity
import dev.lucasnlm.antimine.theme.ThemeActivity
import dev.lucasnlm.antimine.tutorial.view.TutorialCompleteDialogFragment import dev.lucasnlm.antimine.tutorial.view.TutorialCompleteDialogFragment
import dev.lucasnlm.antimine.tutorial.view.TutorialLevelFragment import dev.lucasnlm.antimine.tutorial.view.TutorialLevelFragment
import dev.lucasnlm.antimine.ui.ThematicActivity import dev.lucasnlm.antimine.ui.ThematicActivity

View file

@ -2,8 +2,8 @@ package dev.lucasnlm.antimine
import androidx.multidex.MultiDexApplication import androidx.multidex.MultiDexApplication
import dev.lucasnlm.antimine.common.level.di.LevelModule import dev.lucasnlm.antimine.common.level.di.LevelModule
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.core.di.CommonModule import dev.lucasnlm.antimine.core.di.CommonModule
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.di.AppModule import dev.lucasnlm.antimine.di.AppModule

View file

@ -10,7 +10,7 @@ import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDialogFragment import androidx.appcompat.app.AppCompatDialogFragment
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository

View file

@ -4,7 +4,7 @@ import dev.lucasnlm.antimine.cloud.CloudSaveManagerImpl
import dev.lucasnlm.antimine.support.IapHandler import dev.lucasnlm.antimine.support.IapHandler
import dev.lucasnlm.antimine.common.BuildConfig import dev.lucasnlm.antimine.common.BuildConfig
import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.ProdAnalyticsManager import dev.lucasnlm.antimine.core.analytics.ProdAnalyticsManager
import dev.lucasnlm.antimine.core.cloud.CloudSaveManager import dev.lucasnlm.antimine.core.cloud.CloudSaveManager
import dev.lucasnlm.antimine.share.ShareManager import dev.lucasnlm.antimine.share.ShareManager

View file

@ -10,7 +10,7 @@ import dev.lucasnlm.antimine.playgames.viewmodel.PlayGamesViewModel
import dev.lucasnlm.antimine.splash.viewmodel.SplashViewModel import dev.lucasnlm.antimine.splash.viewmodel.SplashViewModel
import dev.lucasnlm.antimine.stats.viewmodel.StatsViewModel import dev.lucasnlm.antimine.stats.viewmodel.StatsViewModel
import dev.lucasnlm.antimine.text.viewmodel.TextViewModel import dev.lucasnlm.antimine.text.viewmodel.TextViewModel
import dev.lucasnlm.antimine.theme.viewmodel.ThemeViewModel import dev.lucasnlm.antimine.themes.viewmodel.ThemeViewModel
import dev.lucasnlm.antimine.tutorial.viewmodel.TutorialViewModel import dev.lucasnlm.antimine.tutorial.viewmodel.TutorialViewModel
import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module

View file

@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
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.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.core.viewmodel.StatelessViewModel import dev.lucasnlm.antimine.core.viewmodel.StatelessViewModel
import dev.lucasnlm.antimine.history.viewmodel.HistoryEvent import dev.lucasnlm.antimine.history.viewmodel.HistoryEvent
import kotlinx.android.synthetic.main.view_history_item.view.* import kotlinx.android.synthetic.main.view_history_item.view.*

View file

@ -6,10 +6,10 @@ import androidx.core.view.doOnLayout
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import dev.lucasnlm.antimine.DeepLink import dev.lucasnlm.antimine.DeepLink
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Event import dev.lucasnlm.antimine.common.level.models.Event
import dev.lucasnlm.antimine.common.level.view.CommonLevelFragment import dev.lucasnlm.antimine.common.level.view.CommonLevelFragment
import dev.lucasnlm.antimine.common.level.view.SpaceItemDecoration import dev.lucasnlm.antimine.ui.view.SpaceItemDecoration
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext

View file

@ -2,8 +2,8 @@ package dev.lucasnlm.antimine.playgames.viewmodel
import android.app.Activity import android.app.Activity
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.core.viewmodel.StatelessViewModel import dev.lucasnlm.antimine.core.viewmodel.StatelessViewModel
import dev.lucasnlm.antimine.playgames.model.PlayGamesItem import dev.lucasnlm.antimine.playgames.model.PlayGamesItem
import dev.lucasnlm.external.IPlayGamesManager import dev.lucasnlm.external.IPlayGamesManager

View file

@ -7,6 +7,7 @@ import android.view.MenuItem
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.core.cloud.CloudSaveManager
import dev.lucasnlm.antimine.ui.ThematicActivity import dev.lucasnlm.antimine.ui.ThematicActivity
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject

View file

@ -13,10 +13,10 @@ import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import dev.lucasnlm.antimine.BuildConfig import dev.lucasnlm.antimine.BuildConfig
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings import dev.lucasnlm.antimine.core.models.AreaPaintSettings
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.view.paintOnCanvas import dev.lucasnlm.antimine.ui.view.paintOnCanvas
import dev.lucasnlm.antimine.ui.repository.IThemeRepository import dev.lucasnlm.antimine.ui.repository.IThemeRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext

View file

@ -2,9 +2,9 @@ package dev.lucasnlm.antimine.stats.viewmodel
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.database.models.Stats import dev.lucasnlm.antimine.common.level.database.models.Stats
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository
import dev.lucasnlm.antimine.common.level.repository.IStatsRepository import dev.lucasnlm.antimine.common.level.repository.IStatsRepository
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository

View file

@ -8,15 +8,15 @@ import android.view.KeyEvent
import android.view.MotionEvent import android.view.MotionEvent
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings import dev.lucasnlm.antimine.core.models.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.view.AreaAdapter import dev.lucasnlm.antimine.ui.view.AreaView
import dev.lucasnlm.antimine.common.level.view.AreaView
import dev.lucasnlm.antimine.common.level.view.AreaViewHolder import dev.lucasnlm.antimine.common.level.view.AreaViewHolder
import dev.lucasnlm.antimine.preferences.models.ControlStyle import dev.lucasnlm.antimine.preferences.models.ControlStyle
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.tutorial.viewmodel.TutorialViewModel import dev.lucasnlm.antimine.tutorial.viewmodel.TutorialViewModel
import dev.lucasnlm.antimine.ui.view.createAreaPaintSettings
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -36,7 +36,7 @@ class TutorialAreaAdapter(
init { init {
setHasStableIds(false) setHasStableIds(false)
paintSettings = AreaAdapter.createAreaPaintSettings( paintSettings = createAreaPaintSettings(
context.applicationContext, context.applicationContext,
dimensionRepository.areaSize(), dimensionRepository.areaSize(),
preferencesRepository.squareRadius(), preferencesRepository.squareRadius(),

View file

@ -11,7 +11,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDialogFragment import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Event import dev.lucasnlm.antimine.common.level.models.Event
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel

View file

@ -1,7 +1,7 @@
package dev.lucasnlm.antimine.tutorial.view package dev.lucasnlm.antimine.tutorial.view
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
object TutorialField { object TutorialField {
fun getStep0(): List<Area> { fun getStep0(): List<Area> {

View file

@ -12,8 +12,8 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.models.Event import dev.lucasnlm.antimine.common.level.models.Event
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.view.SpaceItemDecoration import dev.lucasnlm.antimine.ui.view.SpaceItemDecoration
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.tutorial.viewmodel.TutorialViewModel import dev.lucasnlm.antimine.tutorial.viewmodel.TutorialViewModel

View file

@ -2,8 +2,8 @@ package dev.lucasnlm.antimine.tutorial.viewmodel
import android.content.Context import android.content.Context
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository
import dev.lucasnlm.antimine.common.level.repository.ISavesRepository import dev.lucasnlm.antimine.common.level.repository.ISavesRepository
import dev.lucasnlm.antimine.common.level.repository.IStatsRepository import dev.lucasnlm.antimine.common.level.repository.IStatsRepository
@ -11,8 +11,8 @@ import dev.lucasnlm.antimine.common.level.repository.ITipRepository
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.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.preferences.models.ControlStyle import dev.lucasnlm.antimine.preferences.models.ControlStyle
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.core.sound.ISoundManager import dev.lucasnlm.antimine.core.sound.ISoundManager

View file

@ -4,7 +4,7 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.share.ShareManager import dev.lucasnlm.antimine.share.ShareManager
import dev.lucasnlm.external.Achievement import dev.lucasnlm.external.Achievement
import dev.lucasnlm.external.IBillingManager import dev.lucasnlm.external.IBillingManager

View file

@ -1,6 +1,6 @@
package dev.lucasnlm.antimine.di package dev.lucasnlm.antimine.di
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.core.sound.ISoundManager import dev.lucasnlm.antimine.core.sound.ISoundManager
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme

View file

@ -4,7 +4,7 @@ import dev.lucasnlm.antimine.IntentViewModelTest
import dev.lucasnlm.antimine.common.level.database.models.FirstOpen 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.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.repository.ISavesRepository import dev.lucasnlm.antimine.common.level.repository.ISavesRepository
import dev.lucasnlm.antimine.history.viewmodel.HistoryEvent import dev.lucasnlm.antimine.history.viewmodel.HistoryEvent

View file

@ -1,7 +1,7 @@
package dev.lucasnlm.antimine.mocks package dev.lucasnlm.antimine.mocks
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.repository.Size import dev.lucasnlm.antimine.core.repository.Size
class FixedDimensionRepository : IDimensionRepository { class FixedDimensionRepository : IDimensionRepository {
override fun areaSize(): Float = 50.0f override fun areaSize(): Float = 50.0f

View file

@ -1,8 +1,8 @@
package dev.lucasnlm.antimine.mocks package dev.lucasnlm.antimine.mocks
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository

View file

@ -3,7 +3,7 @@ package dev.lucasnlm.antimine.stats.viewmodel
import dev.lucasnlm.antimine.IntentViewModelTest import dev.lucasnlm.antimine.IntentViewModelTest
import dev.lucasnlm.antimine.common.level.database.models.Stats import dev.lucasnlm.antimine.common.level.database.models.Stats
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository
import dev.lucasnlm.antimine.common.level.repository.MemoryStatsRepository import dev.lucasnlm.antimine.common.level.repository.MemoryStatsRepository
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository

View file

@ -2,7 +2,7 @@ package dev.lucasnlm.antimine.theme
import dev.lucasnlm.antimine.IntentViewModelTest import dev.lucasnlm.antimine.IntentViewModelTest
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme
import dev.lucasnlm.antimine.ui.model.AreaPalette import dev.lucasnlm.antimine.ui.model.AreaPalette

View file

@ -38,6 +38,7 @@ dependencies {
// Dependencies must be hardcoded to support F-droid // Dependencies must be hardcoded to support F-droid
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':core')
implementation project(':external') implementation project(':external')
implementation project(':i18n') implementation project(':i18n')
implementation project(':preferences') implementation project(':preferences')

View file

@ -6,10 +6,9 @@ import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.Paint import android.graphics.Paint
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
import dev.lucasnlm.antimine.common.level.view.AreaAdapter import dev.lucasnlm.antimine.common.level.view.AreaAdapter
import dev.lucasnlm.antimine.common.level.view.paintOnCanvas
import dev.lucasnlm.antimine.ui.repository.Themes.LightTheme import dev.lucasnlm.antimine.ui.repository.Themes.LightTheme
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
@ -20,7 +19,7 @@ import java.io.FileOutputStream
class AreaScreenshot { class AreaScreenshot {
private lateinit var context: Context private lateinit var context: Context
private fun saveImage(area: Area, fileName: String, ambientMode: Boolean): File { private fun saveImage(area: dev.lucasnlm.antimine.core.models.Area, fileName: String, ambientMode: Boolean): File {
val paintSettings = AreaAdapter.createAreaPaintSettings(context, 128.0f, 3) val paintSettings = AreaAdapter.createAreaPaintSettings(context, 128.0f, 3)
val size = paintSettings.rectF.width().toInt() val size = paintSettings.rectF.width().toInt()
val testPadding = 4 val testPadding = 4
@ -73,7 +72,7 @@ class AreaScreenshot {
return result return result
} }
private fun screenshotTest(area: Area, fileName: String, ambientMode: Boolean = false) { private fun screenshotTest(area: dev.lucasnlm.antimine.core.models.Area, fileName: String, ambientMode: Boolean = false) {
val current = saveImage(area, fileName, ambientMode) val current = saveImage(area, fileName, ambientMode)
assertTrue("$fileName doesn't match the reference", compareScreenshot(current, fileName)) assertTrue("$fileName doesn't match the reference", compareScreenshot(current, fileName))
} }
@ -85,25 +84,25 @@ class AreaScreenshot {
@Test @Test
fun testCoveredArea() { fun testCoveredArea() {
val area = Area(0, 0, 0, isCovered = true) val area = dev.lucasnlm.antimine.core.models.Area(0, 0, 0, isCovered = true)
screenshotTest(area, "covered.png") screenshotTest(area, "covered.png")
} }
@Test @Test
fun testCoveredAreaAmbientMode() { fun testCoveredAreaAmbientMode() {
val area = Area(0, 0, 0, isCovered = true) val area = dev.lucasnlm.antimine.core.models.Area(0, 0, 0, isCovered = true)
screenshotTest(area, "covered_ambient.png", true) screenshotTest(area, "covered_ambient.png", true)
} }
@Test @Test
fun testUncoveredArea() { fun testUncoveredArea() {
val area = Area(0, 0, 0, isCovered = false) val area = dev.lucasnlm.antimine.core.models.Area(0, 0, 0, isCovered = false)
screenshotTest(area, "uncovered.png") screenshotTest(area, "uncovered.png")
} }
@Test @Test
fun testUncoveredAreaAmbientMode() { fun testUncoveredAreaAmbientMode() {
val area = Area(0, 0, 0, isCovered = false) val area = dev.lucasnlm.antimine.core.models.Area(0, 0, 0, isCovered = false)
screenshotTest(area, "uncovered_ambient.png", ambientMode = true) screenshotTest(area, "uncovered_ambient.png", ambientMode = true)
} }
@ -112,7 +111,7 @@ class AreaScreenshot {
repeat(8) { repeat(8) {
val id = it + 1 val id = it + 1
screenshotTest( screenshotTest(
Area( dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -129,7 +128,7 @@ class AreaScreenshot {
repeat(8) { repeat(8) {
val id = it + 1 val id = it + 1
screenshotTest( screenshotTest(
Area( dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -144,55 +143,55 @@ class AreaScreenshot {
@Test @Test
fun testCoveredAreaWithFlag() { fun testCoveredAreaWithFlag() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
isCovered = true, isCovered = true,
mark = Mark.Flag mark = dev.lucasnlm.antimine.core.models.Mark.Flag
) )
screenshotTest(area, "covered_flag.png") screenshotTest(area, "covered_flag.png")
} }
@Test @Test
fun testCoveredAreaWithFlagAmbient() { fun testCoveredAreaWithFlagAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
isCovered = true, isCovered = true,
mark = Mark.Flag mark = dev.lucasnlm.antimine.core.models.Mark.Flag
) )
screenshotTest(area, "covered_flag_ambient.png", true) screenshotTest(area, "covered_flag_ambient.png", true)
} }
@Test @Test
fun testCoveredAreaWithQuestion() { fun testCoveredAreaWithQuestion() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
isCovered = true, isCovered = true,
mark = Mark.Question mark = dev.lucasnlm.antimine.core.models.Mark.Question
) )
screenshotTest(area, "covered_question.png") screenshotTest(area, "covered_question.png")
} }
@Test @Test
fun testCoveredAreaWithQuestionAmbient() { fun testCoveredAreaWithQuestionAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
isCovered = true, isCovered = true,
mark = Mark.Question mark = dev.lucasnlm.antimine.core.models.Mark.Question
) )
screenshotTest(area, "covered_question_ambient.png", true) screenshotTest(area, "covered_question_ambient.png", true)
} }
@Test @Test
fun testCoveredAreaHighlighted() { fun testCoveredAreaHighlighted() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -204,7 +203,7 @@ class AreaScreenshot {
@Test @Test
fun testCoveredAreaHighlightedAmbient() { fun testCoveredAreaHighlightedAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -216,7 +215,7 @@ class AreaScreenshot {
@Test @Test
fun testCoveredAreaWithMine() { fun testCoveredAreaWithMine() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -228,7 +227,7 @@ class AreaScreenshot {
@Test @Test
fun testCoveredAreaWithMineAmbient() { fun testCoveredAreaWithMineAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -240,7 +239,7 @@ class AreaScreenshot {
@Test @Test
fun testUncoveredAreaWithMine() { fun testUncoveredAreaWithMine() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -252,7 +251,7 @@ class AreaScreenshot {
@Test @Test
fun testUncoveredAreaWithMineAmbient() { fun testUncoveredAreaWithMineAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -264,7 +263,7 @@ class AreaScreenshot {
@Test @Test
fun testUncoveredAreaHighlighted() { fun testUncoveredAreaHighlighted() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -277,7 +276,7 @@ class AreaScreenshot {
@Test @Test
fun testUncoveredAreaHighlightedAmbient() { fun testUncoveredAreaHighlightedAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -290,7 +289,7 @@ class AreaScreenshot {
@Test @Test
fun testUncoveredAreaWithMineExploded() { fun testUncoveredAreaWithMineExploded() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -303,7 +302,7 @@ class AreaScreenshot {
@Test @Test
fun testUncoveredAreaWithMineExplodedAmbient() { fun testUncoveredAreaWithMineExplodedAmbient() {
val area = Area( val area = dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -319,7 +318,7 @@ class AreaScreenshot {
repeat(8) { repeat(8) {
val id = it + 1 val id = it + 1
screenshotTest( screenshotTest(
Area( dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,
@ -337,7 +336,7 @@ class AreaScreenshot {
repeat(8) { repeat(8) {
val id = it + 1 val id = it + 1
screenshotTest( screenshotTest(
Area( dev.lucasnlm.antimine.core.models.Area(
0, 0,
0, 0,
0, 0,

View file

@ -7,11 +7,11 @@ import dev.lucasnlm.antimine.common.level.database.models.Stats
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
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.models.Score import dev.lucasnlm.antimine.core.models.Score
import dev.lucasnlm.antimine.common.level.solver.LimitedBruteForceSolver import dev.lucasnlm.antimine.common.level.solver.LimitedBruteForceSolver
import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.ActionResponse import dev.lucasnlm.antimine.preferences.models.ActionResponse
import dev.lucasnlm.antimine.preferences.models.GameControl import dev.lucasnlm.antimine.preferences.models.GameControl
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
@ -56,7 +56,7 @@ class GameController {
fun field() = field fun field() = field
fun field(predicate: (Area) -> Boolean) = field.filter(predicate) fun field(predicate: (dev.lucasnlm.antimine.core.models.Area) -> Boolean) = field.filter(predicate)
fun mines() = field.filter { it.hasMine } fun mines() = field.filter { it.hasMine }
@ -77,7 +77,7 @@ class GameController {
firstOpen = FirstOpen.Position(safeId) firstOpen = FirstOpen.Position(safeId)
} }
private fun handleAction(target: Area, actionResponse: ActionResponse?) { private fun handleAction(target: dev.lucasnlm.antimine.core.models.Area, actionResponse: ActionResponse?) {
val mustPlantMines = !hasMines() val mustPlantMines = !hasMines()
val minefieldHandler: MinefieldHandler val minefieldHandler: MinefieldHandler
@ -175,7 +175,7 @@ class GameController {
} }
} }
fun getScore() = Score( fun getScore() = dev.lucasnlm.antimine.core.models.Score(
mines().count { !it.mistake && it.mark.isFlag() }, mines().count { !it.mistake && it.mark.isFlag() },
getMinesCount(), getMinesCount(),
field.count() field.count()
@ -192,7 +192,7 @@ class GameController {
fun findExplodedMine() = mines().firstOrNull { it.mistake } fun findExplodedMine() = mines().firstOrNull { it.mistake }
fun takeExplosionRadius(target: Area): List<Area> = fun takeExplosionRadius(target: dev.lucasnlm.antimine.core.models.Area): List<dev.lucasnlm.antimine.core.models.Area> =
mines().filter { it.isCovered && it.mark.isNone() }.sortedBy { mines().filter { it.isCovered && it.mark.isNone() }.sortedBy {
val dx1 = (it.posX - target.posX) val dx1 = (it.posX - target.posX)
val dy1 = (it.posY - target.posY) val dy1 = (it.posY - target.posY)

View file

@ -5,21 +5,21 @@ import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.Types import com.squareup.moshi.Types
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import java.lang.reflect.Type import java.lang.reflect.Type
class AreaConverter { class AreaConverter {
private val moshi: Moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() private val moshi: Moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
private val jsonAdapter: JsonAdapter<List<Area>> private val jsonAdapter: JsonAdapter<List<dev.lucasnlm.antimine.core.models.Area>>
init { init {
val type: Type = Types.newParameterizedType(List::class.java, Area::class.java) val type: Type = Types.newParameterizedType(List::class.java, dev.lucasnlm.antimine.core.models.Area::class.java)
this.jsonAdapter = moshi.adapter(type) this.jsonAdapter = moshi.adapter(type)
} }
@TypeConverter @TypeConverter
fun toAreaList(jsonInput: String): List<Area> = jsonAdapter.fromJson(jsonInput) ?: listOf() fun toAreaList(jsonInput: String): List<dev.lucasnlm.antimine.core.models.Area> = jsonAdapter.fromJson(jsonInput) ?: listOf()
@TypeConverter @TypeConverter
fun toJsonString(field: List<Area>): String = jsonAdapter.toJson(field) fun toJsonString(field: List<dev.lucasnlm.antimine.core.models.Area>): String = jsonAdapter.toJson(field)
} }

View file

@ -1,7 +1,7 @@
package dev.lucasnlm.antimine.common.level.database.converters package dev.lucasnlm.antimine.common.level.database.converters
import androidx.room.TypeConverter import androidx.room.TypeConverter
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
class DifficultyConverter { class DifficultyConverter {
@TypeConverter @TypeConverter

View file

@ -4,12 +4,11 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import androidx.room.TypeConverters import androidx.room.TypeConverters
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.database.converters.AreaConverter import dev.lucasnlm.antimine.common.level.database.converters.AreaConverter
import dev.lucasnlm.antimine.common.level.database.converters.FirstOpenConverter import dev.lucasnlm.antimine.common.level.database.converters.FirstOpenConverter
import dev.lucasnlm.antimine.common.level.database.converters.SaveStatusConverter import dev.lucasnlm.antimine.common.level.database.converters.SaveStatusConverter
import dev.lucasnlm.antimine.core.models.Difficulty
@Entity @Entity
data class Save( data class Save(
@ -41,7 +40,7 @@ data class Save(
@TypeConverters(AreaConverter::class) @TypeConverters(AreaConverter::class)
@ColumnInfo(name = "field") @ColumnInfo(name = "field")
val field: List<Area>, val field: List<dev.lucasnlm.antimine.core.models.Area>,
@ColumnInfo(name = "actions") @ColumnInfo(name = "actions")
val actions: Int, val actions: Int,

View file

@ -1,10 +1,10 @@
package dev.lucasnlm.antimine.common.level.logic package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
class FlagAssistant( class FlagAssistant(
private val field: MutableList<Area>, private val field: MutableList<dev.lucasnlm.antimine.core.models.Area>,
) { ) {
fun runFlagAssistant() { fun runFlagAssistant() {
// Must not select Mark.PurposefulNone, only Mark.None. Otherwise, it will flag // Must not select Mark.PurposefulNone, only Mark.None. Otherwise, it will flag
@ -14,9 +14,9 @@ class FlagAssistant(
.forEach(::putFlagIfIsolated) .forEach(::putFlagIfIsolated)
} }
fun result(): List<Area> = field.toList() fun result(): List<dev.lucasnlm.antimine.core.models.Area> = field.toList()
private fun putFlagIfIsolated(it: Area) { private fun putFlagIfIsolated(it: dev.lucasnlm.antimine.core.models.Area) {
val neighbors = field.filterNeighborsOf(it) val neighbors = field.filterNeighborsOf(it)
val neighborsCount = neighbors.count() val neighborsCount = neighbors.count()
val revealedNeighborsCount = neighbors.count { neighbor -> val revealedNeighborsCount = neighbors.count { neighbor ->
@ -24,7 +24,7 @@ class FlagAssistant(
} }
if (revealedNeighborsCount == neighborsCount) { if (revealedNeighborsCount == neighborsCount) {
field[it.id] = it.copy(mark = Mark.Flag) field[it.id] = it.copy(mark = dev.lucasnlm.antimine.core.models.Mark.Flag)
} }
} }
} }

View file

@ -1,6 +1,6 @@
package dev.lucasnlm.antimine.common.level.logic package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import kotlin.math.floor import kotlin.math.floor
import kotlin.random.Random import kotlin.random.Random
@ -9,7 +9,7 @@ class MinefieldCreator(
private val minefield: Minefield, private val minefield: Minefield,
private val randomGenerator: Random, private val randomGenerator: Random,
) { ) {
private fun createMutableEmpty(): List<Area> { private fun createMutableEmpty(): List<dev.lucasnlm.antimine.core.models.Area> {
val width = minefield.width val width = minefield.width
val height = minefield.height val height = minefield.height
val fieldLength = width * height val fieldLength = width * height
@ -17,7 +17,7 @@ class MinefieldCreator(
return (0 until fieldLength).map { index -> return (0 until fieldLength).map { index ->
val yPosition = floor((index / width).toDouble()).toInt() val yPosition = floor((index / width).toDouble()).toInt()
val xPosition = (index % width) val xPosition = (index % width)
Area( dev.lucasnlm.antimine.core.models.Area(
index, index,
xPosition, xPosition,
yPosition, yPosition,
@ -27,11 +27,11 @@ class MinefieldCreator(
} }
} }
fun createEmpty(): List<Area> { fun createEmpty(): List<dev.lucasnlm.antimine.core.models.Area> {
return createMutableEmpty() return createMutableEmpty()
} }
fun create(safeIndex: Int, safeZone: Boolean): List<Area> { fun create(safeIndex: Int, safeZone: Boolean): List<dev.lucasnlm.antimine.core.models.Area> {
return createMutableEmpty().toMutableList().apply { return createMutableEmpty().toMutableList().apply {
// Plant mines and setup number tips // Plant mines and setup number tips
if (safeZone) { filterNotNeighborsOf(safeIndex) } else { filterNot { it.id == safeIndex } } if (safeZone) { filterNotNeighborsOf(safeIndex) } else { filterNot { it.id == safeIndex } }

View file

@ -1,6 +1,6 @@
package dev.lucasnlm.antimine.common.level.logic package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
fun List<Area>.withId(id: Int) = this.first { it.id == id } fun List<Area>.withId(id: Int) = this.first { it.id == id }

View file

@ -1,20 +1,20 @@
package dev.lucasnlm.antimine.common.level.logic package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
class MinefieldHandler( class MinefieldHandler(
private val field: MutableList<Area>, private val field: MutableList<dev.lucasnlm.antimine.core.models.Area>,
private val useQuestionMark: Boolean, private val useQuestionMark: Boolean,
) { ) {
fun showAllMines() { fun showAllMines() {
field.filter { it.hasMine && it.mark != Mark.Flag } field.filter { it.hasMine && it.mark != dev.lucasnlm.antimine.core.models.Mark.Flag }
.forEach { field[it.id] = it.copy(isCovered = false) } .forEach { field[it.id] = it.copy(isCovered = false) }
} }
fun flagAllMines() { fun flagAllMines() {
field.filter { it.hasMine } field.filter { it.hasMine }
.forEach { field[it.id] = it.copy(mark = Mark.Flag) } .forEach { field[it.id] = it.copy(mark = dev.lucasnlm.antimine.core.models.Mark.Flag) }
} }
fun revealAllEmptyAreas() { fun revealAllEmptyAreas() {
@ -36,7 +36,7 @@ class MinefieldHandler(
fun removeMarkAt(index: Int) { fun removeMarkAt(index: Int) {
field.getOrNull(index)?.let { field.getOrNull(index)?.let {
field[it.id] = it.copy(mark = Mark.PurposefulNone) field[it.id] = it.copy(mark = dev.lucasnlm.antimine.core.models.Mark.PurposefulNone)
} }
} }
@ -45,9 +45,9 @@ class MinefieldHandler(
if (it.isCovered) { if (it.isCovered) {
field[index] = it.copy( field[index] = it.copy(
mark = when (it.mark) { mark = when (it.mark) {
Mark.PurposefulNone, Mark.None -> Mark.Flag dev.lucasnlm.antimine.core.models.Mark.PurposefulNone, dev.lucasnlm.antimine.core.models.Mark.None -> dev.lucasnlm.antimine.core.models.Mark.Flag
Mark.Flag -> if (useQuestionMark) Mark.Question else Mark.None dev.lucasnlm.antimine.core.models.Mark.Flag -> if (useQuestionMark) dev.lucasnlm.antimine.core.models.Mark.Question else dev.lucasnlm.antimine.core.models.Mark.None
Mark.Question -> Mark.None dev.lucasnlm.antimine.core.models.Mark.Question -> dev.lucasnlm.antimine.core.models.Mark.None
} }
) )
} }
@ -59,7 +59,7 @@ class MinefieldHandler(
if (isCovered) { if (isCovered) {
field[index] = copy( field[index] = copy(
isCovered = false, isCovered = false,
mark = Mark.None, mark = dev.lucasnlm.antimine.core.models.Mark.None,
mistake = (!passive && hasMine) || (!hasMine && mark.isFlag()) mistake = (!passive && hasMine) || (!hasMine && mark.isFlag())
) )
@ -111,5 +111,5 @@ class MinefieldHandler(
} }
} }
fun result(): List<Area> = field.toList() fun result(): List<dev.lucasnlm.antimine.core.models.Area> = field.toList()
} }

View file

@ -7,6 +7,6 @@ sealed class Status {
class Over( class Over(
val time: Long = 0L, val time: Long = 0L,
val score: Score? = null, val score: dev.lucasnlm.antimine.core.models.Score? = null,
) : Status() ) : Status()
} }

View file

@ -1,6 +1,7 @@
package dev.lucasnlm.antimine.common.level.repository package dev.lucasnlm.antimine.common.level.repository
import dev.lucasnlm.antimine.common.level.models.Difficulty import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import kotlin.random.Random import kotlin.random.Random

View file

@ -1,10 +1,10 @@
package dev.lucasnlm.antimine.common.level.solver 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.core.models.Area
open class BruteForceSolver : GameSolver() { open class BruteForceSolver : GameSolver() {
override fun trySolve(minefield: MutableList<Area>): Boolean { override fun trySolve(minefield: MutableList<dev.lucasnlm.antimine.core.models.Area>): Boolean {
val minefieldHandler = MinefieldHandler(minefield, false) val minefieldHandler = MinefieldHandler(minefield, false)
do { do {

View file

@ -1,6 +1,6 @@
package dev.lucasnlm.antimine.common.level.solver package dev.lucasnlm.antimine.common.level.solver
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
abstract class GameSolver { abstract class GameSolver {
/** /**
@ -12,5 +12,5 @@ abstract class GameSolver {
* Try solve the given [minefield]. * Try solve the given [minefield].
* Returns true if it's solvable or false otherwise. * Returns true if it's solvable or false otherwise.
*/ */
abstract fun trySolve(minefield: MutableList<Area>): Boolean abstract fun trySolve(minefield: MutableList<dev.lucasnlm.antimine.core.models.Area>): Boolean
} }

View file

@ -2,23 +2,21 @@ package dev.lucasnlm.antimine.common.level.view
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Typeface
import android.util.Log import android.util.Log
import android.view.GestureDetector import android.view.GestureDetector
import android.view.KeyEvent import android.view.KeyEvent
import android.view.MotionEvent import android.view.MotionEvent
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.core.models.AreaPaintSettings
import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.preferences.models.ControlStyle import dev.lucasnlm.antimine.preferences.models.ControlStyle
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import kotlinx.coroutines.GlobalScope import dev.lucasnlm.antimine.ui.view.AreaView
import dev.lucasnlm.antimine.ui.view.createAreaPaintSettings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AreaAdapter( class AreaAdapter(
@ -26,6 +24,7 @@ class AreaAdapter(
private val viewModel: GameViewModel, private val viewModel: GameViewModel,
private val preferencesRepository: IPreferencesRepository, private val preferencesRepository: IPreferencesRepository,
dimensionRepository: IDimensionRepository, dimensionRepository: IDimensionRepository,
private val coroutineScope: CoroutineScope,
) : RecyclerView.Adapter<AreaViewHolder>() { ) : RecyclerView.Adapter<AreaViewHolder>() {
private var field = listOf<Area>() private var field = listOf<Area>()
@ -70,7 +69,7 @@ class AreaAdapter(
} }
clickEnabled -> { clickEnabled -> {
requestFocus() requestFocus()
GlobalScope.launch { coroutineScope.launch {
action(position) action(position)
} }
true true
@ -175,21 +174,5 @@ class AreaAdapter(
companion object { companion object {
val TAG = AreaAdapter::class.simpleName!! val TAG = AreaAdapter::class.simpleName!!
fun createAreaPaintSettings(context: Context, size: Float, squareRadius: Int): AreaPaintSettings {
val resources = context.resources
return AreaPaintSettings(
Paint().apply {
isAntiAlias = true
isDither = true
style = Paint.Style.FILL
textSize = 18.0f * context.resources.displayMetrics.density
typeface = Typeface.DEFAULT_BOLD
textAlign = Paint.Align.CENTER
},
RectF(0.0f, 0.0f, size, size),
resources.getDimension(R.dimen.field_radius) * squareRadius
)
}
} }
} }

View file

@ -5,12 +5,13 @@ import android.os.Bundle
import android.view.View import android.view.View
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.common.level.widget.FixedGridLayoutManager import dev.lucasnlm.antimine.common.level.widget.FixedGridLayoutManager
import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
@ -21,7 +22,7 @@ abstract class CommonLevelFragment(@LayoutRes val contentLayoutId: Int) : Fragme
protected val dimensionRepository: IDimensionRepository by inject() protected val dimensionRepository: IDimensionRepository by inject()
protected val gameViewModel by sharedViewModel<GameViewModel>() protected val gameViewModel by sharedViewModel<GameViewModel>()
protected val areaAdapter by lazy { protected val areaAdapter by lazy {
AreaAdapter(requireContext(), gameViewModel, preferencesRepository, dimensionRepository) AreaAdapter(requireContext(), gameViewModel, preferencesRepository, dimensionRepository, lifecycleScope)
} }
protected lateinit var recyclerGrid: RecyclerView protected lateinit var recyclerGrid: RecyclerView

View file

@ -7,19 +7,19 @@ import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.GameController import dev.lucasnlm.antimine.common.level.GameController
import dev.lucasnlm.antimine.common.level.database.models.FirstOpen 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.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Event import dev.lucasnlm.antimine.common.level.models.Event
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository import dev.lucasnlm.antimine.common.level.repository.IMinefieldRepository
import dev.lucasnlm.antimine.common.level.repository.ISavesRepository 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.repository.ITipRepository import dev.lucasnlm.antimine.common.level.repository.ITipRepository
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.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.core.models.Difficulty
import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.core.sound.ISoundManager import dev.lucasnlm.antimine.core.sound.ISoundManager
import dev.lucasnlm.antimine.preferences.models.ActionResponse import dev.lucasnlm.antimine.preferences.models.ActionResponse
@ -59,7 +59,7 @@ open class GameViewModel(
private var initialized = false private var initialized = false
private var currentDifficulty: Difficulty = Difficulty.Standard private var currentDifficulty: Difficulty = Difficulty.Standard
val field = MutableLiveData<List<Area>>() val field = MutableLiveData<List<dev.lucasnlm.antimine.core.models.Area>>()
val elapsedTimeSeconds = MutableLiveData<Long>() val elapsedTimeSeconds = MutableLiveData<Long>()
val mineCount = MutableLiveData<Int>() val mineCount = MutableLiveData<Int>()
val difficulty = MutableLiveData<Difficulty>() val difficulty = MutableLiveData<Difficulty>()
@ -90,7 +90,7 @@ open class GameViewModel(
eventObserver.postValue(Event.StartNewGame) eventObserver.postValue(Event.StartNewGame)
analyticsManager.sentEvent( analyticsManager.sentEvent(
Analytics.NewGame( dev.lucasnlm.antimine.core.models.Analytics.NewGame(
minefield, minefield,
newDifficulty, newDifficulty,
gameController.seed, gameController.seed,
@ -123,7 +123,7 @@ open class GameViewModel(
} }
saveId.postValue(save.uid.toLong()) saveId.postValue(save.uid.toLong())
analyticsManager.sentEvent(Analytics.ResumePreviousGame) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.ResumePreviousGame)
return setup return setup
} }
@ -144,7 +144,7 @@ open class GameViewModel(
eventObserver.postValue(Event.ResumeGame) eventObserver.postValue(Event.ResumeGame)
analyticsManager.sentEvent( analyticsManager.sentEvent(
Analytics.RetryGame( dev.lucasnlm.antimine.core.models.Analytics.RetryGame(
setup, setup,
currentDifficulty, currentDifficulty,
gameController.seed, gameController.seed,
@ -310,19 +310,19 @@ open class GameViewModel(
private fun onFeedbackAnalytics(action: ActionResponse, index: Int) { private fun onFeedbackAnalytics(action: ActionResponse, index: Int) {
when (action) { when (action) {
ActionResponse.OpenTile -> { ActionResponse.OpenTile -> {
analyticsManager.sentEvent(Analytics.OpenTile(index)) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.OpenTile(index))
} }
ActionResponse.SwitchMark -> { ActionResponse.SwitchMark -> {
analyticsManager.sentEvent(Analytics.SwitchMark(index)) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.SwitchMark(index))
} }
ActionResponse.HighlightNeighbors -> { ActionResponse.HighlightNeighbors -> {
analyticsManager.sentEvent(Analytics.HighlightNeighbors(index)) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.HighlightNeighbors(index))
} }
ActionResponse.OpenNeighbors -> { ActionResponse.OpenNeighbors -> {
analyticsManager.sentEvent(Analytics.OpenNeighbors(index)) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.OpenNeighbors(index))
} }
ActionResponse.OpenOrMark -> { ActionResponse.OpenOrMark -> {
analyticsManager.sentEvent(Analytics.OpenOrFlagTile(index)) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.OpenOrFlagTile(index))
} }
} }
} }
@ -430,7 +430,7 @@ open class GameViewModel(
suspend fun gameOver(fromResumeGame: Boolean) { suspend fun gameOver(fromResumeGame: Boolean) {
gameController.run { gameController.run {
analyticsManager.sentEvent(Analytics.GameOver(clock.time(), getScore())) analyticsManager.sentEvent(dev.lucasnlm.antimine.core.models.Analytics.GameOver(clock.time(), getScore()))
if (!fromResumeGame) { if (!fromResumeGame) {
if (preferencesRepository.useHapticFeedback()) { if (preferencesRepository.useHapticFeedback()) {
@ -473,7 +473,7 @@ open class GameViewModel(
fun victory() { fun victory() {
gameController.run { gameController.run {
analyticsManager.sentEvent( analyticsManager.sentEvent(
Analytics.Victory( dev.lucasnlm.antimine.core.models.Analytics.Victory(
clock.time(), clock.time(),
getScore(), getScore(),
currentDifficulty currentDifficulty

View file

@ -2,7 +2,8 @@ package dev.lucasnlm.antimine.core.analytics
import android.content.Context 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.models.Analytics
import dev.lucasnlm.external.IAnalyticsManager
class DebugAnalyticsManager : IAnalyticsManager { class DebugAnalyticsManager : IAnalyticsManager {
override fun setup(context: Context, properties: Map<String, String>) { override fun setup(context: Context, properties: Map<String, String>) {
@ -11,7 +12,7 @@ class DebugAnalyticsManager : IAnalyticsManager {
} }
} }
override fun sentEvent(event: Analytics) { override fun sentEvent(event: dev.lucasnlm.antimine.core.models.Analytics) {
val message = if (event.extra.isNotEmpty()) { val message = if (event.extra.isNotEmpty()) {
"Sent event: '${event.name}' with ${event.extra}" "Sent event: '${event.name}' with ${event.extra}"
} else { } else {

View file

@ -1,7 +1,8 @@
package dev.lucasnlm.antimine.core.analytics 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.models.Analytics
import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.external.IExternalAnalyticsWrapper import dev.lucasnlm.external.IExternalAnalyticsWrapper
class ProdAnalyticsManager( class ProdAnalyticsManager(
@ -11,7 +12,7 @@ class ProdAnalyticsManager(
analyticsWrapper.setup(context, properties) analyticsWrapper.setup(context, properties)
} }
override fun sentEvent(event: Analytics) { override fun sentEvent(event: dev.lucasnlm.antimine.core.models.Analytics) {
analyticsWrapper.sendEvent(event.name, event.extra) analyticsWrapper.sendEvent(event.name, event.extra)
} }
} }

View file

@ -1,8 +1,8 @@
package dev.lucasnlm.antimine.core.di package dev.lucasnlm.antimine.core.di
import android.view.ViewConfiguration import android.view.ViewConfiguration
import dev.lucasnlm.antimine.common.level.repository.DimensionRepository import dev.lucasnlm.antimine.core.repository.DimensionRepository
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.preferences.IPreferencesManager import dev.lucasnlm.antimine.preferences.IPreferencesManager
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.preferences.PreferencesManager import dev.lucasnlm.antimine.preferences.PreferencesManager

View file

@ -1,7 +1,7 @@
package dev.lucasnlm.antimine.common.level.database.converters package dev.lucasnlm.antimine.common.level.database.converters
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
import org.junit.Test import org.junit.Test
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@ -66,39 +66,39 @@ class AreaConverterTest {
private val areaList = private val areaList =
listOf( listOf(
Area( dev.lucasnlm.antimine.core.models.Area(
1, 2, 3, 5, 1, 2, 3, 5,
hasMine = false, hasMine = false,
mistake = false, mistake = false,
isCovered = true, isCovered = true,
mark = Mark.None, mark = dev.lucasnlm.antimine.core.models.Mark.None,
highlighted = true, highlighted = true,
revealed = false, revealed = false,
), ),
Area( dev.lucasnlm.antimine.core.models.Area(
2, 5, 3, 0, 2, 5, 3, 0,
hasMine = true, hasMine = true,
mistake = true, mistake = true,
isCovered = false, isCovered = false,
mark = Mark.PurposefulNone, mark = dev.lucasnlm.antimine.core.models.Mark.PurposefulNone,
highlighted = false, highlighted = false,
revealed = false, revealed = false,
), ),
Area( dev.lucasnlm.antimine.core.models.Area(
3, 1, 1, 3, 3, 1, 1, 3,
hasMine = true, hasMine = true,
mistake = false, mistake = false,
isCovered = true, isCovered = true,
mark = Mark.Flag, mark = dev.lucasnlm.antimine.core.models.Mark.Flag,
highlighted = true, highlighted = true,
revealed = false, revealed = false,
), ),
Area( dev.lucasnlm.antimine.core.models.Area(
4, 0, 0, 6, 4, 0, 0, 6,
hasMine = false, hasMine = false,
mistake = false, mistake = false,
isCovered = true, isCovered = true,
mark = Mark.Question, mark = dev.lucasnlm.antimine.core.models.Mark.Question,
highlighted = true, highlighted = true,
revealed = true, revealed = true,
) )

View file

@ -1,9 +1,9 @@
package dev.lucasnlm.antimine.common.level.logic package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.GameController import dev.lucasnlm.antimine.common.level.GameController
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import dev.lucasnlm.antimine.common.level.models.Score import dev.lucasnlm.antimine.core.models.Score
import dev.lucasnlm.antimine.preferences.models.ControlStyle import dev.lucasnlm.antimine.preferences.models.ControlStyle
import dev.lucasnlm.antimine.core.control.GameControl import dev.lucasnlm.antimine.core.control.GameControl
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -39,7 +39,7 @@ class GameControllerTest {
@Test @Test
fun testGetScore() = runBlockingTest { fun testGetScore() = runBlockingTest {
withGameController { controller -> withGameController { controller ->
assertEquals(Score(0, 20, 100), controller.getScore()) assertEquals(dev.lucasnlm.antimine.core.models.Score(0, 20, 100), controller.getScore())
repeat(20) { markedMines -> repeat(20) { markedMines ->
controller controller
@ -51,7 +51,7 @@ class GameControllerTest {
controller.fakeLongPress(it.id) controller.fakeLongPress(it.id)
} }
assertEquals(Score(markedMines, 20, 100), controller.getScore()) assertEquals(dev.lucasnlm.antimine.core.models.Score(markedMines, 20, 100), controller.getScore())
} }
} }
} }
@ -59,7 +59,7 @@ class GameControllerTest {
@Test @Test
fun testGetScoreWithQuestion() = runBlockingTest { fun testGetScoreWithQuestion() = runBlockingTest {
withGameController { controller -> withGameController { controller ->
assertEquals(Score(0, 20, 100), controller.getScore()) assertEquals(dev.lucasnlm.antimine.core.models.Score(0, 20, 100), controller.getScore())
controller.useQuestionMark(true) controller.useQuestionMark(true)
controller controller
@ -71,7 +71,7 @@ class GameControllerTest {
controller.fakeLongPress(it.id) controller.fakeLongPress(it.id)
} }
assertEquals(Score(0, 20, 100), controller.getScore()) assertEquals(dev.lucasnlm.antimine.core.models.Score(0, 20, 100), controller.getScore())
} }
} }
@ -528,7 +528,7 @@ class GameControllerTest {
} }
} }
private fun GameController.at(index: Int): Area { private fun GameController.at(index: Int): dev.lucasnlm.antimine.core.models.Area {
return this.field().first { it.id == index } return this.field().first { it.id == index }
} }

View file

@ -1,6 +1,6 @@
package dev.lucasnlm.antimine.common.level.logic package dev.lucasnlm.antimine.common.level.logic
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
@ -26,7 +26,7 @@ class MinefieldHandlerTest {
assertTrue(handler.result()[3].isCovered) assertTrue(handler.result()[3].isCovered)
handler.openAt(3, false, openNeighbors = false) handler.openAt(3, false, openNeighbors = false)
assertFalse(handler.result()[3].isCovered) assertFalse(handler.result()[3].isCovered)
assertEquals(Mark.None, handler.result()[3].mark) assertEquals(dev.lucasnlm.antimine.core.models.Mark.None, handler.result()[3].mark)
} }
} }
@ -36,7 +36,7 @@ class MinefieldHandlerTest {
assertTrue(handler.result()[3].isCovered) assertTrue(handler.result()[3].isCovered)
handler.openAt(3, false, openNeighbors = false) handler.openAt(3, false, openNeighbors = false)
assertFalse(handler.result()[3].isCovered) assertFalse(handler.result()[3].isCovered)
assertEquals(Mark.None, handler.result()[3].mark) assertEquals(dev.lucasnlm.antimine.core.models.Mark.None, handler.result()[3].mark)
} }
} }
@ -55,7 +55,7 @@ class MinefieldHandlerTest {
handler.switchMarkAt(3) handler.switchMarkAt(3)
handler.removeMarkAt(3) handler.removeMarkAt(3)
assertTrue(handler.result()[3].mark == Mark.PurposefulNone) assertTrue(handler.result()[3].mark == dev.lucasnlm.antimine.core.models.Mark.PurposefulNone)
assertTrue(handler.result()[3].mark.isNone()) assertTrue(handler.result()[3].mark.isNone())
} }
} }

View file

@ -34,6 +34,8 @@ android {
} }
dependencies { dependencies {
implementation project(':preferences')
// Kotlin // Kotlin
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10'

View file

@ -1,7 +1,5 @@
package dev.lucasnlm.antimine.core.analytics.models package dev.lucasnlm.antimine.core.models
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.common.level.models.Score
import dev.lucasnlm.antimine.preferences.models.Minefield import dev.lucasnlm.antimine.preferences.models.Minefield
sealed class Analytics( sealed class Analytics(

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.models package dev.lucasnlm.antimine.core.models
data class Area( data class Area(
val id: Int, val id: Int,

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.models package dev.lucasnlm.antimine.core.models
import android.graphics.Paint import android.graphics.Paint
import android.graphics.RectF import android.graphics.RectF

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.models package dev.lucasnlm.antimine.core.models
enum class Difficulty( enum class Difficulty(
val text: String, val text: String,

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.models package dev.lucasnlm.antimine.core.models
enum class Mark { enum class Mark {
None, None,

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.models package dev.lucasnlm.antimine.core.models
data class Score( data class Score(
val rightMines: Int, val rightMines: Int,

View file

@ -1,9 +1,9 @@
package dev.lucasnlm.antimine.common.level.repository package dev.lucasnlm.antimine.core.repository
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.content.res.TypedArray import android.content.res.TypedArray
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.core.R
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
interface IDimensionRepository { interface IDimensionRepository {

View file

@ -33,7 +33,7 @@ android {
dependencies { dependencies {
// Dependencies must be hardcoded to support F-droid // Dependencies must be hardcoded to support F-droid
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':core')
// Kotlin // Kotlin
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'

View file

@ -1,7 +1,7 @@
package dev.lucasnlm.antimine.core.analytics package dev.lucasnlm.external
import android.content.Context import android.content.Context
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.models.Analytics
interface IAnalyticsManager { interface IAnalyticsManager {
fun setup(context: Context, properties: Map<String, String>) fun setup(context: Context, properties: Map<String, String>)

1
purchases/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

76
purchases/build.gradle Normal file
View file

@ -0,0 +1,76 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
}
android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation project(':core')
implementation project(':i18n')
implementation project(':preferences')
implementation project(':ui')
implementation project(':external')
// AndroidX
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.activity:activity-ktx:1.1.0'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.0-beta01'
// Constraint
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
// Lifecycle
api 'android.arch.lifecycle:extensions:1.1.1'
implementation 'android.arch.lifecycle:viewmodel:1.1.1'
// Koin
implementation 'org.koin:koin-android:2.2.1'
implementation 'org.koin:koin-androidx-viewmodel:2.2.1'
testImplementation 'org.koin:koin-test:2.2.1'
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
// Kotlin Lib
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10'
// Unit Tests
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.mockito:mockito-core:2.24.0'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0'
testImplementation "io.mockk:mockk:1.10.3"
}

View file

21
purchases/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,24 @@
package dev.lucasnlm.antimine.purchases
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("dev.lucasnlm.antimine.purchases.test", appContext.packageName)
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.lucasnlm.antimine.purchases">
</manifest>

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.support package dev.lucasnlm.antimine.purchases
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Dialog import android.app.Dialog
@ -11,14 +11,13 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDialogFragment import androidx.appcompat.app.AppCompatDialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import dev.lucasnlm.antimine.R import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.core.analytics.models.Analytics
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.external.Ads import dev.lucasnlm.external.Ads
import dev.lucasnlm.external.IAdsManager import dev.lucasnlm.external.IAdsManager
import dev.lucasnlm.external.IBillingManager import dev.lucasnlm.external.IBillingManager
import dev.lucasnlm.external.InstantAppManager import dev.lucasnlm.external.IInstantAppManager
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
@ -27,7 +26,7 @@ class SupportAppDialogFragment : AppCompatDialogFragment() {
private val analyticsManager: IAnalyticsManager by inject() private val analyticsManager: IAnalyticsManager by inject()
private val preferenceRepository: IPreferencesRepository by inject() private val preferenceRepository: IPreferencesRepository by inject()
private val adsManager: IAdsManager by inject() private val adsManager: IAdsManager by inject()
private val instantAppManager: InstantAppManager by inject() private val instantAppManager: IInstantAppManager by inject()
private lateinit var unlockMessage: String private lateinit var unlockMessage: String
private var targetThemeId: Long = -1L private var targetThemeId: Long = -1L
@ -43,7 +42,7 @@ class SupportAppDialogFragment : AppCompatDialogFragment() {
unlockMessage = unlockMessage =
(arguments?.getString(UNLOCK_LABEL) ?: savedInstanceState?.getString(UNLOCK_LABEL)) (arguments?.getString(UNLOCK_LABEL) ?: savedInstanceState?.getString(UNLOCK_LABEL))
?: getString(R.string.support_action) ?: getString(R.string.support_action)
targetThemeId = targetThemeId =
(arguments?.getLong(TARGET_THEME_ID, -1L)) ?: -1L (arguments?.getLong(TARGET_THEME_ID, -1L)) ?: -1L
} }

View file

@ -0,0 +1,17 @@
package dev.lucasnlm.antimine.purchases
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View file

@ -7,3 +7,5 @@ include ':ui'
include ':preferences' include ':preferences'
include ':core' include ':core'
include ':control' include ':control'
include ':themes'
include ':purchases'

1
themes/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

78
themes/build.gradle Normal file
View file

@ -0,0 +1,78 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation project(':core')
implementation project(':external')
implementation project(':i18n')
implementation project(':preferences')
implementation project(':purchases')
implementation project(':ui')
// AndroidX
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.activity:activity-ktx:1.1.0'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.0-beta01'
// Constraint
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
// Lifecycle
api 'android.arch.lifecycle:extensions:1.1.1'
implementation 'android.arch.lifecycle:viewmodel:1.1.1'
// Koin
implementation 'org.koin:koin-android:2.2.1'
implementation 'org.koin:koin-androidx-viewmodel:2.2.1'
testImplementation 'org.koin:koin-test:2.2.1'
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
// Kotlin Lib
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10'
// Unit Tests
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.mockito:mockito-core:2.24.0'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0'
testImplementation "io.mockk:mockk:1.10.3"
}

View file

21
themes/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,24 @@
package dev.lucasnlm.antimine.themes
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("dev.lucasnlm.antimine.themes.test", appContext.packageName)
}
}

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="dev.lucasnlm.antimine.themes"
xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:label="@string/themes"
android:name=".ThemeActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="dev.lucasnlm.antimine.GameActivity" />
</activity>
</application>
</manifest>

View file

@ -1,21 +1,20 @@
package dev.lucasnlm.antimine.theme package dev.lucasnlm.antimine.themes
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.core.cloud.CloudSaveManager
import dev.lucasnlm.antimine.common.level.repository.IDimensionRepository import dev.lucasnlm.antimine.core.repository.IDimensionRepository
import dev.lucasnlm.antimine.common.level.view.SpaceItemDecoration
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.support.SupportAppDialogFragment import dev.lucasnlm.antimine.purchases.SupportAppDialogFragment
import dev.lucasnlm.antimine.theme.view.ThemeAdapter import dev.lucasnlm.antimine.themes.view.ThemeAdapter
import dev.lucasnlm.antimine.theme.viewmodel.ThemeEvent import dev.lucasnlm.antimine.themes.viewmodel.ThemeEvent
import dev.lucasnlm.antimine.theme.viewmodel.ThemeViewModel import dev.lucasnlm.antimine.themes.viewmodel.ThemeViewModel
import dev.lucasnlm.antimine.ui.ThematicActivity import dev.lucasnlm.antimine.ui.ThematicActivity
import dev.lucasnlm.antimine.ui.view.SpaceItemDecoration
import dev.lucasnlm.external.IBillingManager import dev.lucasnlm.external.IBillingManager
import kotlinx.android.synthetic.main.activity_game.*
import kotlinx.android.synthetic.main.activity_theme.* import kotlinx.android.synthetic.main.activity_theme.*
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.singleOrNull import kotlinx.coroutines.flow.singleOrNull

View file

@ -1,7 +1,7 @@
package dev.lucasnlm.antimine.theme.view package dev.lucasnlm.antimine.themes.view
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.core.models.Mark
object ExampleField { object ExampleField {
fun getField() = listOf( fun getField() = listOf(

View file

@ -1,18 +1,18 @@
package dev.lucasnlm.antimine.theme.view package dev.lucasnlm.antimine.themes.view
import android.graphics.Color import android.graphics.Color
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.R import dev.lucasnlm.antimine.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings import dev.lucasnlm.antimine.ui.view.createAreaPaintSettings
import dev.lucasnlm.antimine.common.level.view.AreaAdapter import dev.lucasnlm.antimine.themes.R
import dev.lucasnlm.antimine.common.level.view.AreaView
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme
import dev.lucasnlm.antimine.theme.viewmodel.ThemeEvent import dev.lucasnlm.antimine.themes.viewmodel.ThemeEvent
import dev.lucasnlm.antimine.theme.viewmodel.ThemeViewModel import dev.lucasnlm.antimine.themes.viewmodel.ThemeViewModel
import dev.lucasnlm.antimine.ui.view.AreaView
import kotlinx.android.synthetic.main.view_theme.view.* import kotlinx.android.synthetic.main.view_theme.view.*
class ThemeAdapter( class ThemeAdapter(
@ -45,7 +45,7 @@ class ThemeAdapter(
override fun onBindViewHolder(holder: ThemeViewHolder, position: Int) { override fun onBindViewHolder(holder: ThemeViewHolder, position: Int) {
val theme = themes[position] val theme = themes[position]
val paintSettings = AreaAdapter.createAreaPaintSettings( val paintSettings = createAreaPaintSettings(
holder.itemView.context, holder.itemView.context,
areaSize, areaSize,
squareRadius squareRadius

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.theme.viewmodel package dev.lucasnlm.antimine.themes.viewmodel
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.theme.viewmodel package dev.lucasnlm.antimine.themes.viewmodel
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme

View file

@ -1,12 +1,12 @@
package dev.lucasnlm.antimine.theme.viewmodel package dev.lucasnlm.antimine.themes.viewmodel
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.core.analytics.models.Analytics
import dev.lucasnlm.antimine.preferences.IPreferencesRepository import dev.lucasnlm.antimine.preferences.IPreferencesRepository
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme
import dev.lucasnlm.antimine.ui.repository.IThemeRepository import dev.lucasnlm.antimine.ui.repository.IThemeRepository
import dev.lucasnlm.antimine.ui.repository.Themes import dev.lucasnlm.antimine.ui.repository.Themes
import dev.lucasnlm.antimine.core.viewmodel.IntentViewModel import dev.lucasnlm.antimine.core.viewmodel.IntentViewModel
import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.external.IBillingManager import dev.lucasnlm.external.IBillingManager
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow

View file

@ -21,14 +21,14 @@
android:layout_gravity="center" android:layout_gravity="center"
android:columnCount="3"> android:columnCount="3">
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area0" android:id="@+id/area0"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="0.5dp" android:layout_marginBottom="0.5dp"
android:layout_marginEnd="0.5dp" /> android:layout_marginEnd="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area1" android:id="@+id/area1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -36,14 +36,14 @@
android:layout_marginStart="0.5dp" android:layout_marginStart="0.5dp"
android:layout_marginEnd="0.5dp" /> android:layout_marginEnd="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area2" android:id="@+id/area2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="0.5dp" android:layout_marginStart="0.5dp"
android:layout_marginBottom="0.5dp" /> android:layout_marginBottom="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area3" android:id="@+id/area3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -51,13 +51,13 @@
android:layout_marginBottom="0.5dp" android:layout_marginBottom="0.5dp"
android:layout_marginTop="0.5dp" /> android:layout_marginTop="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area4" android:id="@+id/area4"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="0.5dp" /> android:layout_margin="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area5" android:id="@+id/area5"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -65,14 +65,14 @@
android:layout_marginBottom="0.5dp" android:layout_marginBottom="0.5dp"
android:layout_marginTop="0.5dp"/> android:layout_marginTop="0.5dp"/>
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area6" android:id="@+id/area6"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="0.5dp" android:layout_marginTop="0.5dp"
android:layout_marginEnd="0.5dp" /> android:layout_marginEnd="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area7" android:id="@+id/area7"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -80,7 +80,7 @@
android:layout_marginStart="0.5dp" android:layout_marginStart="0.5dp"
android:layout_marginEnd="0.5dp" /> android:layout_marginEnd="0.5dp" />
<dev.lucasnlm.antimine.common.level.view.AreaView <dev.lucasnlm.antimine.ui.view.AreaView
android:id="@+id/area8" android:id="@+id/area8"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".level.LevelActivity">
<item
android:id="@+id/delete"
android:icon="@drawable/delete"
android:title="@string/delete_all"
app:showAsAction="ifRoom" />
</menu>

View file

@ -0,0 +1,17 @@
package dev.lucasnlm.antimine.themes
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View file

@ -34,6 +34,8 @@ android {
} }
dependencies { dependencies {
implementation project(':core')
implementation project(':i18n')
implementation project(':preferences') implementation project(':preferences')
// AndroidX // AndroidX
@ -41,6 +43,9 @@ dependencies {
implementation 'androidx.activity:activity-ktx:1.1.0' implementation 'androidx.activity:activity-ktx:1.1.0'
implementation 'androidx.fragment:fragment-ktx:1.2.5' implementation 'androidx.fragment:fragment-ktx:1.2.5'
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.0-beta01'
// Constraint // Constraint
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.view package dev.lucasnlm.antimine.ui.view
import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
@ -6,10 +6,10 @@ import android.graphics.Paint
import android.graphics.Rect 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.core.models.Area
import dev.lucasnlm.antimine.common.level.models.Area import dev.lucasnlm.antimine.core.models.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings import dev.lucasnlm.antimine.core.models.Mark
import dev.lucasnlm.antimine.common.level.models.Mark import dev.lucasnlm.antimine.ui.R
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme
fun Area.paintOnCanvas( fun Area.paintOnCanvas(

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.view package dev.lucasnlm.antimine.ui.view
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
@ -12,10 +12,7 @@ import android.view.MotionEvent
import android.view.View import android.view.View
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import dev.lucasnlm.antimine.common.R import dev.lucasnlm.antimine.ui.R
import dev.lucasnlm.antimine.common.level.models.Area
import dev.lucasnlm.antimine.common.level.models.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.models.Mark
import dev.lucasnlm.antimine.ui.model.AppTheme import dev.lucasnlm.antimine.ui.model.AppTheme
class AreaView : View { class AreaView : View {
@ -23,8 +20,8 @@ class AreaView : View {
private var isAmbientMode: Boolean = false private var isAmbientMode: Boolean = false
private var isLowBitAmbient: Boolean = false private var isLowBitAmbient: Boolean = false
private var area: Area? = null private var area: dev.lucasnlm.antimine.core.models.Area? = null
private lateinit var paintSettings: AreaPaintSettings private lateinit var paintSettings: dev.lucasnlm.antimine.core.models.AreaPaintSettings
private lateinit var theme: AppTheme private lateinit var theme: AppTheme
private val gestureDetector: GestureDetector by lazy { private val gestureDetector: GestureDetector by lazy {
@ -49,11 +46,11 @@ class AreaView : View {
} }
fun bindField( fun bindField(
area: Area, area: dev.lucasnlm.antimine.core.models.Area,
theme: AppTheme, theme: AppTheme,
isAmbientMode: Boolean, isAmbientMode: Boolean,
isLowBitAmbient: Boolean, isLowBitAmbient: Boolean,
paintSettings: AreaPaintSettings paintSettings: dev.lucasnlm.antimine.core.models.AreaPaintSettings
) { ) {
this.paintSettings = paintSettings this.paintSettings = paintSettings
@ -87,12 +84,12 @@ class AreaView : View {
override fun onTouchEvent(event: MotionEvent?): Boolean = override fun onTouchEvent(event: MotionEvent?): Boolean =
gestureDetector.onTouchEvent(event) || super.onTouchEvent(event) gestureDetector.onTouchEvent(event) || super.onTouchEvent(event)
private fun bindContentDescription(area: Area) { private fun bindContentDescription(area: dev.lucasnlm.antimine.core.models.Area) {
contentDescription = when { contentDescription = when {
area.mark == Mark.Flag -> { area.mark == dev.lucasnlm.antimine.core.models.Mark.Flag -> {
context.getString(if (area.mistake) R.string.desc_wrongly_marked_area else R.string.desc_marked_area) context.getString(if (area.mistake) R.string.desc_wrongly_marked_area else R.string.desc_marked_area)
} }
area.mark == Mark.Question -> context.getString(R.string.desc_marked_area) area.mark == dev.lucasnlm.antimine.core.models.Mark.Question -> context.getString(R.string.desc_marked_area)
area.isCovered -> context.getString(R.string.desc_convered_area) area.isCovered -> context.getString(R.string.desc_convered_area)
!area.isCovered && area.minesAround > 0 -> area.minesAround.toString() !area.isCovered && area.minesAround > 0 -> area.minesAround.toString()
!area.isCovered && area.hasMine -> context.getString(R.string.exploded_mine) !area.isCovered && area.hasMine -> context.getString(R.string.exploded_mine)

View file

@ -0,0 +1,24 @@
package dev.lucasnlm.antimine.ui.view
import android.content.Context
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Typeface
import dev.lucasnlm.antimine.core.R
import dev.lucasnlm.antimine.core.models.AreaPaintSettings
fun createAreaPaintSettings(context: Context, size: Float, squareRadius: Int): AreaPaintSettings {
val resources = context.resources
return AreaPaintSettings(
Paint().apply {
isAntiAlias = true
isDither = true
style = Paint.Style.FILL
textSize = 18.0f * context.resources.displayMetrics.density
typeface = Typeface.DEFAULT_BOLD
textAlign = Paint.Align.CENTER
},
RectF(0.0f, 0.0f, size, size),
resources.getDimension(R.dimen.field_radius) * squareRadius
)
}

View file

@ -1,4 +1,4 @@
package dev.lucasnlm.antimine.common.level.view package dev.lucasnlm.antimine.ui.view
import android.graphics.Rect import android.graphics.Rect
import android.view.View import android.view.View

View file

@ -2,8 +2,8 @@ package dev.lucasnlm.antimine.wear
import android.app.Application import android.app.Application
import dev.lucasnlm.antimine.common.level.di.LevelModule import dev.lucasnlm.antimine.common.level.di.LevelModule
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.models.Analytics import dev.lucasnlm.antimine.core.models.Analytics
import dev.lucasnlm.antimine.core.di.CommonModule import dev.lucasnlm.antimine.core.di.CommonModule
import dev.lucasnlm.antimine.wear.di.AppModule import dev.lucasnlm.antimine.wear.di.AppModule
import dev.lucasnlm.antimine.wear.di.ViewModelModule import dev.lucasnlm.antimine.wear.di.ViewModelModule

View file

@ -8,7 +8,7 @@ import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.models.AmbientSettings import dev.lucasnlm.antimine.common.level.models.AmbientSettings
import dev.lucasnlm.antimine.common.level.models.Event import dev.lucasnlm.antimine.common.level.models.Event
import dev.lucasnlm.antimine.common.level.view.CommonLevelFragment import dev.lucasnlm.antimine.common.level.view.CommonLevelFragment
import dev.lucasnlm.antimine.common.level.view.SpaceItemDecoration import dev.lucasnlm.antimine.ui.view.SpaceItemDecoration
import dev.lucasnlm.antimine.common.level.widget.FixedGridLayoutManager import dev.lucasnlm.antimine.common.level.widget.FixedGridLayoutManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View file

@ -2,7 +2,7 @@ package dev.lucasnlm.antimine.wear.di
import dev.lucasnlm.antimine.common.BuildConfig import dev.lucasnlm.antimine.common.BuildConfig
import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager import dev.lucasnlm.antimine.core.analytics.DebugAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager import dev.lucasnlm.external.IAnalyticsManager
import dev.lucasnlm.antimine.core.analytics.ProdAnalyticsManager import dev.lucasnlm.antimine.core.analytics.ProdAnalyticsManager
import dev.lucasnlm.external.AdsManager import dev.lucasnlm.external.AdsManager
import dev.lucasnlm.external.BillingManager import dev.lucasnlm.external.BillingManager