From 870e985af1139289d4ecfc440824885d24de5029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Thu, 29 Aug 2024 11:15:48 +0200 Subject: [PATCH] Detect/manage end game --- android/gradle.properties | 4 +-- assets/ui/game_draw.png | Bin 0 -> 170 bytes assets/ui/game_fail.png | Bin 3647 -> 170 bytes .../metadata/android/en-US/changelogs/3.txt | 1 + .../metadata/android/fr-FR/changelogs/3.txt | 1 + lib/cubit/game_cubit.dart | 15 +++++++-- lib/models/game/game.dart | 9 ++++++ lib/ui/widgets/game/game_board.dart | 4 +-- lib/ui/widgets/game/game_end.dart | 29 +++++++++++++----- pubspec.yaml | 2 +- resources/ui/images/game_draw.svg | 2 ++ resources/ui/images/game_fail.svg | 2 +- 12 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 assets/ui/game_draw.png create mode 100644 fastlane/metadata/android/en-US/changelogs/3.txt create mode 100644 fastlane/metadata/android/fr-FR/changelogs/3.txt create mode 100644 resources/ui/images/game_draw.svg diff --git a/android/gradle.properties b/android/gradle.properties index 818e87b..db7a1ee 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -app.versionName=0.0.2 -app.versionCode=2 +app.versionName=0.0.3 +app.versionCode=3 diff --git a/assets/ui/game_draw.png b/assets/ui/game_draw.png new file mode 100644 index 0000000000000000000000000000000000000000..047508dc7427561315ec1c3834f25ab888324c06 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6jLZxS3>iZITo@P_I14-?iy0W?oEaG8oERJS zYjH3zFi4iTMwA5Sr<If^7Ns(jmzV2h=4BTrCl;jY<rk&TerF@az`(#9;1lBd|NsBx zN2E_MFfcHd1o;IsI6S+N#=yWJ?djqeA|d(qpdljz1H&PO-^=58`4boz7#Iq4gbpw; TwzFS+2jY3U`njxgN@xNAJ<2Yo literal 0 HcmV?d00001 diff --git a/assets/ui/game_fail.png b/assets/ui/game_fail.png index 93f2801f9d6bb2ce508e1293cd64d6ff2e9970ec..047508dc7427561315ec1c3834f25ab888324c06 100644 GIT binary patch delta 97 zcmdllvx;$o1Scai0|P^b&_9=niZ;Fs%mF?juK)l4Uw%aT1Oo#DV@Z%-FoVOh8)*y- z4AP!1jv*3~Zx0$WGB7Y4Quw_*j+Z}yfq{XcKu72R17kb;#djc{r>mdKI;Vst0G&A; A+yDRo delta 3601 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 diff --git a/fastlane/metadata/android/en-US/changelogs/3.txt b/fastlane/metadata/android/en-US/changelogs/3.txt new file mode 100644 index 0000000..e0f6ddf --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/3.txt @@ -0,0 +1 @@ +End game management. diff --git a/fastlane/metadata/android/fr-FR/changelogs/3.txt b/fastlane/metadata/android/fr-FR/changelogs/3.txt new file mode 100644 index 0000000..8c32891 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/3.txt @@ -0,0 +1 @@ +Gestion de la fin de partie. diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart index 6f80a61..ecc7b78 100644 --- a/lib/cubit/game_cubit.dart +++ b/lib/cubit/game_cubit.dart @@ -37,7 +37,7 @@ class GameCubit extends HydratedCubit<GameState> { currentPlayer: state.currentGame.currentPlayer, scores: state.currentGame.scores, ); - game.dump(); + // game.dump(); updateState(game); } @@ -108,6 +108,12 @@ class GameCubit extends HydratedCubit<GameState> { toggleCurrentPlayer(); + if (!state.currentGame.canPlay()) { + printlog('user has no more move to play'); + state.currentGame.isFinished = true; + refresh(); + } + state.currentGame.animationInProgress = false; refresh(); } @@ -139,17 +145,20 @@ class GameCubit extends HydratedCubit<GameState> { if (state.currentGame.isOpponentHouse(lastCellIndex)) { final int seedsCount = state.currentGame.board.cells[lastCellIndex]; - printlog('found $seedsCount seed(s) on final house.'); + printlog('found $seedsCount seed(s) on final house'); if ([2, 3].contains(seedsCount)) { - printlog('ok will earn these seeds.'); + printlog('-> ok will earn these seeds'); state.currentGame.board.cells[lastCellIndex] = 0; state.currentGame.scores[state.currentGame.currentPlayer] += seedsCount; refresh(); // (recursively) check previous cells + printlog('-> dispatch to previous cell'); animateSeedsEarning(state.currentGame.getPreviousCellIndex(lastCellIndex)); + } else { + printlog('-> nothing to do'); } } } diff --git a/lib/models/game/game.dart b/lib/models/game/game.dart index df87774..74288db 100644 --- a/lib/models/game/game.dart +++ b/lib/models/game/game.dart @@ -124,6 +124,15 @@ class Game { return false; } + bool canPlay() { + for (int cellIndex = 0; cellIndex < board.cells.length; cellIndex++) { + if (isCurrentPlayerHouse(cellIndex) && isMoveAllowed(cellIndex)) { + return true; + } + } + return false; + } + void dump() { printlog(''); printlog('## Current game dump:'); diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart index 91715a8..d8273bf 100644 --- a/lib/ui/widgets/game/game_board.dart +++ b/lib/ui/widgets/game/game_board.dart @@ -39,7 +39,7 @@ class GameBoardWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ GamePlayerWidget( - active: currentGame.currentPlayer == 0, + active: !currentGame.isFinished && currentGame.currentPlayer == 0, ), Container( margin: const EdgeInsets.all(2), @@ -95,7 +95,7 @@ class GameBoardWidget extends StatelessWidget { ), ), GamePlayerWidget( - active: currentGame.currentPlayer == 1, + active: !currentGame.isFinished && currentGame.currentPlayer == 1, ), ], ); diff --git a/lib/ui/widgets/game/game_end.dart b/lib/ui/widgets/game/game_end.dart index f94c8b8..12add5f 100644 --- a/lib/ui/widgets/game/game_end.dart +++ b/lib/ui/widgets/game/game_end.dart @@ -14,10 +14,25 @@ class GameEndWidget extends StatelessWidget { builder: (BuildContext context, GameState gameState) { final Game currentGame = gameState.currentGame; - const Image decorationImage = Image( + const Image imageWinner = Image( image: AssetImage('assets/ui/game_win.png'), fit: BoxFit.fill, ); + const Image imageLoser = Image( + image: AssetImage('assets/ui/game_fail.png'), + fit: BoxFit.fill, + ); + const Image imageDraw = Image( + image: AssetImage('assets/ui/game_draw.png'), + fit: BoxFit.fill, + ); + + final Image player1 = currentGame.scores[0] == currentGame.scores[1] + ? imageDraw + : (currentGame.scores[0] > currentGame.scores[1] ? imageWinner : imageLoser); + final Image player2 = currentGame.scores[0] == currentGame.scores[1] + ? imageDraw + : (currentGame.scores[1] > currentGame.scores[0] ? imageWinner : imageLoser); return Container( margin: const EdgeInsets.all(2), @@ -27,18 +42,16 @@ class GameEndWidget extends StatelessWidget { children: [ TableRow( children: [ - const Column( - children: [decorationImage], + Column( + children: [player1], ), Column( children: [ - currentGame.animationInProgress - ? decorationImage - : const QuitGameButton() + currentGame.animationInProgress ? imageWinner : const QuitGameButton() ], ), - const Column( - children: [decorationImage], + Column( + children: [player2], ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 7d63e14..bf03338 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: Awale game publish_to: "none" -version: 0.0.2+2 +version: 0.0.3+3 environment: sdk: "^3.0.0" diff --git a/resources/ui/images/game_draw.svg b/resources/ui/images/game_draw.svg new file mode 100644 index 0000000..d988c49 --- /dev/null +++ b/resources/ui/images/game_draw.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"/> diff --git a/resources/ui/images/game_fail.svg b/resources/ui/images/game_fail.svg index 2922fd7..d988c49 100644 --- a/resources/ui/images/game_fail.svg +++ b/resources/ui/images/game_fail.svg @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x=".44662" y=".89101" width="92.772" height="91.894" ry="11.689" fill="#d11717" stroke="#fff" stroke-width=".238"/><path d="m71.624 59.304c3.5089 3.5089 3.5089 9.0561 0 12.565-1.6976 1.6976-3.9623 2.6034-6.2261 2.6034s-4.5275-0.90569-6.2261-2.6034l-12.452-12.452-12.452 12.452c-1.6976 1.6976-3.9623 2.6034-6.2261 2.6034s-4.5275-0.90569-6.2261-2.6034c-3.5089-3.5089-3.5089-9.0561 0-12.565l12.452-12.452-12.452-12.452c-3.5089-3.5089-3.5089-9.0561 0-12.565s9.0561-3.5089 12.565 0l12.452 12.452 12.452-12.452c3.5089-3.5089 9.0561-3.5089 12.565 0s3.5089 9.0561 0 12.565l-12.452 12.452z" fill="#e7e7e7" stroke-width=".20213"/></svg> +<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"/> -- GitLab