Skip to content
Snippets Groups Projects
Commit ab06b5d2 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '11-add-basic-ai' into 'master'

Resolve "Add basic AI"

Closes #11

See merge request !10
parents 9ba2cdc3 2976e3fe
No related branches found
No related tags found
1 merge request!10Resolve "Add basic AI"
Pipeline #5971 passed
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=0.0.9 app.versionName=0.0.10
app.versionCode=9 app.versionCode=10
Add (naive) AI player.
Ajout d'une IA (naîve) comme joueur.
...@@ -8,12 +8,18 @@ class DefaultGameSettings { ...@@ -8,12 +8,18 @@ class DefaultGameSettings {
]; ];
// game mode: available values // game mode: available values
static const String gameModeDual = 'dual'; static const String gameModeHumanVsHuman = 'human-vs-human';
static const String gameModeHumanVsRobot = 'human-vs-robot';
static const String gameModeRobotVsHuman = 'robot-vs-human';
static const String gameModeRobotVsRobot = 'robot-vs-robot';
static const List<String> allowedGameModeValues = [ static const List<String> allowedGameModeValues = [
gameModeDual, gameModeHumanVsHuman,
gameModeHumanVsRobot,
gameModeRobotVsHuman,
gameModeRobotVsRobot,
]; ];
// items count: default value // items count: default value
static const String defaultGameModeValue = gameModeDual; static const String defaultGameModeValue = gameModeHumanVsHuman;
// available values from parameter code // available values from parameter code
static List<String> getAvailableValues(String parameterCode) { static List<String> getAvailableValues(String parameterCode) {
......
...@@ -7,6 +7,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart'; ...@@ -7,6 +7,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:awale/models/game/game.dart'; import 'package:awale/models/game/game.dart';
import 'package:awale/models/settings/settings_game.dart'; import 'package:awale/models/settings/settings_game.dart';
import 'package:awale/models/settings/settings_global.dart'; import 'package:awale/models/settings/settings_global.dart';
import 'package:awale/robot/robot_player.dart';
import 'package:awale/utils/tools.dart'; import 'package:awale/utils/tools.dart';
part 'game_state.dart'; part 'game_state.dart';
...@@ -59,6 +60,8 @@ class GameCubit extends HydratedCubit<GameState> { ...@@ -59,6 +60,8 @@ class GameCubit extends HydratedCubit<GameState> {
updateState(newGame); updateState(newGame);
refresh(); refresh();
robotPlay();
} }
void quitGame() { void quitGame() {
...@@ -80,6 +83,17 @@ class GameCubit extends HydratedCubit<GameState> { ...@@ -80,6 +83,17 @@ class GameCubit extends HydratedCubit<GameState> {
void toggleCurrentPlayer() { void toggleCurrentPlayer() {
state.currentGame.currentPlayer = 1 - state.currentGame.currentPlayer; state.currentGame.currentPlayer = 1 - state.currentGame.currentPlayer;
refresh(); refresh();
robotPlay();
}
void robotPlay() async {
if (!state.currentGame.isFinished && !state.currentGame.isCurrentPlayerHuman()) {
final int pickedCell = RobotPlayer.pickCell(state.currentGame);
await Future.delayed(const Duration(milliseconds: 500));
tapOnCell(pickedCell);
}
} }
void tapOnCell(int cellIndex) async { void tapOnCell(int cellIndex) async {
......
import 'package:awale/config/default_game_settings.dart';
import 'package:awale/models/game/board.dart'; import 'package:awale/models/game/board.dart';
import 'package:awale/models/settings/settings_game.dart'; import 'package:awale/models/settings/settings_game.dart';
import 'package:awale/models/settings/settings_global.dart'; import 'package:awale/models/settings/settings_global.dart';
...@@ -137,6 +138,25 @@ class Game { ...@@ -137,6 +138,25 @@ class Game {
return false; return false;
} }
bool isPlayerHuman(int playerIndex) {
switch (gameSettings.gameMode) {
case DefaultGameSettings.gameModeHumanVsHuman:
return true;
case DefaultGameSettings.gameModeHumanVsRobot:
return (playerIndex == 0);
case DefaultGameSettings.gameModeRobotVsHuman:
return (playerIndex == 1);
case DefaultGameSettings.gameModeRobotVsRobot:
return false;
default:
}
return true;
}
bool isCurrentPlayerHuman() {
return isPlayerHuman(currentPlayer);
}
void dump() { void dump() {
printlog(''); printlog('');
printlog('## Current game dump:'); printlog('## Current game dump:');
......
import 'package:awale/models/game/game.dart';
class RobotPlayer {
static pickCell(Game currentGame) {
List<int> allowedMoves = [];
for (int cellIndex = 0; cellIndex < currentGame.board.cells.length; cellIndex++) {
if (currentGame.isCurrentPlayerHouse(cellIndex) &&
currentGame.isMoveAllowed(cellIndex)) {
allowedMoves.add(cellIndex);
}
}
allowedMoves.shuffle();
final int pickedCellIndex = allowedMoves[0];
return pickedCellIndex;
}
}
...@@ -2,6 +2,7 @@ import 'dart:math'; ...@@ -2,6 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:awale/config/default_game_settings.dart';
import 'package:awale/models/settings/settings_game.dart'; import 'package:awale/models/settings/settings_game.dart';
import 'package:awale/models/settings/settings_global.dart'; import 'package:awale/models/settings/settings_global.dart';
import 'package:awale/utils/tools.dart'; import 'package:awale/utils/tools.dart';
...@@ -40,6 +41,9 @@ class ParameterPainter extends CustomPainter { ...@@ -40,6 +41,9 @@ class ParameterPainter extends CustomPainter {
// content // content
switch (code) { switch (code) {
case DefaultGameSettings.parameterCodeGameMode:
paintGameModeParameterItem(value, canvas, canvasSize);
break;
default: default:
printlog('Unknown parameter: $code/$value'); printlog('Unknown parameter: $code/$value');
paintUnknownParameterItem(value, canvas, canvasSize); paintUnknownParameterItem(value, canvas, canvasSize);
...@@ -87,4 +91,63 @@ class ParameterPainter extends CustomPainter { ...@@ -87,4 +91,63 @@ class ParameterPainter extends CustomPainter {
), ),
); );
} }
void paintGameModeParameterItem(
final String value,
final Canvas canvas,
final double size,
) {
String text = '';
Color baseColor = Colors.grey;
switch (value) {
case DefaultGameSettings.gameModeHumanVsHuman:
text = '🧑 🧑';
baseColor = Colors.green;
break;
case DefaultGameSettings.gameModeHumanVsRobot:
text = '🧑 🤖';
baseColor = Colors.pink;
break;
case DefaultGameSettings.gameModeRobotVsHuman:
text = '🤖 🧑';
baseColor = Colors.pink;
break;
case DefaultGameSettings.gameModeRobotVsRobot:
text = '🤖 🤖';
baseColor = Colors.brown;
break;
default:
}
final paint = Paint();
paint.strokeJoin = StrokeJoin.round;
paint.strokeWidth = 3;
paint.color = baseColor;
paint.style = PaintingStyle.fill;
canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
final textSpan = TextSpan(
text: text,
style: const TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.bold,
),
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
);
textPainter.layout();
textPainter.paint(
canvas,
Offset(
(size - textPainter.width) * 0.5,
(size - textPainter.height) * 0.5,
),
);
}
} }
...@@ -25,8 +25,9 @@ class GamePlayerWidget extends StatelessWidget { ...@@ -25,8 +25,9 @@ class GamePlayerWidget extends StatelessWidget {
final bool isCurrentPlayer = (currentGame.currentPlayer == playerIndex); final bool isCurrentPlayer = (currentGame.currentPlayer == playerIndex);
final int seedsCount = isCurrentPlayer ? currentGame.currentHand : 0; final int seedsCount = isCurrentPlayer ? currentGame.currentHand : 0;
final Color baseColor = final Color baseColor = isCurrentPlayer
isCurrentPlayer ? Colors.pink : Theme.of(context).colorScheme.surface; ? (currentGame.isPlayerHuman(playerIndex) ? Colors.pink : Colors.grey)
: Theme.of(context).colorScheme.surface;
return Container( return Container(
margin: const EdgeInsets.all(2), margin: const EdgeInsets.all(2),
......
...@@ -3,7 +3,7 @@ description: Awale game ...@@ -3,7 +3,7 @@ description: Awale game
publish_to: "none" publish_to: "none"
version: 0.0.9+9 version: 0.0.10+10
environment: environment:
sdk: "^3.0.0" sdk: "^3.0.0"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment