flutter: Allow to save color settings

Rename Color to PieceColor.
This commit is contained in:
Calcitem 2021-02-26 01:25:54 +08:00
parent 6939e916ff
commit 79c6ebaf7b
13 changed files with 168 additions and 133 deletions

View File

@ -17,6 +17,7 @@
*/ */
import 'package:sanmill/mill/rule.dart'; import 'package:sanmill/mill/rule.dart';
import 'package:sanmill/style/colors.dart';
import 'profile.dart'; import 'profile.dart';
@ -35,6 +36,11 @@ class Config {
static bool depthExtension = true; static bool depthExtension = true;
static bool openingBook = false; static bool openingBook = false;
// Color
static int boardLineColor = UIColors.boardLineColor.value;
static int darkBackgroundColor = UIColors.darkBackgroundColor.value;
static int boardBackgroundColor = UIColors.boardBackgroundColor.value;
// Rules // Rules
static int piecesCount = 12; static int piecesCount = 12;
static int piecesAtLeastCount = 3; static int piecesAtLeastCount = 3;
@ -65,6 +71,14 @@ class Config {
Config.depthExtension = profile['depthExtension'] ?? false; Config.depthExtension = profile['depthExtension'] ?? false;
Config.openingBook = profile['openingBook'] ?? false; Config.openingBook = profile['openingBook'] ?? false;
// Color
Config.boardLineColor =
profile['boardLineColor'] ?? UIColors.boardLineColor.value;
Config.darkBackgroundColor =
profile['darkBackgroundColor'] ?? UIColors.darkBackgroundColor.value;
Config.boardBackgroundColor =
profile['boardBackgroundColor'] ?? UIColors.boardBackgroundColor.value;
// Rules // Rules
rule.piecesCount = Config.piecesCount = profile['piecesCount'] ?? 12; rule.piecesCount = Config.piecesCount = profile['piecesCount'] ?? 12;
rule.piecesAtLeastCount = rule.piecesAtLeastCount =
@ -109,6 +123,11 @@ class Config {
profile['depthExtension'] = Config.depthExtension; profile['depthExtension'] = Config.depthExtension;
profile['openingBook'] = Config.openingBook; profile['openingBook'] = Config.openingBook;
// Color
profile['boardLineColor'] = Config.boardLineColor;
profile['darkBackgroundColor'] = Config.darkBackgroundColor;
profile['boardBackgroundColor'] = Config.boardBackgroundColor;
// Rules // Rules
profile['piecesCount'] = Config.piecesCount; profile['piecesCount'] = Config.piecesCount;
profile['piecesAtLeastCount'] = Config.piecesAtLeastCount; profile['piecesAtLeastCount'] = Config.piecesAtLeastCount;

View File

@ -125,10 +125,10 @@ class _SanmillAppState extends State<SanmillApp> {
// //
@override @override
void initState() { void initState() {
super.initState();
Chain.capture(() { Chain.capture(() {
Config.loadProfile(); Config.loadProfile();
}); });
super.initState();
} }
@override @override

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import 'package:flutter/animation.dart';
import 'package:sanmill/common/config.dart'; import 'package:sanmill/common/config.dart';
import 'package:sanmill/engine/engine.dart'; import 'package:sanmill/engine/engine.dart';
import 'package:sanmill/mill/types.dart'; import 'package:sanmill/mill/types.dart';
@ -25,7 +24,7 @@ import 'mill.dart';
import 'position.dart'; import 'position.dart';
enum PlayerType { human, AI } enum PlayerType { human, AI }
Map<String, bool> isAi = {Color.black: false, Color.white: true}; Map<String, bool> isAi = {PieceColor.black: false, PieceColor.white: true};
class Game { class Game {
static Game _instance; static Game _instance;
@ -33,16 +32,20 @@ class Game {
Position _position; Position _position;
int _focusIndex, _blurIndex; int _focusIndex, _blurIndex;
String sideToMove = Color.black; String sideToMove = PieceColor.black;
bool isColorInverted = false; bool isColorInverted = false;
Map<String, bool> isSearching = {Color.black: false, Color.white: false}; Map<String, bool> isSearching = {
PieceColor.black: false,
PieceColor.white: false
};
EngineType engineType; EngineType engineType;
bool aiIsSearching() { bool aiIsSearching() {
return isSearching[Color.black] == true || isSearching[Color.white] == true; return isSearching[PieceColor.black] == true ||
isSearching[PieceColor.white] == true;
} }
void setWhoIsAi(EngineType type) { void setWhoIsAi(EngineType type) {
@ -52,21 +55,21 @@ class Game {
case EngineType.humanVsAi: case EngineType.humanVsAi:
case EngineType.testViaLAN: case EngineType.testViaLAN:
if (Config.aiMovesFirst) { if (Config.aiMovesFirst) {
isAi[Color.black] = true; isAi[PieceColor.black] = true;
isAi[Color.white] = false; isAi[PieceColor.white] = false;
} else if (!Config.aiMovesFirst) { } else if (!Config.aiMovesFirst) {
isAi[Color.black] = false; isAi[PieceColor.black] = false;
isAi[Color.white] = true; isAi[PieceColor.white] = true;
} }
break; break;
case EngineType.humanVsHuman: case EngineType.humanVsHuman:
case EngineType.humanVsLAN: case EngineType.humanVsLAN:
isAi[Color.black] = false; isAi[PieceColor.black] = false;
isAi[Color.white] = false; isAi[PieceColor.white] = false;
break; break;
case EngineType.aiVsAi: case EngineType.aiVsAi:
isAi[Color.black] = true; isAi[PieceColor.black] = true;
isAi[Color.white] = true; isAi[PieceColor.white] = true;
break; break;
case EngineType.humanVsCloud: case EngineType.humanVsCloud:
break; break;
@ -122,7 +125,7 @@ class Game {
_focusIndex = _blurIndex = Move.invalidMove; _focusIndex = _blurIndex = Move.invalidMove;
moveHistory = [""]; moveHistory = [""];
// TODO // TODO
sideToMove = Color.black; sideToMove = PieceColor.black;
} }
select(int pos) { select(int pos) {
@ -145,7 +148,7 @@ class Game {
// //
// Can regret only our turn // Can regret only our turn
// TODO // TODO
if (_position.side != Color.white) { if (_position.side != PieceColor.white) {
//Audios.playTone('invalid.mp3'); //Audios.playTone('invalid.mp3');
return false; return false;
} }
@ -210,26 +213,26 @@ class Game {
sideToMove = position.sideToMove(); sideToMove = position.sideToMove();
total = position.score[Color.black] + total = position.score[PieceColor.black] +
position.score[Color.white] + position.score[PieceColor.white] +
position.score[Color.draw]; position.score[PieceColor.draw];
if (total == 0) { if (total == 0) {
blackWinRate = 0; blackWinRate = 0;
whiteWinRate = 0; whiteWinRate = 0;
drawRate = 0; drawRate = 0;
} else { } else {
blackWinRate = position.score[Color.black] * 100 / total; blackWinRate = position.score[PieceColor.black] * 100 / total;
whiteWinRate = position.score[Color.white] * 100 / total; whiteWinRate = position.score[PieceColor.white] * 100 / total;
drawRate = position.score[Color.draw] * 100 / total; drawRate = position.score[PieceColor.draw] * 100 / total;
} }
String stat = "Score: " + String stat = "Score: " +
position.score[Color.black].toString() + position.score[PieceColor.black].toString() +
" : " + " : " +
position.score[Color.white].toString() + position.score[PieceColor.white].toString() +
" : " + " : " +
position.score[Color.draw].toString() + position.score[PieceColor.draw].toString() +
"\ttotal: " + "\ttotal: " +
total.toString() + total.toString() +
"\n" + "\n" +

View File

@ -53,7 +53,7 @@ int makeSquare(int file, int rank) {
enum GameResult { pending, win, lose, draw, none } enum GameResult { pending, win, lose, draw, none }
class Color { class PieceColor {
static const none = '*'; static const none = '*';
static const black = '@'; static const black = '@';
static const white = 'O'; static const white = 'O';
@ -82,10 +82,10 @@ class Color {
} }
class Piece { class Piece {
static const noPiece = Color.none; static const noPiece = PieceColor.none;
static const blackStone = Color.black; static const blackStone = PieceColor.black;
static const whiteStone = Color.white; static const whiteStone = PieceColor.white;
static const ban = Color.ban; static const ban = PieceColor.ban;
static bool isEmpty(String c) => noPiece.contains(c); static bool isEmpty(String c) => noPiece.contains(c);
static bool isBlack(String c) => blackStone.contains(c); static bool isBlack(String c) => blackStone.contains(c);

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import 'package:flutter/cupertino.dart';
import 'package:sanmill/mill/mill.dart'; import 'package:sanmill/mill/mill.dart';
import 'package:sanmill/mill/recorder.dart'; import 'package:sanmill/mill/recorder.dart';
import 'package:sanmill/mill/rule.dart'; import 'package:sanmill/mill/rule.dart';
@ -47,28 +46,38 @@ class Position {
GameRecorder recorder; GameRecorder recorder;
Map<String, int> pieceInHandCount = {Color.black: -1, Color.white: -1}; Map<String, int> pieceInHandCount = {
Map<String, int> pieceOnBoardCount = {Color.black: 0, Color.white: 0}; PieceColor.black: -1,
PieceColor.white: -1
};
Map<String, int> pieceOnBoardCount = {
PieceColor.black: 0,
PieceColor.white: 0
};
int pieceToRemoveCount = 0; int pieceToRemoveCount = 0;
int gamePly = 0; int gamePly = 0;
String _sideToMove = Color.black; String _sideToMove = PieceColor.black;
int rule50 = 0; int rule50 = 0;
int pliesFromNull = 0; int pliesFromNull = 0;
StateInfo st; StateInfo st;
String us = Color.black; String us = PieceColor.black;
String them = Color.white; String them = PieceColor.white;
String winner = Color.nobody; String winner = PieceColor.nobody;
GameOverReason gameOverReason = GameOverReason.noReason; GameOverReason gameOverReason = GameOverReason.noReason;
Phase phase = Phase.none; Phase phase = Phase.none;
Act action = Act.none; Act action = Act.none;
Map<String, int> score = {Color.black: 0, Color.white: 0, Color.draw: 0}; Map<String, int> score = {
PieceColor.black: 0,
PieceColor.white: 0,
PieceColor.draw: 0
};
int currentSquare = 0; int currentSquare = 0;
int nPlayed = 0; int nPlayed = 0;
@ -137,7 +146,7 @@ class Position {
void setSideToMove(String color) { void setSideToMove(String color) {
_sideToMove = color; _sideToMove = color;
us = _sideToMove; us = _sideToMove;
them = Color.opponent(us); them = PieceColor.opponent(us);
} }
String movedPiece(int move) { String movedPiece(int move) {
@ -197,7 +206,7 @@ class Position {
} }
// Active color // Active color
ss += _sideToMove == Color.black ? "b" : "w"; ss += _sideToMove == PieceColor.black ? "b" : "w";
ss += " "; ss += " ";
@ -243,18 +252,18 @@ class Position {
ss += " "; ss += " ";
ss += pieceOnBoardCount[Color.black].toString() + ss += pieceOnBoardCount[PieceColor.black].toString() +
" " + " " +
pieceInHandCount[Color.black].toString() + pieceInHandCount[PieceColor.black].toString() +
" " + " " +
pieceOnBoardCount[Color.white].toString() + pieceOnBoardCount[PieceColor.white].toString() +
" " + " " +
pieceInHandCount[Color.white].toString() + pieceInHandCount[PieceColor.white].toString() +
" " + " " +
pieceToRemoveCount.toString() + pieceToRemoveCount.toString() +
" "; " ";
int sideIsBlack = _sideToMove == Color.black ? 1 : 0; int sideIsBlack = _sideToMove == PieceColor.black ? 1 : 0;
ss += ss +=
rule50.toString() + " " + (1 + (gamePly - sideIsBlack) ~/ 2).toString(); rule50.toString() + " " + (1 + (gamePly - sideIsBlack) ~/ 2).toString();
@ -309,9 +318,9 @@ class Position {
if (move.length > "Player".length && if (move.length > "Player".length &&
move.substring(0, "Player".length - 1) == "Player") { move.substring(0, "Player".length - 1) == "Player") {
if (move["Player".length] == '1') { if (move["Player".length] == '1') {
return resign(Color.black); return resign(PieceColor.black);
} else { } else {
return resign(Color.white); return resign(PieceColor.white);
} }
} }
@ -322,8 +331,8 @@ class Position {
if (move == "draw") { if (move == "draw") {
phase = Phase.gameOver; phase = Phase.gameOver;
winner = Color.draw; winner = PieceColor.draw;
score[Color.draw]++; score[PieceColor.draw]++;
// TODO // TODO
gameOverReason = GameOverReason.drawReasonThreefoldRepetition; gameOverReason = GameOverReason.drawReasonThreefoldRepetition;
return true; return true;
@ -372,34 +381,37 @@ class Position {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
int pieceOnBoardCountCount() { int pieceOnBoardCountCount() {
pieceOnBoardCount[Color.black] = pieceOnBoardCount[Color.white] = 0; pieceOnBoardCount[PieceColor.black] =
pieceOnBoardCount[PieceColor.white] = 0;
for (int f = 1; f < fileExNumber; f++) { for (int f = 1; f < fileExNumber; f++) {
for (int r = 0; r < rankNumber; r++) { for (int r = 0; r < rankNumber; r++) {
int s = f * rankNumber + r; int s = f * rankNumber + r;
if (board[s] == Piece.blackStone) { if (board[s] == Piece.blackStone) {
pieceOnBoardCount[Color.black]++; pieceOnBoardCount[PieceColor.black]++;
} else if (board[s] == Piece.whiteStone) { } else if (board[s] == Piece.whiteStone) {
pieceOnBoardCount[Color.black]++; pieceOnBoardCount[PieceColor.black]++;
} }
} }
} }
if (pieceOnBoardCount[Color.black] > rule.piecesCount || if (pieceOnBoardCount[PieceColor.black] > rule.piecesCount ||
pieceOnBoardCount[Color.white] > rule.piecesCount) { pieceOnBoardCount[PieceColor.white] > rule.piecesCount) {
return -1; return -1;
} }
return pieceOnBoardCount[Color.black] + pieceOnBoardCount[Color.white]; return pieceOnBoardCount[PieceColor.black] +
pieceOnBoardCount[PieceColor.white];
} }
int getNPiecesInHand() { int getNPiecesInHand() {
pieceInHandCount[Color.black] = pieceInHandCount[PieceColor.black] =
rule.piecesCount - pieceOnBoardCount[Color.black]; rule.piecesCount - pieceOnBoardCount[PieceColor.black];
pieceInHandCount[Color.white] = pieceInHandCount[PieceColor.white] =
rule.piecesCount - pieceOnBoardCount[Color.white]; rule.piecesCount - pieceOnBoardCount[PieceColor.white];
return pieceOnBoardCount[Color.black] + pieceOnBoardCount[Color.white]; return pieceOnBoardCount[PieceColor.black] +
pieceOnBoardCount[PieceColor.white];
} }
void clearBoard() { void clearBoard() {
@ -421,7 +433,7 @@ class Position {
gameOverReason = GameOverReason.noReason; gameOverReason = GameOverReason.noReason;
phase = Phase.placing; phase = Phase.placing;
setSideToMove(Color.black); setSideToMove(PieceColor.black);
action = Act.place; action = Act.place;
currentSquare = 0; currentSquare = 0;
@ -436,7 +448,7 @@ class Position {
getNPiecesInHand(); getNPiecesInHand();
pieceToRemoveCount = 0; pieceToRemoveCount = 0;
winner = Color.nobody; winner = PieceColor.nobody;
createMoveTable(); createMoveTable();
createMillTable(); createMillTable();
currentSquare = 0; currentSquare = 0;
@ -449,17 +461,18 @@ class Position {
rule50 = 0; rule50 = 0;
phase = Phase.ready; phase = Phase.ready;
setSideToMove(Color.black); setSideToMove(PieceColor.black);
action = Act.place; action = Act.place;
winner = Color.nobody; winner = PieceColor.nobody;
gameOverReason = GameOverReason.noReason; gameOverReason = GameOverReason.noReason;
clearBoard(); clearBoard();
pieceOnBoardCount[Color.black] = pieceOnBoardCount[Color.white] = 0; pieceOnBoardCount[PieceColor.black] =
pieceInHandCount[Color.black] = pieceOnBoardCount[PieceColor.white] = 0;
pieceInHandCount[Color.white] = rule.piecesCount; pieceInHandCount[PieceColor.black] =
pieceInHandCount[PieceColor.white] = rule.piecesCount;
pieceToRemoveCount = 0; pieceToRemoveCount = 0;
currentSquare = 0; currentSquare = 0;
@ -527,11 +540,11 @@ class Position {
int n = millsCount(currentSquare); int n = millsCount(currentSquare);
if (n == 0) { if (n == 0) {
assert(pieceInHandCount[Color.black] >= 0 && assert(pieceInHandCount[PieceColor.black] >= 0 &&
pieceInHandCount[Color.white] >= 0); pieceInHandCount[PieceColor.white] >= 0);
if (pieceInHandCount[Color.black] == 0 && if (pieceInHandCount[PieceColor.black] == 0 &&
pieceInHandCount[Color.white] == 0) { pieceInHandCount[PieceColor.white] == 0) {
if (checkIfGameIsOver()) { if (checkIfGameIsOver()) {
//Audios.playTone('mill.mp3'); //Audios.playTone('mill.mp3');
return true; return true;
@ -633,11 +646,11 @@ class Position {
if (pieceToRemoveCount <= 0) return false; if (pieceToRemoveCount <= 0) return false;
// if piece is not their // if piece is not their
if (!(Color.opponent(sideToMove()) == board[s])) return false; if (!(PieceColor.opponent(sideToMove()) == board[s])) return false;
if (!rule.mayRemoveFromMillsAlways && if (!rule.mayRemoveFromMillsAlways &&
potentialMillsCount(s, Color.nobody) > 0 && potentialMillsCount(s, PieceColor.nobody) > 0 &&
!isAllInMills(Color.opponent(sideToMove()))) { !isAllInMills(PieceColor.opponent(sideToMove()))) {
return false; return false;
} }
@ -670,8 +683,8 @@ class Position {
} }
if (phase == Phase.placing) { if (phase == Phase.placing) {
if (pieceInHandCount[Color.black] == 0 && if (pieceInHandCount[PieceColor.black] == 0 &&
pieceInHandCount[Color.white] == 0) { pieceInHandCount[PieceColor.white] == 0) {
phase = Phase.moving; phase = Phase.moving;
action = Act.select; action = Act.select;
@ -719,7 +732,7 @@ class Position {
return false; return false;
} }
setGameOver(Color.opponent(loser), GameOverReason.loseReasonResign); setGameOver(PieceColor.opponent(loser), GameOverReason.loseReasonResign);
return true; return true;
} }
@ -738,8 +751,8 @@ class Position {
void updateScore() { void updateScore() {
if (phase == Phase.gameOver) { if (phase == Phase.gameOver) {
if (winner == Color.draw) { if (winner == PieceColor.draw) {
score[Color.draw]++; score[PieceColor.draw]++;
return; return;
} }
@ -755,19 +768,20 @@ class Position {
} }
if (rule.maxStepsLedToDraw > 0 && rule50 > rule.maxStepsLedToDraw) { if (rule.maxStepsLedToDraw > 0 && rule50 > rule.maxStepsLedToDraw) {
winner = Color.draw; winner = PieceColor.draw;
phase = Phase.gameOver; phase = Phase.gameOver;
gameOverReason = GameOverReason.drawReasonRule50; gameOverReason = GameOverReason.drawReasonRule50;
print("Game over, draw, because of $gameOverReason."); print("Game over, draw, because of $gameOverReason.");
return true; return true;
} }
if (pieceOnBoardCount[Color.black] + pieceOnBoardCount[Color.white] >= if (pieceOnBoardCount[PieceColor.black] +
pieceOnBoardCount[PieceColor.white] >=
rankNumber * fileNumber) { rankNumber * fileNumber) {
if (rule.isBlackLoseButNotDrawWhenBoardFull) { if (rule.isBlackLoseButNotDrawWhenBoardFull) {
setGameOver(Color.white, GameOverReason.loseReasonBoardIsFull); setGameOver(PieceColor.white, GameOverReason.loseReasonBoardIsFull);
} else { } else {
setGameOver(Color.draw, GameOverReason.drawReasonBoardIsFull); setGameOver(PieceColor.draw, GameOverReason.drawReasonBoardIsFull);
} }
return true; return true;
@ -778,7 +792,7 @@ class Position {
if (phase == Phase.moving && action == Act.select && isNoWay) { if (phase == Phase.moving && action == Act.select && isNoWay) {
if (rule.isLoseButNotChangeSideWhenNoWay) { if (rule.isLoseButNotChangeSideWhenNoWay) {
setGameOver( setGameOver(
Color.opponent(sideToMove()), GameOverReason.loseReasonNoWay); PieceColor.opponent(sideToMove()), GameOverReason.loseReasonNoWay);
return true; return true;
} else { } else {
changeSideToMove(); // TODO: Need? changeSideToMove(); // TODO: Need?
@ -1342,7 +1356,7 @@ class Position {
assert(0 <= from && from < sqNumber); assert(0 <= from && from < sqNumber);
if (c == Color.nobody) { if (c == PieceColor.nobody) {
c = colorOn(to); c = colorOn(to);
} }
@ -1409,7 +1423,7 @@ class Position {
bool isAllInMills(String c) { bool isAllInMills(String c) {
for (int i = sqBegin; i < sqEnd; i++) { for (int i = sqBegin; i < sqEnd; i++) {
if (board[i] == c) { if (board[i] == c) {
if (potentialMillsCount(i, Color.nobody) == 0) { if (potentialMillsCount(i, PieceColor.nobody) == 0) {
return false; return false;
} }
} }
@ -1420,7 +1434,8 @@ class Position {
bool isAllSurrounded() { bool isAllSurrounded() {
// Full // Full
if (pieceOnBoardCount[Color.black] + pieceOnBoardCount[Color.white] >= if (pieceOnBoardCount[PieceColor.black] +
pieceOnBoardCount[PieceColor.white] >=
rankNumber * fileNumber) { rankNumber * fileNumber) {
//print("Board is full."); //print("Board is full.");
return true; return true;
@ -1489,7 +1504,8 @@ class Position {
tempPosition._grid[move.from] = tempPosition._grid[move.to]; tempPosition._grid[move.from] = tempPosition._grid[move.to];
tempPosition._grid[move.to] = move.removed; tempPosition._grid[move.to] = move.removed;
tempPosition._sideToMove = Color.opponent(tempPosition._sideToMove); tempPosition._sideToMove =
PieceColor.opponent(tempPosition._sideToMove);
}); });
recorder.lastPositionWithRemove = tempPosition.fen(); recorder.lastPositionWithRemove = tempPosition.fen();
@ -1539,7 +1555,7 @@ class Position {
void changeSideToMove() { void changeSideToMove() {
them = _sideToMove; them = _sideToMove;
_sideToMove = Color.opponent(_sideToMove); _sideToMove = PieceColor.opponent(_sideToMove);
print("$_sideToMove to move."); print("$_sideToMove to move.");
} }

View File

@ -52,7 +52,7 @@ class GameRecorder {
if (fullMove == 0) { if (fullMove == 0) {
fullMove++; fullMove++;
} else if (position.side != Color.black) { } else if (position.side != PieceColor.black) {
fullMove++; fullMove++;
} }

View File

@ -18,7 +18,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sanmill/common/config.dart'; import 'package:sanmill/common/config.dart';
import 'package:sanmill/style/colors.dart';
import 'package:sanmill/widgets/board.dart'; import 'package:sanmill/widgets/board.dart';
import 'painter_base.dart'; import 'painter_base.dart';
@ -51,7 +50,7 @@ class BoardPainter extends PiecesBasePainter {
double offsetX, double offsetX,
double offsetY, double offsetY,
}) { }) {
paint.color = UIColors.boardLineColor; paint.color = Color(Config.boardLineColor);
paint.style = PaintingStyle.stroke; paint.style = PaintingStyle.stroke;
const double borderLineWidth = 2.0; const double borderLineWidth = 2.0;

View File

@ -19,9 +19,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class UIColors { class UIColors {
// see:
// https://www.color-hex.com/color-palette/8548
// https://applecolors.com/palette/30822-chess-board-logo
static const crusoeColor = Color(0xFF165B31); static const crusoeColor = Color(0xFF165B31);
static const burlyWoodColor = Color(0xFFDEB887); static const burlyWoodColor = Color(0xFFDEB887);
static const turmericColor = Color.fromARGB(0xFF, 186, 202, 68); static const turmericColor = Color.fromARGB(0xFF, 186, 202, 68);

View File

@ -17,10 +17,10 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sanmill/common/config.dart';
import 'package:sanmill/mill/game.dart'; import 'package:sanmill/mill/game.dart';
import 'package:sanmill/painting/board_painter.dart'; import 'package:sanmill/painting/board_painter.dart';
import 'package:sanmill/painting/pieces_painter.dart'; import 'package:sanmill/painting/pieces_painter.dart';
import 'package:sanmill/style/colors.dart';
class Board extends StatelessWidget { class Board extends StatelessWidget {
// //
@ -43,7 +43,7 @@ class Board extends StatelessWidget {
height: height, height: height,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(boardBorderRadius), borderRadius: BorderRadius.circular(boardBorderRadius),
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
), ),
child: CustomPaint( child: CustomPaint(
painter: BoardPainter(width: width), painter: BoardPainter(width: width),

View File

@ -80,12 +80,12 @@ class _GamePageState extends State<GamePage> with RouteAware {
final winner = Game.shared.position.winner; final winner = Game.shared.position.winner;
Map<String, String> colorWinStrings = { Map<String, String> colorWinStrings = {
Color.black: S.of(context).blackWin, PieceColor.black: S.of(context).blackWin,
Color.white: S.of(context).whiteWin, PieceColor.white: S.of(context).whiteWin,
Color.draw: S.of(context).draw PieceColor.draw: S.of(context).draw
}; };
if (winner == Color.nobody) { if (winner == PieceColor.nobody) {
if (Game.shared.position.phase == Phase.placing) { if (Game.shared.position.phase == Phase.placing) {
changeStatus(S.of(context).tipPlace); changeStatus(S.of(context).tipPlace);
} else if (Game.shared.position.phase == Phase.moving) { } else if (Game.shared.position.phase == Phase.moving) {
@ -193,7 +193,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
setState(() {}); setState(() {});
if (position.winner == Color.nobody) { if (position.winner == PieceColor.nobody) {
engineToGo(); engineToGo();
} else { } else {
showTips(); showTips();
@ -210,16 +210,16 @@ class _GamePageState extends State<GamePage> with RouteAware {
engineToGo() async { engineToGo() async {
// TODO // TODO
while ((Config.isAutoRestart == true || while ((Config.isAutoRestart == true ||
Game.shared.position.winner == Color.nobody) && Game.shared.position.winner == PieceColor.nobody) &&
Game.shared.isAiToMove() && Game.shared.isAiToMove() &&
mounted && mounted &&
context != null) { context != null) {
if (widget.engineType == EngineType.aiVsAi) { if (widget.engineType == EngineType.aiVsAi) {
String score = Game.shared.position.score[Color.black].toString() + String score = Game.shared.position.score[PieceColor.black].toString() +
" : " + " : " +
Game.shared.position.score[Color.white].toString() + Game.shared.position.score[PieceColor.white].toString() +
" : " + " : " +
Game.shared.position.score[Color.draw].toString(); Game.shared.position.score[PieceColor.draw].toString();
changeStatus(score); changeStatus(score);
} else { } else {
@ -242,7 +242,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
} }
if (Config.isAutoRestart == true && if (Config.isAutoRestart == true &&
Game.shared.position.winner != Color.nobody) { Game.shared.position.winner != PieceColor.nobody) {
Game.shared.newGame(); Game.shared.newGame();
} }
} }
@ -323,7 +323,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
//String winnerStr = //String winnerStr =
// winner == Color.black ? S.of(context).black : S.of(context).white; // winner == Color.black ? S.of(context).black : S.of(context).white;
String loserStr = String loserStr =
winner == Color.black ? S.of(context).white : S.of(context).black; winner == PieceColor.black ? S.of(context).white : S.of(context).black;
switch (Game.shared.position.gameOverReason) { switch (Game.shared.position.gameOverReason) {
case GameOverReason.loseReasonlessThanThree: case GameOverReason.loseReasonlessThanThree:
@ -359,27 +359,27 @@ class _GamePageState extends State<GamePage> with RouteAware {
} }
GameResult getGameResult(var winner) { GameResult getGameResult(var winner) {
if (isAi[Color.black] && isAi[Color.white]) { if (isAi[PieceColor.black] && isAi[PieceColor.white]) {
return GameResult.none; return GameResult.none;
} }
if (winner == Color.black) { if (winner == PieceColor.black) {
if (isAi[Color.black]) { if (isAi[PieceColor.black]) {
return GameResult.lose; return GameResult.lose;
} else { } else {
return GameResult.win; return GameResult.win;
} }
} }
if (winner == Color.white) { if (winner == PieceColor.white) {
if (isAi[Color.white]) { if (isAi[PieceColor.white]) {
return GameResult.lose; return GameResult.lose;
} else { } else {
return GameResult.win; return GameResult.win;
} }
} }
if (winner == Color.draw) { if (winner == PieceColor.draw) {
return GameResult.draw; return GameResult.draw;
} }
@ -495,7 +495,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
width: 180, width: 180,
margin: EdgeInsets.only(bottom: 10), margin: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
borderRadius: BorderRadius.circular(2), borderRadius: BorderRadius.circular(2),
), ),
), ),
@ -540,7 +540,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
), ),
margin: EdgeInsets.symmetric(horizontal: GamePage.screenPaddingH), margin: EdgeInsets.symmetric(horizontal: GamePage.screenPaddingH),
padding: EdgeInsets.symmetric(vertical: 2), padding: EdgeInsets.symmetric(vertical: 2),
@ -629,7 +629,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
final operatorBar = createOperatorBar(); final operatorBar = createOperatorBar();
return Scaffold( return Scaffold(
backgroundColor: UIColors.darkBackgroundColor, backgroundColor: Color(Config.darkBackgroundColor),
body: Column(children: <Widget>[header, board, operatorBar]), body: Column(children: <Widget>[header, board, operatorBar]),
); );
} }

View File

@ -59,7 +59,8 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
child: const Text('Confirm'), child: const Text('Confirm'),
onPressed: () { onPressed: () {
setState(() => currentColor = pickerColor); setState(() => currentColor = pickerColor);
UIColors.boardBackgroundColor = pickerColor; Config.boardBackgroundColor = pickerColor.value;
Config.save();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
), ),
@ -91,7 +92,8 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
child: const Text('Confirm'), child: const Text('Confirm'),
onPressed: () { onPressed: () {
setState(() => currentColor = pickerColor); setState(() => currentColor = pickerColor);
UIColors.darkBackgroundColor = pickerColor; Config.darkBackgroundColor = pickerColor.value;
Config.save();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
), ),
@ -123,7 +125,8 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
child: const Text('Confirm'), child: const Text('Confirm'),
onPressed: () { onPressed: () {
setState(() => currentColor = pickerColor); setState(() => currentColor = pickerColor);
UIColors.boardLineColor = pickerColor; Config.boardLineColor = pickerColor.value;
Config.save();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
), ),
@ -303,7 +306,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
Text(S.of(context).skillLevel, style: headerStyle), Text(S.of(context).skillLevel, style: headerStyle),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
Card( Card(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
elevation: 0.5, elevation: 0.5,
margin: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 0), margin: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 0),
child: Column( child: Column(
@ -328,7 +331,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
const SizedBox(height: 16), const SizedBox(height: 16),
Text(S.of(context).sound, style: headerStyle), Text(S.of(context).sound, style: headerStyle),
Card( Card(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
margin: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -351,7 +354,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
const SizedBox(height: 16), const SizedBox(height: 16),
Text(S.of(context).whoMovesFirst, style: headerStyle), Text(S.of(context).whoMovesFirst, style: headerStyle),
Card( Card(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
margin: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -371,7 +374,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
const SizedBox(height: 16), const SizedBox(height: 16),
Text(S.of(context).misc, style: headerStyle), Text(S.of(context).misc, style: headerStyle),
Card( Card(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
margin: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -395,7 +398,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
const SizedBox(height: 16), const SizedBox(height: 16),
Text(S.of(context).color, style: headerStyle), Text(S.of(context).color, style: headerStyle),
Card( Card(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
margin: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -403,9 +406,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
title: Text(S.of(context).boardColor, style: itemStyle), title: Text(S.of(context).boardColor, style: itemStyle),
trailing: trailing:
Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
Text(UIColors.boardBackgroundColor Text(Config.boardBackgroundColor.toRadixString(16)),
.toString()
.substring(5)),
Icon(Icons.keyboard_arrow_right, Icon(Icons.keyboard_arrow_right,
color: UIColors.secondaryColor), color: UIColors.secondaryColor),
]), ]),
@ -416,8 +417,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
title: Text(S.of(context).backgroudColor, style: itemStyle), title: Text(S.of(context).backgroudColor, style: itemStyle),
trailing: trailing:
Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
Text( Text(Config.darkBackgroundColor.toRadixString(16)),
UIColors.darkBackgroundColor.toString().substring(5)),
Icon(Icons.keyboard_arrow_right, Icon(Icons.keyboard_arrow_right,
color: UIColors.secondaryColor), color: UIColors.secondaryColor),
]), ]),
@ -428,7 +428,7 @@ class _GameSettingsPageState extends State<GameSettingsPage> {
title: Text(S.of(context).lineColor, style: itemStyle), title: Text(S.of(context).lineColor, style: itemStyle),
trailing: trailing:
Row(mainAxisSize: MainAxisSize.min, children: <Widget>[ Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
Text(UIColors.boardLineColor.toString().substring(5)), Text(Config.boardLineColor.toRadixString(16)),
Icon(Icons.keyboard_arrow_right, Icon(Icons.keyboard_arrow_right,
color: UIColors.secondaryColor), color: UIColors.secondaryColor),
]), ]),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sanmill/common/config.dart';
import 'package:sanmill/style/app_theme.dart'; import 'package:sanmill/style/app_theme.dart';
import 'package:sanmill/style/colors.dart'; import 'package:sanmill/style/colors.dart';
@ -20,7 +21,7 @@ class _HelpScreenState extends State<HelpScreen> {
child: SafeArea( child: SafeArea(
top: false, top: false,
child: Scaffold( child: Scaffold(
backgroundColor: UIColors.crusoeColor, backgroundColor: Color(Config.darkBackgroundColor),
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
const SizedBox(height: 16), const SizedBox(height: 16),

View File

@ -195,7 +195,7 @@ class _RuleSettingsPageState extends State<RuleSettingsPage> {
const SizedBox(height: 16), const SizedBox(height: 16),
Text(S.of(context).rules, style: headerStyle), Text(S.of(context).rules, style: headerStyle),
Card( Card(
color: UIColors.boardBackgroundColor, color: Color(Config.boardBackgroundColor),
margin: const EdgeInsets.symmetric(vertical: 10), margin: const EdgeInsets.symmetric(vertical: 10),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[