parent
b2e7775673
commit
37f1a3a437
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
import 'package:sanmill/mill/position.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
|
||||
class Mills {
|
||||
const Mills._();
|
||||
|
@ -110,7 +110,7 @@ class Mills {
|
|||
/* 39 */ [0, 0, 0, 0],
|
||||
];
|
||||
|
||||
if (rule.hasDiagonalLines) {
|
||||
if (LocalDatabaseService.rules.hasDiagonalLines) {
|
||||
Position.adjacentSquares = adjacentSquares_diagonal;
|
||||
} else {
|
||||
Position.adjacentSquares = adjacentSquares;
|
||||
|
@ -524,7 +524,7 @@ class Mills {
|
|||
]
|
||||
];
|
||||
|
||||
if (rule.hasDiagonalLines) {
|
||||
if (LocalDatabaseService.rules.hasDiagonalLines) {
|
||||
Position.millTable = millTable_diagonal;
|
||||
} else {
|
||||
Position.millTable = millTable;
|
||||
|
|
|
@ -20,7 +20,6 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:sanmill/mill/game.dart';
|
||||
import 'package:sanmill/mill/mills.dart';
|
||||
import 'package:sanmill/mill/recorder.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/mill/types.dart';
|
||||
import 'package:sanmill/mill/zobrist.dart';
|
||||
import 'package:sanmill/services/audios.dart';
|
||||
|
@ -155,7 +154,7 @@ class Position {
|
|||
|
||||
phase = Phase.placing;
|
||||
|
||||
setPosition(rule); // TODO
|
||||
setPosition(); // TODO
|
||||
|
||||
// TODO
|
||||
recorder = GameRecorder(lastPositionWithRemove: fen());
|
||||
|
@ -283,13 +282,16 @@ class Position {
|
|||
score[PieceColor.draw] = score[PieceColor.draw]! + 1;
|
||||
|
||||
// TODO: WAR to judge rule50
|
||||
if (rule.nMoveRule > 0 && posKeyHistory.length >= rule.nMoveRule - 1) {
|
||||
if (LocalDatabaseService.rules.nMoveRule > 0 &&
|
||||
posKeyHistory.length >= LocalDatabaseService.rules.nMoveRule - 1) {
|
||||
gameOverReason = GameOverReason.drawReasonRule50;
|
||||
} else if (rule.endgameNMoveRule < rule.nMoveRule &&
|
||||
} else if (LocalDatabaseService.rules.endgameNMoveRule <
|
||||
LocalDatabaseService.rules.nMoveRule &&
|
||||
isThreeEndgame &&
|
||||
posKeyHistory.length >= rule.endgameNMoveRule - 1) {
|
||||
posKeyHistory.length >=
|
||||
LocalDatabaseService.rules.endgameNMoveRule - 1) {
|
||||
gameOverReason = GameOverReason.drawReasonEndgameRule50;
|
||||
} else if (rule.threefoldRepetitionRule) {
|
||||
} else if (LocalDatabaseService.rules.threefoldRepetitionRule) {
|
||||
gameOverReason =
|
||||
GameOverReason.drawReasonThreefoldRepetition; // TODO: Sure?
|
||||
} else {
|
||||
|
@ -345,7 +347,8 @@ class Position {
|
|||
(posKeyHistory.isNotEmpty &&
|
||||
st.key != posKeyHistory[posKeyHistory.length - 1])) {
|
||||
posKeyHistory.add(st.key);
|
||||
if (rule.threefoldRepetitionRule && hasGameCycle()) {
|
||||
if (LocalDatabaseService.rules.threefoldRepetitionRule &&
|
||||
hasGameCycle()) {
|
||||
setGameOver(
|
||||
PieceColor.draw,
|
||||
GameOverReason.drawReasonThreefoldRepetition,
|
||||
|
@ -422,8 +425,8 @@ class Position {
|
|||
|
||||
pieceOnBoardCount[PieceColor.white] =
|
||||
pieceOnBoardCount[PieceColor.black] = 0;
|
||||
pieceInHandCount[PieceColor.white] =
|
||||
pieceInHandCount[PieceColor.black] = rule.piecesCount;
|
||||
pieceInHandCount[PieceColor.white] = pieceInHandCount[PieceColor.black] =
|
||||
LocalDatabaseService.rules.piecesCount;
|
||||
pieceToRemoveCount = 0;
|
||||
|
||||
// TODO:
|
||||
|
@ -508,11 +511,11 @@ class Position {
|
|||
phase = Phase.moving;
|
||||
action = Act.select;
|
||||
|
||||
if (rule.hasBannedLocations) {
|
||||
if (LocalDatabaseService.rules.hasBannedLocations) {
|
||||
removeBanStones();
|
||||
}
|
||||
|
||||
if (!rule.isDefenderMoveFirst) {
|
||||
if (!LocalDatabaseService.rules.isDefenderMoveFirst) {
|
||||
changeSideToMove();
|
||||
}
|
||||
|
||||
|
@ -525,10 +528,12 @@ class Position {
|
|||
gameInstance.focusIndex = squareToIndex[s];
|
||||
await Audios.playTone(Sound.place);
|
||||
} else {
|
||||
pieceToRemoveCount = rule.mayRemoveMultiple ? n : 1;
|
||||
pieceToRemoveCount =
|
||||
LocalDatabaseService.rules.mayRemoveMultiple ? n : 1;
|
||||
updateKeyMisc();
|
||||
|
||||
if (rule.mayOnlyRemoveUnplacedPieceInPlacingPhase &&
|
||||
if (LocalDatabaseService
|
||||
.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase &&
|
||||
pieceInHandCount[them] != null) {
|
||||
pieceInHandCount[them] =
|
||||
pieceInHandCount[them]! - 1; // Or pieceToRemoveCount?
|
||||
|
@ -546,7 +551,7 @@ class Position {
|
|||
phase = Phase.moving;
|
||||
action = Act.select;
|
||||
|
||||
if (rule.isDefenderMoveFirst) {
|
||||
if (LocalDatabaseService.rules.isDefenderMoveFirst) {
|
||||
changeSideToMove();
|
||||
}
|
||||
|
||||
|
@ -567,7 +572,9 @@ class Position {
|
|||
}
|
||||
|
||||
// if illegal
|
||||
if (pieceOnBoardCount[sideToMove]! > rule.flyPieceCount || !rule.mayFly) {
|
||||
if (pieceOnBoardCount[sideToMove]! >
|
||||
LocalDatabaseService.rules.flyPieceCount ||
|
||||
!LocalDatabaseService.rules.mayFly) {
|
||||
int md;
|
||||
|
||||
for (md = 0; md < moveDirectionNumber; md++) {
|
||||
|
@ -610,7 +617,8 @@ class Position {
|
|||
await Audios.playTone(Sound.place);
|
||||
}
|
||||
} else {
|
||||
pieceToRemoveCount = rule.mayRemoveMultiple ? n : 1;
|
||||
pieceToRemoveCount =
|
||||
LocalDatabaseService.rules.mayRemoveMultiple ? n : 1;
|
||||
updateKeyMisc();
|
||||
action = Act.remove;
|
||||
gameInstance.focusIndex = squareToIndex[s];
|
||||
|
@ -633,7 +641,7 @@ class Position {
|
|||
// if piece is not their
|
||||
if (!(PieceColor.opponent(sideToMove) == board[s])) return -2;
|
||||
|
||||
if (!rule.mayRemoveFromMillsAlways &&
|
||||
if (!LocalDatabaseService.rules.mayRemoveFromMillsAlways &&
|
||||
potentialMillsCount(s, PieceColor.nobody) > 0 &&
|
||||
!isAllInMills(PieceColor.opponent(sideToMove))) {
|
||||
return -3;
|
||||
|
@ -643,7 +651,8 @@ class Position {
|
|||
|
||||
await Audios.playTone(Sound.remove);
|
||||
|
||||
if (rule.hasBannedLocations && phase == Phase.placing) {
|
||||
if (LocalDatabaseService.rules.hasBannedLocations &&
|
||||
phase == Phase.placing) {
|
||||
// Remove and put ban
|
||||
board[s] = _grid[squareToIndex[s]!] = Piece.ban;
|
||||
updateKey(s);
|
||||
|
@ -660,7 +669,7 @@ class Position {
|
|||
}
|
||||
|
||||
if (pieceOnBoardCount[them]! + pieceInHandCount[them]! <
|
||||
rule.piecesAtLeastCount) {
|
||||
LocalDatabaseService.rules.piecesAtLeastCount) {
|
||||
setGameOver(sideToMove, GameOverReason.loseReasonlessThanThree);
|
||||
return 0;
|
||||
}
|
||||
|
@ -680,11 +689,11 @@ class Position {
|
|||
phase = Phase.moving;
|
||||
action = Act.select;
|
||||
|
||||
if (rule.hasBannedLocations) {
|
||||
if (LocalDatabaseService.rules.hasBannedLocations) {
|
||||
removeBanStones();
|
||||
}
|
||||
|
||||
if (rule.isDefenderMoveFirst) {
|
||||
if (LocalDatabaseService.rules.isDefenderMoveFirst) {
|
||||
isGameOver();
|
||||
return 0;
|
||||
}
|
||||
|
@ -764,14 +773,16 @@ class Position {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (rule.nMoveRule > 0 && posKeyHistory.length >= rule.nMoveRule) {
|
||||
if (LocalDatabaseService.rules.nMoveRule > 0 &&
|
||||
posKeyHistory.length >= LocalDatabaseService.rules.nMoveRule) {
|
||||
setGameOver(PieceColor.draw, GameOverReason.drawReasonRule50);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rule.endgameNMoveRule < rule.nMoveRule &&
|
||||
if (LocalDatabaseService.rules.endgameNMoveRule <
|
||||
LocalDatabaseService.rules.nMoveRule &&
|
||||
isThreeEndgame &&
|
||||
posKeyHistory.length >= rule.endgameNMoveRule) {
|
||||
posKeyHistory.length >= LocalDatabaseService.rules.endgameNMoveRule) {
|
||||
setGameOver(PieceColor.draw, GameOverReason.drawReasonEndgameRule50);
|
||||
return true;
|
||||
}
|
||||
|
@ -779,7 +790,7 @@ class Position {
|
|||
if (pieceOnBoardCount[PieceColor.white]! +
|
||||
pieceOnBoardCount[PieceColor.black]! >=
|
||||
rankNumber * fileNumber) {
|
||||
if (rule.isWhiteLoseButNotDrawWhenBoardFull) {
|
||||
if (LocalDatabaseService.rules.isWhiteLoseButNotDrawWhenBoardFull) {
|
||||
setGameOver(PieceColor.black, GameOverReason.loseReasonBoardIsFull);
|
||||
} else {
|
||||
setGameOver(PieceColor.draw, GameOverReason.drawReasonBoardIsFull);
|
||||
|
@ -789,7 +800,7 @@ class Position {
|
|||
}
|
||||
|
||||
if (phase == Phase.moving && action == Act.select && isAllSurrounded()) {
|
||||
if (rule.isLoseButNotChangeSideWhenNoWay) {
|
||||
if (LocalDatabaseService.rules.isLoseButNotChangeSideWhenNoWay) {
|
||||
setGameOver(
|
||||
PieceColor.opponent(sideToMove),
|
||||
GameOverReason.loseReasonNoWay,
|
||||
|
@ -805,7 +816,7 @@ class Position {
|
|||
}
|
||||
|
||||
void removeBanStones() {
|
||||
assert(rule.hasBannedLocations);
|
||||
assert(LocalDatabaseService.rules.hasBannedLocations);
|
||||
|
||||
int s = 0;
|
||||
|
||||
|
@ -961,7 +972,9 @@ class Position {
|
|||
}
|
||||
|
||||
// Can fly
|
||||
if (pieceOnBoardCount[sideToMove]! <= rule.flyPieceCount && rule.mayFly) {
|
||||
if (pieceOnBoardCount[sideToMove]! <=
|
||||
LocalDatabaseService.rules.flyPieceCount &&
|
||||
LocalDatabaseService.rules.mayFly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -982,7 +995,7 @@ class Position {
|
|||
}
|
||||
|
||||
bool isStarSquare(int s) {
|
||||
if (rule.hasDiagonalLines == true) {
|
||||
if (LocalDatabaseService.rules.hasDiagonalLines == true) {
|
||||
return s == 17 || s == 19 || s == 21 || s == 23;
|
||||
}
|
||||
|
||||
|
@ -993,9 +1006,11 @@ class Position {
|
|||
|
||||
int get nPiecesInHand {
|
||||
pieceInHandCount[PieceColor.white] =
|
||||
rule.piecesCount - pieceOnBoardCount[PieceColor.white]!;
|
||||
LocalDatabaseService.rules.piecesCount -
|
||||
pieceOnBoardCount[PieceColor.white]!;
|
||||
pieceInHandCount[PieceColor.black] =
|
||||
rule.piecesCount - pieceOnBoardCount[PieceColor.black]!;
|
||||
LocalDatabaseService.rules.piecesCount -
|
||||
pieceOnBoardCount[PieceColor.black]!;
|
||||
|
||||
return pieceOnBoardCount[PieceColor.white]! +
|
||||
pieceOnBoardCount[PieceColor.black]!;
|
||||
|
@ -1011,7 +1026,7 @@ class Position {
|
|||
}
|
||||
}
|
||||
|
||||
int setPosition(Rule newRule) {
|
||||
int setPosition() {
|
||||
result = GameResult.pending;
|
||||
|
||||
gamePly = 0;
|
||||
|
@ -1060,8 +1075,10 @@ class Position {
|
|||
}
|
||||
}
|
||||
|
||||
if (pieceOnBoardCount[PieceColor.white]! > rule.piecesCount ||
|
||||
pieceOnBoardCount[PieceColor.black]! > rule.piecesCount) {
|
||||
if (pieceOnBoardCount[PieceColor.white]! >
|
||||
LocalDatabaseService.rules.piecesCount ||
|
||||
pieceOnBoardCount[PieceColor.black]! >
|
||||
LocalDatabaseService.rules.piecesCount) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
This file is part of Sanmill.
|
||||
Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file)
|
||||
|
||||
Sanmill is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Sanmill is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:sanmill/services/language_info.dart';
|
||||
|
||||
// TODO: [Leptopoda] deprecate this thingy. No reason to keep it
|
||||
class Rule {
|
||||
String name = "Default Rule";
|
||||
String description = "";
|
||||
int piecesCount = specialCountryAndRegion == "Iran" ? 12 : 9;
|
||||
int flyPieceCount = 3;
|
||||
int piecesAtLeastCount = 3;
|
||||
bool hasDiagonalLines = specialCountryAndRegion == "Iran";
|
||||
bool hasBannedLocations = false;
|
||||
bool mayMoveInPlacingPhase = false;
|
||||
bool isDefenderMoveFirst = false;
|
||||
bool mayRemoveMultiple = false;
|
||||
bool mayRemoveFromMillsAlways = false;
|
||||
bool mayOnlyRemoveUnplacedPieceInPlacingPhase = false;
|
||||
bool isWhiteLoseButNotDrawWhenBoardFull = true;
|
||||
bool isLoseButNotChangeSideWhenNoWay = true;
|
||||
bool mayFly = true;
|
||||
int nMoveRule = 100;
|
||||
int endgameNMoveRule = 100;
|
||||
bool threefoldRepetitionRule = true;
|
||||
}
|
||||
|
||||
Rule rule = Rule();
|
||||
|
||||
const ruleNumber = 4;
|
|
@ -26,7 +26,6 @@ import 'package:flutter/services.dart';
|
|||
import 'package:sanmill/generated/intl/l10n.dart';
|
||||
import 'package:sanmill/mill/game.dart';
|
||||
import 'package:sanmill/mill/position.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/mill/types.dart';
|
||||
import 'package:sanmill/models/preferences.dart';
|
||||
import 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
|
@ -234,13 +233,15 @@ class _GamePageState extends State<GamePage>
|
|||
} else {
|
||||
//Audios.playTone(Audios.place);
|
||||
if (gameInstance.engineType == EngineType.humanVsAi && mounted) {
|
||||
if (rule.mayOnlyRemoveUnplacedPieceInPlacingPhase) {
|
||||
if (LocalDatabaseService
|
||||
.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase) {
|
||||
showTip(S.of(context).continueToMakeMove);
|
||||
} else {
|
||||
showTip(S.of(context).tipPlaced);
|
||||
}
|
||||
} else if (mounted) {
|
||||
if (rule.mayOnlyRemoveUnplacedPieceInPlacingPhase) {
|
||||
if (LocalDatabaseService
|
||||
.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase) {
|
||||
showTip(
|
||||
S.of(context).tipPlaced,
|
||||
); // TODO: HumanVsHuman - Change tip
|
||||
|
@ -291,7 +292,7 @@ class _GamePageState extends State<GamePage>
|
|||
|
||||
final us = gameInstance.sideToMove;
|
||||
if (position.phase == Phase.moving &&
|
||||
rule.mayFly &&
|
||||
LocalDatabaseService.rules.mayFly &&
|
||||
(gameInstance.position.pieceOnBoardCount[us] ==
|
||||
LocalDatabaseService.rules.flyPieceCount ||
|
||||
gameInstance.position.pieceOnBoardCount[us] == 3)) {
|
||||
|
@ -454,7 +455,8 @@ class _GamePageState extends State<GamePage>
|
|||
(posKeyHistory.isNotEmpty &&
|
||||
position.st.key != posKeyHistory[posKeyHistory.length - 1])) {
|
||||
posKeyHistory.add(position.st.key);
|
||||
if (rule.threefoldRepetitionRule && position.hasGameCycle()) {
|
||||
if (LocalDatabaseService.rules.threefoldRepetitionRule &&
|
||||
position.hasGameCycle()) {
|
||||
position.setGameOver(
|
||||
PieceColor.draw,
|
||||
GameOverReason.drawReasonThreefoldRepetition,
|
||||
|
|
|
@ -24,7 +24,6 @@ import 'package:flutter/foundation.dart'
|
|||
import 'package:flutter/material.dart' show Color, Locale;
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/models/color.dart';
|
||||
import 'package:sanmill/models/display.dart';
|
||||
import 'package:sanmill/models/preferences.dart';
|
||||
|
@ -82,7 +81,6 @@ class LocalDatabaseService {
|
|||
await _initDisplay();
|
||||
await _initPreferences();
|
||||
await _initRules();
|
||||
DatabaseV1.initRules();
|
||||
await _DatabaseMigrator.migrate();
|
||||
}
|
||||
|
||||
|
@ -161,10 +159,7 @@ class LocalDatabaseService {
|
|||
_rulesBox.listenable(keys: [rulesKey]);
|
||||
|
||||
/// saves the given [rules] to the settings Box
|
||||
static set rules(Rules rules) {
|
||||
_rulesBox.put(rulesKey, rules);
|
||||
DatabaseV1.initRules();
|
||||
}
|
||||
static set rules(Rules rules) => _rulesBox.put(rulesKey, rules);
|
||||
|
||||
/// gets the given [Rules] from the settings Box
|
||||
static Rules get rules => _rulesBox.get(rulesKey) ?? Rules();
|
||||
|
|
|
@ -74,11 +74,11 @@ class _DatabaseMigrator {
|
|||
|
||||
/// Migration 0 - KV to Hive
|
||||
///
|
||||
/// - Calls the [DatabaseV1.migrateDB] to migrate from KV storage.
|
||||
/// - Calls the [_DatabaseV1.migrateDB] to migrate from KV storage.
|
||||
static Future<void> _migrateToHive() async {
|
||||
assert(_currentVersion <= 0);
|
||||
|
||||
await DatabaseV1.migrateDB();
|
||||
await _DatabaseV1.migrateDB();
|
||||
debugPrint("$_tag migrated from KV");
|
||||
}
|
||||
|
||||
|
@ -111,8 +111,8 @@ class _DatabaseMigrator {
|
|||
/// Database KV Migrator
|
||||
///
|
||||
/// This class provides helper methods to migrate from the old KV storage to the new hiveDB.
|
||||
class DatabaseV1 {
|
||||
const DatabaseV1._();
|
||||
class _DatabaseV1 {
|
||||
const _DatabaseV1._();
|
||||
|
||||
static const _tag = "[KV store Migration]";
|
||||
|
||||
|
@ -162,29 +162,4 @@ class DatabaseV1 {
|
|||
debugPrint("$_tag $_file does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
/// initializes the [Rules] object with the contents of [LocalDatabaseService.rules]
|
||||
static void initRules() {
|
||||
final _rules = LocalDatabaseService.rules;
|
||||
// Rules
|
||||
rule.piecesCount = _rules.piecesCount;
|
||||
rule.flyPieceCount = _rules.flyPieceCount;
|
||||
rule.piecesAtLeastCount = _rules.piecesAtLeastCount;
|
||||
rule.hasDiagonalLines = _rules.hasDiagonalLines;
|
||||
rule.hasBannedLocations = _rules.hasBannedLocations;
|
||||
rule.mayMoveInPlacingPhase = _rules.mayMoveInPlacingPhase;
|
||||
rule.isDefenderMoveFirst = _rules.isDefenderMoveFirst;
|
||||
rule.mayRemoveMultiple = _rules.mayRemoveMultiple;
|
||||
rule.mayRemoveFromMillsAlways = _rules.mayRemoveFromMillsAlways;
|
||||
rule.mayOnlyRemoveUnplacedPieceInPlacingPhase =
|
||||
_rules.mayOnlyRemoveUnplacedPieceInPlacingPhase;
|
||||
rule.isWhiteLoseButNotDrawWhenBoardFull =
|
||||
_rules.isWhiteLoseButNotDrawWhenBoardFull;
|
||||
rule.isLoseButNotChangeSideWhenNoWay =
|
||||
_rules.isLoseButNotChangeSideWhenNoWay;
|
||||
rule.mayFly = _rules.mayFly;
|
||||
rule.nMoveRule = _rules.nMoveRule;
|
||||
rule.endgameNMoveRule = _rules.endgameNMoveRule;
|
||||
rule.threefoldRepetitionRule = _rules.threefoldRepetitionRule;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue