diff --git a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt index f42db16..ca5b423 100644 --- a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt +++ b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt @@ -40,12 +40,11 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.google.accompanist.systemuicontroller.rememberSystemUiController -import com.google.android.play.core.review.ReviewManager import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import me.zobrist.tichucounter.domain.DrawerItem -import me.zobrist.tichucounter.domain.ISettingsChangeListener +import me.zobrist.tichucounter.domain.ISystemSettingsChangeListener import me.zobrist.tichucounter.domain.KeepScreenOn import me.zobrist.tichucounter.domain.Language import me.zobrist.tichucounter.domain.ReviewService @@ -70,7 +69,7 @@ import me.zobrist.tichucounter.ui.settings.SettingsViewModel import javax.inject.Inject @AndroidEntryPoint -class MainActivity : AppCompatActivity(), ISettingsChangeListener { +class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener { @Inject lateinit var settingsAdapter: SettingsAdapter @@ -192,7 +191,6 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { var topBarState by remember { mutableStateOf(TopBarState()) } var snackbarHostState by remember { mutableStateOf(SnackbarHostState()) } - val scope = rememberCoroutineScope() Scaffold( snackbarHost = { SnackbarHost(snackbarHostState) }, @@ -211,7 +209,7 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { startDestination = Route.COUNTER.name, modifier = Modifier.padding(paddings) ) { - composable(Route.COUNTER.name) { + this.composable(Route.COUNTER.name.toString()) { var expanded by remember { mutableStateOf(false) } @@ -231,15 +229,16 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener { mainViewModel.activeGameHasRounds, { expanded = true } ) { + val newGameTranslated = stringResource(R.string.new_game) DropDownMenu( - mapOf("new" to R.string.newGame), + listOf(newGameTranslated), "", expanded, ) { expanded = false it?.let { when (it) { - "new" -> mainViewModel.newGame() + newGameTranslated -> mainViewModel.newGame() } } } diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/ReviewService.kt b/app/src/main/java/me/zobrist/tichucounter/domain/ReviewService.kt index 63a1507..bc2c806 100644 --- a/app/src/main/java/me/zobrist/tichucounter/domain/ReviewService.kt +++ b/app/src/main/java/me/zobrist/tichucounter/domain/ReviewService.kt @@ -2,27 +2,17 @@ package me.zobrist.tichucounter.domain import android.app.Activity import android.content.Context -import androidx.fragment.app.FragmentActivity import androidx.preference.PreferenceManager import com.google.android.play.core.review.ReviewManagerFactory -import com.google.android.play.core.review.testing.FakeReviewManager -import dagger.hilt.android.internal.Contexts import dagger.hilt.android.qualifiers.ActivityContext -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.android.scopes.ActivityScoped -import dagger.hilt.android.scopes.FragmentScoped -import dagger.hilt.android.scopes.ViewScoped -import java.time.Duration -import java.time.Period import java.util.Date import javax.inject.Inject -import javax.inject.Singleton class ReviewService @Inject constructor(@ActivityContext private val appContext: Context) { private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext) - private val THREE_MONTHS : Long = 7776000000 + private val THREE_MONTHS: Long = 7776000000 private var requestCalled: Int get() = sharedPreferences.getInt("requestCalled", 0) @@ -43,10 +33,8 @@ class ReviewService @Inject constructor(@ActivityContext private val appContext: fun request() { requestCalled += 1 - if(requestCalled >= 3) - { - if(nextReviewedDate.time < System.currentTimeMillis()) - { + if (requestCalled >= 3) { + if (nextReviewedDate.time < System.currentTimeMillis()) { requestCalled = 0 nextReviewedDate = Date(System.currentTimeMillis() + THREE_MONTHS) diff --git a/app/src/main/java/me/zobrist/tichucounter/domain/SettingsAdapter.kt b/app/src/main/java/me/zobrist/tichucounter/domain/SettingsAdapter.kt index 6f7e074..e011f75 100644 --- a/app/src/main/java/me/zobrist/tichucounter/domain/SettingsAdapter.kt +++ b/app/src/main/java/me/zobrist/tichucounter/domain/SettingsAdapter.kt @@ -4,7 +4,6 @@ import android.content.Context import androidx.core.os.LocaleListCompat import androidx.preference.PreferenceManager import dagger.hilt.android.qualifiers.ApplicationContext -import java.util.Date import javax.inject.Inject import javax.inject.Singleton @@ -17,12 +16,19 @@ enum class Language(val value: LocaleListCompat) { enum class KeepScreenOn(val value: Boolean) { ON(true), OFF(false) } -interface ISettingsChangeListener { +typealias VictoryPoints = Int + +interface ISettingsChangeListener +interface ISystemSettingsChangeListener : ISettingsChangeListener { fun onLanguageChanged(language: Language) fun onThemeChanged(theme: Theme) fun onScreenOnChanged(keepOn: KeepScreenOn) } +interface IGameSettingsChangeListener : ISettingsChangeListener { + fun onVictoryPointsChanged(victoryPoints: Int) +} + @Singleton class SettingsAdapter @Inject constructor(@ApplicationContext private val context: Context) { @@ -37,9 +43,9 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex var keepScreenOn: KeepScreenOn private set - var reviewDialogShownDate: Date - get() = Date(sharedPreferences.getLong("reviewDialogShownDate", 0)) - set(value) = updatePreference("reviewDialogShownDate", value.time) + + var victoryPoints: Int + private set init { language = try { @@ -59,14 +65,22 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex } catch (_: java.lang.Exception) { KeepScreenOn.OFF } + + victoryPoints = sharedPreferences.getInt(VictoryPoints::class.simpleName, 1000) } fun registerOnChangeListener(listener: ISettingsChangeListener) { listenerList.add(listener) - listener.onThemeChanged(theme) - listener.onLanguageChanged(language) - listener.onScreenOnChanged(keepScreenOn) + if (listener is ISystemSettingsChangeListener) { + listener.onThemeChanged(theme) + listener.onLanguageChanged(language) + listener.onScreenOnChanged(keepScreenOn) + } + + if (listener is IGameSettingsChangeListener) { + listener.onVictoryPointsChanged(victoryPoints) + } } fun unregisterOnChangeListener(listener: ISettingsChangeListener?) { @@ -93,6 +107,12 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex notifyListeners(setting) } + fun setVictoryPoints(setting: Int) { + this.victoryPoints = setting + updatePreference(VictoryPoints::class.simpleName, setting) + notifyListeners(setting) + } + private fun updatePreference(name: String?, value: String) { val editor = sharedPreferences.edit() editor.putString(name, value) @@ -105,22 +125,33 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex editor.apply() } + private fun updatePreference(name: String?, value: Int) { + val editor = sharedPreferences.edit() + editor.putInt(name, value) + editor.apply() + } + private fun notifyListeners(language: Language) { - listenerList.forEach { + listenerList.filterIsInstance().forEach { it.onLanguageChanged(language) } } private fun notifyListeners(theme: Theme) { - listenerList.forEach { + listenerList.filterIsInstance().forEach { it.onThemeChanged(theme) } } - private fun notifyListeners(keepScreenOn: KeepScreenOn) { - listenerList.forEach { - it.onScreenOnChanged(keepScreenOn) + private fun notifyListeners(victoryPoints: VictoryPoints) { + listenerList.filterIsInstance().forEach { + it.onVictoryPointsChanged(victoryPoints) } } + private fun notifyListeners(keepScreenOn: KeepScreenOn) { + listenerList.filterIsInstance().forEach { + it.onScreenOnChanged(keepScreenOn) + } + } } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt b/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt index 022f07b..db9d2b4 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt @@ -7,10 +7,8 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.launch import me.zobrist.tichucounter.data.entity.Round -import me.zobrist.tichucounter.domain.ReviewService import me.zobrist.tichucounter.repository.GameRepository import javax.inject.Inject diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/composables/DropDownMenu.kt b/app/src/main/java/me/zobrist/tichucounter/ui/composables/DropDownMenu.kt index 12a9700..6042af4 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/composables/DropDownMenu.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/composables/DropDownMenu.kt @@ -7,25 +7,29 @@ import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource @Composable -fun DropDownMenu(map: Map, selected: T, expanded: Boolean, onSelected: (T?) -> Unit) { +fun DropDownMenu( + list: Collection, + selected: T, + expanded: Boolean, + onSelected: (T?) -> Unit +) { DropdownMenu( expanded = expanded, onDismissRequest = { onSelected(null) } ) { - map.forEach { + list.forEach { DropdownMenuItem( onClick = { - onSelected(it.key) + onSelected(it) }, trailingIcon = { - if (it.key == selected) { + if (it == selected) { Icon(Icons.Outlined.Check, null) } }, - text = { Text(stringResource(it.value)) }, + text = { Text(it.toString()) }, ) } } diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt index a338d72..1c6c68d 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt @@ -3,7 +3,13 @@ package me.zobrist.tichucounter.ui.counter import android.content.res.Configuration import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.EmojiEvents +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Icon import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -12,7 +18,9 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import me.zobrist.tichucounter.R import me.zobrist.tichucounter.data.entity.Round import me.zobrist.tichucounter.ui.AppTheme @@ -23,6 +31,18 @@ fun Counter(viewModel: ICounterViewModel = PreviewViewModel()) { var orientation by remember { mutableStateOf(Configuration.ORIENTATION_PORTRAIT) } orientation = LocalConfiguration.current.orientation + if (viewModel.showVictoryDialog) { + GameVictoryDialog( + viewModel.totalScoreA, + viewModel.totalScoreB, + viewModel.teamNameA, + viewModel.teamNameB, + { viewModel.victoryDialogExecuted(false) }) + { + viewModel.victoryDialogExecuted(true) + } + } + Surface { if (orientation == Configuration.ORIENTATION_LANDSCAPE) { Landscape(viewModel) @@ -102,6 +122,54 @@ fun CounterViewPreview() { } } +@Preview() +@Composable +fun GameVictoryDialog( + pointsA: Int = 2000, + pointsB: Int = 50, + nameA: String = "nameA", + nameB: String = "nameB", + onDismiss: () -> Unit = {}, + onNewGame: () -> Unit = {}, +) { + + val winner = if (pointsA > pointsB) { + nameA + } else { + nameB + } + + val message = if (pointsA == pointsB) { + stringResource(R.string.draw_message, winner, 100) + } else { + stringResource(R.string.victory_message) + } + + val title = if (pointsA == pointsB) { + stringResource(R.string.draw_title) + } else { + stringResource(R.string.victory_title, winner) + } + + AlertDialog( + onDismissRequest = { onDismiss() }, + dismissButton = { + TextButton({ onDismiss() }) { + Text(stringResource(R.string.continue_play)) + } + }, + confirmButton = { + TextButton({ onNewGame() }) { + Text(stringResource(R.string.new_game)) + } + }, + icon = { Icon(Icons.Outlined.EmojiEvents, null) }, + title = { Text(title) }, + text = { Text(message) } + + ) +} + internal class PreviewViewModel : ICounterViewModel { override var roundScoreList: List = listOf(Round(1, 10, 90), Round(1, 50, 50), Round(1, 70, 30)) @@ -123,6 +191,7 @@ internal class PreviewViewModel : ICounterViewModel { listOf("TeamA", "asdffd", "TeamB", "really really long Team Name that is way too long") override val teamNameSuggestionsB: List = listOf("TeamA", "asdffd", "TeamB", "really really long Team Name that is way too long") + override var showVictoryDialog: Boolean = false override fun focusLastInput() { } @@ -155,6 +224,9 @@ internal class PreviewViewModel : ICounterViewModel { override fun updateNameB(value: String) { } + override fun victoryDialogExecuted(result: Boolean) { + } + override fun updateFocusStateA(state: Boolean) { } diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterViewModel.kt b/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterViewModel.kt index f943a48..e56330f 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterViewModel.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterViewModel.kt @@ -11,7 +11,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import me.zobrist.tichucounter.data.entity.Game import me.zobrist.tichucounter.data.entity.Round +import me.zobrist.tichucounter.domain.IGameSettingsChangeListener +import me.zobrist.tichucounter.domain.SettingsAdapter import me.zobrist.tichucounter.domain.Tichu import me.zobrist.tichucounter.domain.digitCount import me.zobrist.tichucounter.domain.getTotalPoints @@ -58,16 +61,19 @@ interface ICounterViewModel : IKeyBoardViewModel { val teamNameB: String val teamNameSuggestionsA: List val teamNameSuggestionsB: List + val showVictoryDialog: Boolean fun updateNameA(value: String) fun updateNameB(value: String) + fun victoryDialogExecuted(result: Boolean) } @HiltViewModel class CounterViewModel @Inject constructor( - private val gameRepository: GameRepository + private val gameRepository: GameRepository, + private val settings: SettingsAdapter ) : - ViewModel(), ICounterViewModel { + ViewModel(), ICounterViewModel, IGameSettingsChangeListener { override var roundScoreList by mutableStateOf(emptyList()) private set @@ -113,6 +119,8 @@ class CounterViewModel @Inject constructor( override var teamNameSuggestionsB by mutableStateOf(listOf()) private set + override var showVictoryDialog by mutableStateOf(false) + private set override var activeValue: String get() { @@ -155,11 +163,14 @@ class CounterViewModel @Inject constructor( private var distinctTeamNames = listOf() + private var victoryDialogShown = false + + private var lastGame: Game? = null + init { viewModelScope.launch { gameRepository.getActiveGameFlow().collect { if (it != null) { - val score = it.getTotalPoints() roundScoreList = it.rounds @@ -171,6 +182,16 @@ class CounterViewModel @Inject constructor( buildTeamNameSuggestions() + if (it.game.uid != lastGame?.uid) { + victoryDialogShown = false + lastGame = it.game + } + + if (!victoryDialogShown) { + if (totalScoreA >= settings.victoryPoints || totalScoreB >= settings.victoryPoints) { + showVictoryDialog = true + } + } } } } @@ -182,6 +203,12 @@ class CounterViewModel @Inject constructor( buildTeamNameSuggestions() } } + + settings.registerOnChangeListener(this) + } + + override fun onCleared() { + settings.unregisterOnChangeListener(this) } override fun focusLastInput() { @@ -290,6 +317,17 @@ class CounterViewModel @Inject constructor( } } + override fun victoryDialogExecuted(result: Boolean) { + showVictoryDialog = false + victoryDialogShown = true + + if (result) { + viewModelScope.launch { + gameRepository.newGame() + } + } + } + override fun updateFocusStateA(state: Boolean) { isAFocused = state if (state) { @@ -363,4 +401,8 @@ class CounterViewModel @Inject constructor( return filtered.sorted().sortedBy { it.length }.take(10) } + + override fun onVictoryPointsChanged(victoryPoints: Int) { + victoryDialogShown = false + } } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsView.kt index bcdddf4..83ffacb 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsView.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsView.kt @@ -44,6 +44,7 @@ val themeMap = mapOf( Theme.LIGHT to R.string.light ) +val victoryPointsList = listOf(500, 1000, 1500, 2000) @Composable fun SettingsView(viewModel: SettingsViewModel) { @@ -51,9 +52,11 @@ fun SettingsView(viewModel: SettingsViewModel) { viewModel.screenOn.value, viewModel.language, viewModel.theme, + viewModel.victoryPoints, { viewModel.updateScreenOn(it) }, { viewModel.updateLanguage(it) }, - { viewModel.updateTheme(it) }) + { viewModel.updateTheme(it) }, + { viewModel.updateVictoryPoints(it) }) } @Composable @@ -61,11 +64,22 @@ fun SettingsView( valueScreenOn: Boolean = true, valueLanguage: Language = Language.ENGLISH, valueTheme: Theme = Theme.DARK, + valueVictoryPoints: Int = 1000, updateScreenOn: (KeepScreenOn) -> Unit = {}, updateLanguage: (Language) -> Unit = {}, - updateTheme: (Theme) -> Unit = {} + updateTheme: (Theme) -> Unit = {}, + updateVictoryPoints: (Int) -> Unit = {} ) { - Column { + Column( + Modifier + .padding(20.dp) + ) { + + Text( + text = stringResource(R.string.display), + style = MaterialTheme.typography.headlineMedium + ) + BooleanSetting( stringResource(R.string.keep_screen_on), valueScreenOn @@ -82,6 +96,18 @@ fun SettingsView( themeMap, valueTheme, ) { updateTheme(it) } + + Text( + text = stringResource(R.string.game), + style = MaterialTheme.typography.headlineMedium + ) + + + ListSetting( + stringResource(R.string.victory_points), + victoryPointsList, + valueVictoryPoints + ) { updateVictoryPoints(it) } } } @@ -90,7 +116,7 @@ fun BooleanSetting(name: String, value: Boolean, updateValue: (Boolean) -> Unit) Row( Modifier - .padding(20.dp) + .padding(bottom = 15.dp, top = 5.dp) .fillMaxWidth() ) { Column(Modifier.weight(5f)) { @@ -119,21 +145,32 @@ fun BooleanSetting(name: String, value: Boolean, updateValue: (Boolean) -> Unit) @Composable fun StringSetting(name: String, map: Map, selected: T, onSelected: (T) -> Unit) { + val translated = map.map { it.key to stringResource(it.value) }.toMap() + val getValue = map.map { stringResource(it.value) to it.key }.toMap() + + ListSetting( + name, + translated.values, + translated[selected] + ) { getValue[it]?.let { it1 -> onSelected(it1) } } +} + +@Composable +fun ListSetting(name: String, list: Collection, selected: T, onSelected: (T) -> Unit) { + var expanded by remember { mutableStateOf(false) } Row( Modifier .fillMaxWidth() - .padding(20.dp) + .padding(bottom = 15.dp, top = 5.dp) .clickable { expanded = true }) { Column(Modifier.weight(5f)) { Text(name, style = MaterialTheme.typography.bodyLarge, overflow = TextOverflow.Ellipsis) - map[selected]?.let { - Text( - stringResource(it), - style = MaterialTheme.typography.labelLarge - ) - } + Text( + selected.toString(), + style = MaterialTheme.typography.labelLarge + ) } Column(Modifier.weight(1f)) { @@ -142,15 +179,15 @@ fun StringSetting(name: String, map: Map, selected: T, onSelected: ( contentDescription = null, modifier = Modifier.align(End) ) - } - DropDownMenu( - map, - selected, - expanded, - ) { - expanded = false - it?.let { onSelected(it) } + DropDownMenu( + list, + selected, + expanded, + ) { + expanded = false + it?.let { onSelected(it) } + } } } } @@ -167,20 +204,3 @@ fun SettingsViewPreview() { } } } - -@Preview(name = "Light Mode") -@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true) -@Composable -fun StringSettingPreview() { - - AppTheme { - Surface { - DropDownMenu( - themeMap, - Theme.LIGHT, - true, - ) {} - } - } -} - diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsViewModel.kt b/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsViewModel.kt index b37e1bd..b3657b3 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/settings/SettingsViewModel.kt @@ -24,6 +24,9 @@ class SettingsViewModel @Inject constructor(private val settings: SettingsAdapte var screenOn by mutableStateOf(settings.keepScreenOn) private set + var victoryPoints by mutableStateOf(settings.victoryPoints) + private set + fun updateLanguage(language: Language) { settings.setLanguage(language) this.language = settings.language @@ -39,4 +42,8 @@ class SettingsViewModel @Inject constructor(private val settings: SettingsAdapte screenOn = settings.keepScreenOn } + fun updateVictoryPoints(value: Int) { + settings.setVictoryPoints(value) + victoryPoints = settings.victoryPoints + } } \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d2138cd..be1fb4e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -12,7 +12,7 @@ Einstellungen Ein Aus - Neues Spiel + Neues Spiel Verlauf löschen Wirklich den gesamten Verlauf löschen? Diese Aktion kann nicht rückgängig gemacht werden. Abbrechen @@ -29,5 +29,11 @@ RÜCKGÄNGIG Spiel aktiviert. WEITERSPIELEN - + Anzeige + Spiel + Siegespunkte + %1$s hat gewonnen + Sieht aus, als ob ihr ein neues Spiel starten solltet, um das endgültig zu klären. + Unentschieden + Herzliche Gratulation! Wie wäre es mit einer Revanche? \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3d18461..f477b30 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,7 +15,7 @@ Settings On Off - New Game + New Game Delete history You really want to delete the history? This action can\'t be undone. Cancel @@ -28,9 +28,16 @@ About Contact us Play Store - Continue + Continue game Game deleted. UNDO Game activated. CONTINUE PLAYING + Display + Game + Victory points + %1$s won the game + Looks like you should start a new game to settle this for good. + Draw + Congratulations! How about a rematch? \ No newline at end of file