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
Branches 12-improve-ai 14-improve-app-metadata
Tags Release_0.0.10_10
1 merge request!10Resolve "Add basic AI"
Pipeline #5971 passed
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=0.0.9
app.versionCode=9
app.versionName=0.0.10
app.versionCode=10
Add (naive) AI player.
Ajout d'une IA (naîve) comme joueur.
......@@ -8,12 +8,18 @@ class DefaultGameSettings {
];
// 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 = [
gameModeDual,
gameModeHumanVsHuman,
gameModeHumanVsRobot,
gameModeRobotVsHuman,
gameModeRobotVsRobot,
];
// items count: default value
static const String defaultGameModeValue = gameModeDual;
static const String defaultGameModeValue = gameModeHumanVsHuman;
// available values from parameter code
static List<String> getAvailableValues(String parameterCode) {
......
......@@ -7,6 +7,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:awale/models/game/game.dart';
import 'package:awale/models/settings/settings_game.dart';
import 'package:awale/models/settings/settings_global.dart';
import 'package:awale/robot/robot_player.dart';
import 'package:awale/utils/tools.dart';
part 'game_state.dart';
......@@ -59,6 +60,8 @@ class GameCubit extends HydratedCubit<GameState> {
updateState(newGame);
refresh();
robotPlay();
}
void quitGame() {
......@@ -80,6 +83,17 @@ class GameCubit extends HydratedCubit<GameState> {
void toggleCurrentPlayer() {
state.currentGame.currentPlayer = 1 - state.currentGame.currentPlayer;
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 {
......
import 'package:awale/config/default_game_settings.dart';
import 'package:awale/models/game/board.dart';
import 'package:awale/models/settings/settings_game.dart';
import 'package:awale/models/settings/settings_global.dart';
......@@ -137,6 +138,25 @@ class Game {
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() {
printlog('');
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';
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_global.dart';
import 'package:awale/utils/tools.dart';
......@@ -40,6 +41,9 @@ class ParameterPainter extends CustomPainter {
// content
switch (code) {
case DefaultGameSettings.parameterCodeGameMode:
paintGameModeParameterItem(value, canvas, canvasSize);
break;
default:
printlog('Unknown parameter: $code/$value');
paintUnknownParameterItem(value, canvas, canvasSize);
......@@ -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 {
final bool isCurrentPlayer = (currentGame.currentPlayer == playerIndex);
final int seedsCount = isCurrentPlayer ? currentGame.currentHand : 0;
final Color baseColor =
isCurrentPlayer ? Colors.pink : Theme.of(context).colorScheme.surface;
final Color baseColor = isCurrentPlayer
? (currentGame.isPlayerHuman(playerIndex) ? Colors.pink : Colors.grey)
: Theme.of(context).colorScheme.surface;
return Container(
margin: const EdgeInsets.all(2),
......
......@@ -3,7 +3,7 @@ description: Awale game
publish_to: "none"
version: 0.0.9+9
version: 0.0.10+10
environment:
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