better null safety

This commit is contained in:
Leptopoda 2021-10-24 21:47:39 +02:00 committed by Nikolas Rimikis
parent bc915c7d53
commit ed85908834
5 changed files with 86 additions and 100 deletions

View File

@ -44,7 +44,7 @@ class Position {
List<String> board = List.filled(sqNumber, "");
List<String> _grid = List.filled(7 * 7, "");
GameRecorder? recorder;
late GameRecorder recorder;
Map<String, int> pieceInHandCount = {
PieceColor.white: -1,
@ -79,7 +79,7 @@ class Position {
int currentSquare = 0;
int nPlayed = 0;
String? record;
late String record;
static late List<List<List<int>>> millTable;
static late List<List<int>> adjacentSquares;
@ -280,9 +280,8 @@ class Position {
if (move == "draw") {
phase = Phase.gameOver;
_winner = PieceColor.draw;
if (score[PieceColor.draw] != null) {
score[PieceColor.draw] = score[PieceColor.draw]! + 1;
}
score[PieceColor.draw] = score[PieceColor.draw]! + 1;
// TODO: WAR to judge rule50
if (rule.nMoveRule > 0 && posKeyHistory.length >= rule.nMoveRule - 1) {
@ -342,7 +341,7 @@ class Position {
++gamePly;
++st.pliesFromNull;
if (record != null && record!.length > "-(1,2)".length) {
if (record.length > "-(1,2)".length) {
if (posKeyHistory.isEmpty ||
(posKeyHistory.isNotEmpty &&
st.key != posKeyHistory[posKeyHistory.length - 1])) {
@ -360,7 +359,7 @@ class Position {
this.move = m;
recorder!.moveIn(m, this); // TODO: Is Right?
recorder.moveIn(m, this); // TODO: Is Right?
return true;
}
@ -748,17 +747,7 @@ class Position {
void updateScore() {
if (phase == Phase.gameOver) {
if (_winner == PieceColor.draw) {
if (score[PieceColor.draw] != null) {
score[PieceColor.draw] = score[PieceColor.draw]! + 1;
}
return;
}
if (score[_winner] != null) {
score[_winner] = score[_winner]! + 1;
}
score[_winner] = score[_winner]! + 1;
}
}
@ -1063,15 +1052,11 @@ class Position {
for (int r = 0; r < rankNumber; r++) {
final int s = f * rankNumber + r;
if (board[s] == Piece.whiteStone) {
if (pieceOnBoardCount[PieceColor.white] != null) {
pieceOnBoardCount[PieceColor.white] =
pieceOnBoardCount[PieceColor.white]! + 1;
}
pieceOnBoardCount[PieceColor.white] =
pieceOnBoardCount[PieceColor.white]! + 1;
} else if (board[s] == Piece.blackStone) {
if (pieceOnBoardCount[PieceColor.black] != null) {
pieceOnBoardCount[PieceColor.black] =
pieceOnBoardCount[PieceColor.black]! + 1;
}
pieceOnBoardCount[PieceColor.black] =
pieceOnBoardCount[PieceColor.black]! + 1;
}
}
}
@ -1089,17 +1074,17 @@ class Position {
Future<String> gotoHistory(HistoryMove move, [int? index]) async {
final int moveIndex = _gotoHistoryIndex(move, index);
if (recorder == null) {
debugPrint("[goto] recorder is null.");
return "null";
}
//if (recorder == null) {
// debugPrint("[goto] recorder is null.");
// return "null";
//}
if (recorder!.cur == moveIndex) {
if (recorder.cur == moveIndex) {
debugPrint("[goto] cur is equal to moveIndex.");
return "equal";
}
final history = recorder!.history;
final history = recorder.history;
if (moveIndex < -1 || history.length <= moveIndex) {
debugPrint("[goto] moveIndex is out of range.");
@ -1125,8 +1110,8 @@ class Position {
}
for (var i = 0; i <= moveIndex; i++) {
if (await gameInstance.doMove(history[i].move!) == false) {
errString = history[i].move!;
if (await gameInstance.doMove(history[i].move) == false) {
errString = history[i].move;
break;
}
}
@ -1134,8 +1119,8 @@ class Position {
// Restore context
gameInstance.engineType = engineTypeBackup;
gameInstance.setWhoIsAi(engineTypeBackup);
recorder!.history = historyBack;
recorder!.cur = moveIndex;
recorder.history = historyBack;
recorder.cur = moveIndex;
Audios.isTemporaryMute = false;
await _gotoHistoryPlaySound(move);
@ -1146,20 +1131,20 @@ class Position {
int _gotoHistoryIndex(HistoryMove move, [int? index]) {
switch (move) {
case HistoryMove.forwardAll:
return recorder!.history.length - 1;
return recorder.history.length - 1;
case HistoryMove.backAll:
return -1;
case HistoryMove.farward:
return recorder!.cur + 1;
return recorder.cur + 1;
case HistoryMove.backN:
assert(index != null);
int _index = recorder!.cur - index!;
int _index = recorder.cur - index!;
if (_index < -1) {
_index = -1;
}
return _index;
case HistoryMove.backOne:
return recorder!.cur - 1;
return recorder.cur - 1;
}
}
@ -1180,15 +1165,15 @@ class Position {
}
String movesSinceLastRemove() {
int? i = 0;
int i = 0;
final buffer = StringBuffer();
int posAfterLastRemove = 0;
//debugPrint("recorder.movesCount = ${recorder.movesCount}");
for (i = recorder!.movesCount - 1; i! >= 0; i--) {
for (i = recorder.movesCount - 1; i >= 0; i--) {
//if (recorder.moveAt(i).type == MoveType.remove) break;
if (recorder!.moveAt(i).move![0] == '-') break;
if (recorder.moveAt(i).move[0] == '-') break;
}
if (i >= 0) {
@ -1197,8 +1182,8 @@ class Position {
//debugPrint("[movesSinceLastRemove] posAfterLastRemove = $posAfterLastRemove");
for (int i = posAfterLastRemove; i < recorder!.movesCount; i++) {
buffer.write(" ${recorder!.moveAt(i).move}");
for (int i = posAfterLastRemove; i < recorder.movesCount; i++) {
buffer.write(" ${recorder.moveAt(i).move}");
}
final String moves = buffer.toString();
@ -1213,13 +1198,13 @@ class Position {
return moves.isNotEmpty ? moves.substring(1) : '';
}
String get moveHistoryText => recorder!.buildMoveHistoryText();
String get moveHistoryText => recorder.buildMoveHistoryText();
String get side => _sideToMove;
Move? get lastMove => recorder!.last;
Move? get lastMove => recorder.last;
String? get lastPositionWithRemove => recorder!.lastPositionWithRemove;
String? get lastPositionWithRemove => recorder.lastPositionWithRemove;
}
enum HistoryMove { forwardAll, backAll, farward, backN, backOne }

View File

@ -40,7 +40,7 @@ class Move {
String removed = Piece.noPiece;
// 'move' is the UCI engine's move-string
String? move = "";
String move = "";
// "notation" is Standard Notation
String? notation = "";
@ -55,30 +55,30 @@ class Move {
throw "Error: Invalid Move: $move";
}
if (move![0] == '-' && move!.length == "-(1,2)".length) {
if (move[0] == '-' && move.length == "-(1,2)".length) {
type = MoveType.remove;
from = fromFile = fromRank = fromIndex = invalidMove;
toFile = int.parse(move![2]);
toRank = int.parse(move![4]);
toFile = int.parse(move[2]);
toRank = int.parse(move[4]);
to = makeSquare(toFile, toRank);
notation = "x${squareToWmdNotation[to]}";
//captured = Piece.noPiece;
} else if (move!.length == "(1,2)->(3,4)".length) {
} else if (move.length == "(1,2)->(3,4)".length) {
type = MoveType.move;
fromFile = int.parse(move![1]);
fromRank = int.parse(move![3]);
fromFile = int.parse(move[1]);
fromRank = int.parse(move[3]);
from = makeSquare(fromFile, fromRank);
fromIndex = squareToIndex[from] ?? invalidMove;
toFile = int.parse(move![8]);
toRank = int.parse(move![10]);
toFile = int.parse(move[8]);
toRank = int.parse(move[10]);
to = makeSquare(toFile, toRank);
notation = "${squareToWmdNotation[from]}-${squareToWmdNotation[to]}";
removed = Piece.noPiece;
} else if (move!.length == "(1,2)".length) {
} else if (move.length == "(1,2)".length) {
type = MoveType.place;
from = fromFile = fromRank = fromIndex = invalidMove;
toFile = int.parse(move![1]);
toRank = int.parse(move![3]);
toFile = int.parse(move[1]);
toRank = int.parse(move[3]);
to = makeSquare(toFile, toRank);
notation = "${squareToWmdNotation[to]}";
removed = Piece.noPiece;
@ -105,12 +105,12 @@ class Move {
parse();
}
static bool legal(String? move) {
static bool legal(String move) {
if (move == "draw") {
return true; // TODO
}
if (move == null || move.length > "(3,1)->(2,1)".length) return false;
if (move.length > "(3,1)->(2,1)".length) return false;
const String range = "0123456789(,)->";

View File

@ -455,7 +455,7 @@ class _GamePageState extends State<GamePage>
if (ret) {
gameInstance.sideToMove = position.sideToMove;
gameInstance.moveHistory.add(position.record!);
gameInstance.moveHistory.add(position.record);
// TODO: Need Others?
// Increment ply counters. In particular,
@ -465,7 +465,7 @@ class _GamePageState extends State<GamePage>
++position.st.rule50;
++position.st.pliesFromNull;
if (position.record!.length > "-(1,2)".length) {
if (position.record.length > "-(1,2)".length) {
if (posKeyHistory.isEmpty ||
(posKeyHistory.isNotEmpty &&
position.st.key != posKeyHistory[posKeyHistory.length - 1])) {
@ -484,8 +484,8 @@ class _GamePageState extends State<GamePage>
//position.move = m;
final Move m = Move(position.record);
position.recorder!.prune();
position.recorder!.moveIn(m, position);
position.recorder.prune();
position.recorder.moveIn(m, position);
/*
if (LocalDatabaseService.preferences.screenReaderSupport && m.notation != null) {
@ -528,7 +528,7 @@ class _GamePageState extends State<GamePage>
showSnackBar(context, S.of(context).notAIsTurn);
return;
}
if (!gameInstance.position.recorder!.isClean()) {
if (!gameInstance.position.recorder.isClean()) {
debugPrint(
"[engineToGo] History is not clean. Cannot get search result now.",
);
@ -551,7 +551,7 @@ class _GamePageState extends State<GamePage>
if (mounted) {
showTip(S.of(context).thinking);
final Move? m = gameInstance.position.recorder!.lastMove;
final Move? m = gameInstance.position.recorder.lastMove;
if (LocalDatabaseService.preferences.screenReaderSupport &&
gameInstance.position.action != Act.remove &&
@ -593,7 +593,7 @@ class _GamePageState extends State<GamePage>
);
}
await gameInstance.doMove(move.move!);
await gameInstance.doMove(move.move);
showTips();
if (LocalDatabaseService.preferences.screenReaderSupport &&
move.notation != null) {
@ -665,8 +665,8 @@ class _GamePageState extends State<GamePage>
debugPrint(text);
await onTakeBackAllButtonPressed(false);
gameInstance.position.recorder!.clear();
final importFailedStr = gameInstance.position.recorder!.import(text);
gameInstance.position.recorder.clear();
final importFailedStr = gameInstance.position.recorder.import(text);
if (importFailedStr != "") {
showTip("${S.of(context).cannotImport} $importFailedStr");
@ -1030,7 +1030,7 @@ class _GamePageState extends State<GamePage>
*/
late final String text;
final lastEffectiveMove = pos.recorder!.lastEffectiveMove;
final lastEffectiveMove = pos.recorder.lastEffectiveMove;
if (lastEffectiveMove != null && lastEffectiveMove.notation != null) {
text = "${S.of(context).lastMove}: ${lastEffectiveMove.notation}";
} else {
@ -1593,12 +1593,12 @@ class _GamePageState extends State<GamePage>
: "\n$_tip";
String lastMove = "";
if (pos.recorder?.lastMove?.notation != null) {
final String n1 = pos.recorder!.lastMove!.notation!;
if (pos.recorder.lastMove?.notation != null) {
final String n1 = pos.recorder.lastMove!.notation!;
if (n1.startsWith("x")) {
final String n2 =
pos.recorder!.moveAt(pos.recorder!.movesCount - 2).notation!;
pos.recorder.moveAt(pos.recorder.movesCount - 2).notation!;
lastMove = n2 + n1;
} else {
lastMove = n1;

View File

@ -30,9 +30,9 @@ class PiecePaintParam {
}
class PiecesPainter extends PiecesBasePainter {
final Position? position;
final int? focusIndex;
final int? blurIndex;
final Position position;
final int focusIndex;
final int blurIndex;
final double animationValue;
int pointStyle = 0;
@ -81,17 +81,17 @@ class PiecesPainter extends PiecesBasePainter {
static void doPaint(
Canvas canvas,
Paint paint, {
Position? position,
double? gridWidth,
double? squareWidth,
int? pointStyle,
double? pointWidth,
double? pieceWidth,
double? animatedPieceWidth,
double? offsetX,
double? offsetY,
int? focusIndex = invalidIndex,
int? blurIndex = invalidIndex,
required Position position,
required double gridWidth,
required double squareWidth,
required int pointStyle,
required double pointWidth,
required double pieceWidth,
required double animatedPieceWidth,
required double offsetX,
required double offsetY,
int focusIndex = invalidIndex,
int blurIndex = invalidIndex,
}) {
//
final left = offsetX;
@ -107,19 +107,19 @@ class PiecesPainter extends PiecesBasePainter {
for (var row = 0; row < 7; row++) {
for (var col = 0; col < 7; col++) {
final index = row * 7 + col;
final piece = position!.pieceOnGrid(index); // No Pieces when initial
final piece = position.pieceOnGrid(index); // No Pieces when initial
if (piece == Piece.noPiece) continue;
final pos =
Offset(left! + squareWidth! * col, top! + squareWidth * row);
Offset(left+ squareWidth* col, top+ squareWidth * row);
final animated = focusIndex == index;
piecesToDraw
.add(PiecePaintParam(piece: piece, pos: pos, animated: animated));
shadowPath.addOval(
Rect.fromCenter(center: pos, width: pieceWidth!, height: pieceWidth),
Rect.fromCenter(center: pos, width: pieceWidth, height: pieceWidth),
);
}
}
@ -138,10 +138,10 @@ class PiecesPainter extends PiecesBasePainter {
*/
for (final pps in piecesToDraw) {
final pieceRadius = pieceWidth! / 2;
final pieceRadius = pieceWidth/ 2;
final pieceInnerRadius = pieceRadius * 0.99;
final animatedPieceRadius = animatedPieceWidth! / 2;
final animatedPieceRadius = animatedPieceWidth/ 2;
final animatedPieceInnerRadius = animatedPieceRadius * 0.99;
// Draw Border of Piece
@ -189,7 +189,7 @@ class PiecesPainter extends PiecesBasePainter {
// draw focus and blur position
final int row = focusIndex! ~/ 7;
final int row = focusIndex~/ 7;
final int column = focusIndex % 7;
if (focusIndex != invalidIndex) {
@ -218,22 +218,22 @@ class PiecesPainter extends PiecesBasePainter {
paint.strokeWidth = 2;
canvas.drawCircle(
Offset(left! + column * squareWidth!, top! + row * squareWidth),
animatedPieceWidth! / 2,
Offset(left+ column * squareWidth, top+ row * squareWidth),
animatedPieceWidth/ 2,
paint,
);
}
if (blurIndex != invalidIndex) {
final row = blurIndex! ~/ 7;
final row = blurIndex~/ 7;
final column = blurIndex % 7;
paint.color = blurPositionColor;
paint.style = PaintingStyle.fill;
canvas.drawCircle(
Offset(left! + column * squareWidth!, top! + row * squareWidth),
animatedPieceWidth! / 2 * 0.8,
Offset(left+ column * squareWidth, top+ row * squareWidth),
animatedPieceWidth/ 2 * 0.8,
paint,
);
}

View File

@ -58,6 +58,7 @@ class SettingsListTile extends StatelessWidget {
color: AppTheme.listTileSubtitleColor,
),
),
// TODO: [Leptopoda] fix the trailing widget
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[