Skip to content

Commit

Permalink
refactor: make _computeBestMoveShapes() public
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-anders committed Oct 22, 2024
1 parent decd1cd commit abd8ebc
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 70 deletions.
72 changes: 72 additions & 0 deletions lib/src/model/common/eval.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'dart:math' as math;

import 'package:chessground/chessground.dart';
import 'package:collection/collection.dart';
import 'package:dartchess/dartchess.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:lichess_mobile/src/model/common/chess.dart';

Expand Down Expand Up @@ -158,6 +161,75 @@ class PvData with _$PvData {

typedef MoveWithWinningChances = ({Move move, double winningChances});

ISet<Shape> computeBestMoveShapes(
IList<MoveWithWinningChances> moves,
Side sideToMove,
PieceAssets pieceAssets,
) {
// Scale down all moves with index > 0 based on how much worse their winning chances are compared to the best move
// (assume moves are ordered by their winning chances, so index==0 is the best move)
double scaleArrowAgainstBestMove(int index) {
const minScale = 0.15;
const maxScale = 1.0;
const winningDiffScaleFactor = 2.5;

final bestMove = moves[0];
final winningDiffComparedToBestMove =
bestMove.winningChances - moves[index].winningChances;
// Force minimum scale if the best move is significantly better than this move
if (winningDiffComparedToBestMove > 0.3) {
return minScale;
}
return clampDouble(
math.max(
minScale,
maxScale - winningDiffScaleFactor * winningDiffComparedToBestMove,
),
0,
1,
);
}

return ISet(
moves.mapIndexed(
(i, m) {
final move = m.move;
// Same colors as in the Web UI with a slightly different opacity
// The best move has a different color than the other moves
final color = Color((i == 0) ? 0x66003088 : 0x664A4A4A);
switch (move) {
case NormalMove(from: _, to: _, promotion: final promRole):
return [
Arrow(
color: color,
orig: move.from,
dest: move.to,
scale: scaleArrowAgainstBestMove(i),
),
if (promRole != null)
PieceShape(
color: color,
orig: move.to,
pieceAssets: pieceAssets,
piece: Piece(color: sideToMove, role: promRole),
),
];
case DropMove(role: final role, to: _):
return [
PieceShape(
color: color,
orig: move.to,
pieceAssets: pieceAssets,
opacity: 0.5,
piece: Piece(color: sideToMove, role: role),
),
];
}
},
).expand((e) => e),
);
}

double cpToPawns(int cp) => cp / 100;

int cpFromPawns(double pawns) => (pawns * 100).round();
Expand Down
71 changes: 1 addition & 70 deletions lib/src/view/analysis/analysis_board.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class AnalysisBoardState extends ConsumerState<AnalysisBoard> {
final ISet<Shape> bestMoveShapes = showBestMoveArrow &&
analysisState.isEngineAvailable &&
bestMoves != null
? _computeBestMoveShapes(
? computeBestMoveShapes(
bestMoves,
currentNode.position.turn,
boardPrefs.pieceSet.assets,
Expand Down Expand Up @@ -119,75 +119,6 @@ class AnalysisBoardState extends ConsumerState<AnalysisBoard> {
);
}

ISet<Shape> _computeBestMoveShapes(
IList<MoveWithWinningChances> moves,
Side sideToMove,
PieceAssets pieceAssets,
) {
// Scale down all moves with index > 0 based on how much worse their winning chances are compared to the best move
// (assume moves are ordered by their winning chances, so index==0 is the best move)
double scaleArrowAgainstBestMove(int index) {
const minScale = 0.15;
const maxScale = 1.0;
const winningDiffScaleFactor = 2.5;

final bestMove = moves[0];
final winningDiffComparedToBestMove =
bestMove.winningChances - moves[index].winningChances;
// Force minimum scale if the best move is significantly better than this move
if (winningDiffComparedToBestMove > 0.3) {
return minScale;
}
return clampDouble(
math.max(
minScale,
maxScale - winningDiffScaleFactor * winningDiffComparedToBestMove,
),
0,
1,
);
}

return ISet(
moves.mapIndexed(
(i, m) {
final move = m.move;
// Same colors as in the Web UI with a slightly different opacity
// The best move has a different color than the other moves
final color = Color((i == 0) ? 0x66003088 : 0x664A4A4A);
switch (move) {
case NormalMove(from: _, to: _, promotion: final promRole):
return [
Arrow(
color: color,
orig: move.from,
dest: move.to,
scale: scaleArrowAgainstBestMove(i),
),
if (promRole != null)
PieceShape(
color: color,
orig: move.to,
pieceAssets: pieceAssets,
piece: Piece(color: sideToMove, role: promRole),
),
];
case DropMove(role: final role, to: _):
return [
PieceShape(
color: color,
orig: move.to,
pieceAssets: pieceAssets,
opacity: 0.5,
piece: Piece(color: sideToMove, role: role),
),
];
}
},
).expand((e) => e),
);
}

void _onCompleteShape(Shape shape) {
if (userShapes.any((element) => element == shape)) {
setState(() {
Expand Down

0 comments on commit abd8ebc

Please sign in to comment.