Skip to content

Commit

Permalink
perfect: Support return value
Browse files Browse the repository at this point in the history
Change-Id: Ic468438dbc337a60fd76b62990d918cea2d0d305
  • Loading branch information
calcitem committed Dec 24, 2023
1 parent 5b065a0 commit cc5c447
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 30 deletions.
21 changes: 15 additions & 6 deletions src/perfect/perfect_adaptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,32 @@
#define USE_DEPRECATED_CLR_API_WITHOUT_WARNING

static Move malom_remove_move = MOVE_NONE;
static Value malom_remove_value = VALUE_UNKNOWN;

static std::condition_variable cv;

int GetBestMove(int whiteBitboard, int blackBitboard, int whiteStonesToPlace,
int blackStonesToPlace, int playerToMove, bool onlyStoneTaking)
int blackStonesToPlace, int playerToMove, bool onlyStoneTaking,
Value &value)
{
return MalomSolutionAccess::getBestMove(whiteBitboard, blackBitboard,
whiteStonesToPlace,
blackStonesToPlace, playerToMove,
onlyStoneTaking);
onlyStoneTaking, value);
}

int perfect_init()
{
malom_remove_move = MOVE_NONE;
malom_remove_value = VALUE_UNKNOWN;

return 0;
}

int perfect_exit()
{
malom_remove_move = MOVE_NONE;
malom_remove_value = VALUE_UNKNOWN;

return 0;
}
Expand Down Expand Up @@ -176,11 +180,15 @@ std::vector<Move> convertBitboardMove(int whiteBitboard, int blackBitboard,

Value perfect_search(const Position *pos, Move &move)
{
Value value = VALUE_UNKNOWN;

if (malom_remove_move != MOVE_NONE) {
Move ret = malom_remove_move;
value = malom_remove_value;
malom_remove_move = MOVE_NONE;
malom_remove_value = VALUE_UNKNOWN;
move = ret;
return VALUE_MOVE_PERFECT;
return value;
}

std::vector<Move> moves;
Expand Down Expand Up @@ -234,15 +242,17 @@ Value perfect_search(const Position *pos, Move &move)
// If this increases the number of stones the player to move has,
// then that player will have one less stone to place after the move.
// TODO: Do not use -fexceptions

try {
int moveBitboard = GetBestMove(whiteBitboard, blackBitboard,
whiteStonesToPlace, blackStonesToPlace,
playerToMove, onlyStoneTaking);
playerToMove, onlyStoneTaking, value);
moves = convertBitboardMove(whiteBitboard, blackBitboard, playerToMove,
moveBitboard);

if (moves.size() == 2) {
malom_remove_move = moves.at(1);
malom_remove_value = value;
}
} catch (const std::exception &) {
move = MOVE_NONE;
Expand All @@ -251,8 +261,7 @@ Value perfect_search(const Position *pos, Move &move)

move = Move(moves.at(0));

// TODO: Return the value of the position
return VALUE_MOVE_PERFECT;
return value;
}

#endif // GABOR_MALOM_PERFECT_AI
10 changes: 6 additions & 4 deletions src/perfect/perfect_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ std::exception *MalomSolutionAccess::lastError = nullptr;
int MalomSolutionAccess::getBestMove(int whiteBitboard, int blackBitboard,
int whiteStonesToPlace,
int blackStonesToPlace, int playerToMove,
bool onlyStoneTaking)
bool onlyStoneTaking, Value &value)
{
initializeIfNeeded();

Expand Down Expand Up @@ -95,7 +95,7 @@ int MalomSolutionAccess::getBestMove(int whiteBitboard, int blackBitboard,
int ret = 0;

try {
ret = pp->chooseRandom(pp->goodMoves(s)).toBitBoard();
ret = pp->chooseRandom(pp->goodMoves(s, value)).toBitBoard();
} catch (std::out_of_range &) {
throw std::runtime_error("We don't have a database entry for this "
"position. This can happen either if the "
Expand All @@ -111,12 +111,14 @@ int MalomSolutionAccess::getBestMove(int whiteBitboard, int blackBitboard,

int MalomSolutionAccess::getBestMoveNoException(
int whiteBitboard, int blackBitboard, int whiteStonesToPlace,
int blackStonesToPlace, int playerToMove, bool onlyStoneTaking)
int blackStonesToPlace, int playerToMove, bool onlyStoneTaking,
Value &value)
{
try {
lastError = nullptr;
return getBestMove(whiteBitboard, blackBitboard, whiteStonesToPlace,
blackStonesToPlace, playerToMove, onlyStoneTaking);
blackStonesToPlace, playerToMove, onlyStoneTaking,
value);
} catch (std::exception &e) {
lastError = &e;
return 0;
Expand Down
5 changes: 3 additions & 2 deletions src/perfect/perfect_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ class MalomSolutionAccess
public:
static int getBestMove(int whiteBitboard, int blackBitboard,
int whiteStonesToPlace, int blackStonesToPlace,
int playerToMove, bool onlyStoneTaking);
int playerToMove, bool onlyStoneTaking,
Value &value);

static int getBestMoveNoException(int whiteBitboard, int blackBitboard,
int whiteStonesToPlace,
int blackStonesToPlace, int playerToMove,
bool onlyStoneTaking);
bool onlyStoneTaking, Value &value);

static std::string getLastError();

Expand Down
23 changes: 18 additions & 5 deletions src/perfect/perfect_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ Wrappers::gui_eval_elem2 PerfectPlayer::moveValue(const GameState &s,

template <typename T, typename K>
std::vector<T> PerfectPlayer::allMaxBy(std::function<K(T)> f,
const std::vector<T> &l, K minValue)
const std::vector<T> &l, K minValue, Value &value)
{
std::vector<T> r;

Expand Down Expand Up @@ -386,20 +386,31 @@ std::vector<T> PerfectPlayer::allMaxBy(std::function<K(T)> f,
}
}

char e = f(r.at(0)).toString().at(0);

if (e == 'L') {
value = -VALUE_MATE_PERFECT;
} else if (e == 'W') {
value = VALUE_MATE_PERFECT;
} else {
value = VALUE_DRAW_PERFECT;
}

return r;
}

#if 1
// Assuming the definition of gui_eval_elem2::min_value function
std::vector<AdvancedMove> PerfectPlayer::goodMoves(const GameState &s)
std::vector<AdvancedMove> PerfectPlayer::goodMoves(const GameState &s, Value &value)
{
return allMaxBy(std::function<Wrappers::gui_eval_elem2(AdvancedMove)>(
[this, &s](AdvancedMove m) { return moveValue(s, m); }),
getMoveList(s),
Wrappers::gui_eval_elem2::min_value(getSec(s)));
Wrappers::gui_eval_elem2::min_value(getSec(s)), value);
}
#else
std::vector<AdvancedMove> PerfectPlayer::goodMoves(const GameState &s)
std::vector<AdvancedMove> PerfectPlayer::goodMoves(const GameState &s,
Value &value)
{
auto moveList = getMoveList(s);
std::cout << "Move list size: " << moveList.size()
Expand Down Expand Up @@ -452,8 +463,10 @@ void PerfectPlayer::sendMoveToGUI(AdvancedMove m)

void PerfectPlayer::toMove(const GameState &s)
{
Value value = VALUE_UNKNOWN;

try {
AdvancedMove mh = chooseRandom(goodMoves(s));
AdvancedMove mh = chooseRandom(goodMoves(s, value));
sendMoveToGUI(mh);
} catch (const std::out_of_range &) {
sendMoveToGUI(chooseRandom(getMoveList(s)));
Expand Down
8 changes: 6 additions & 2 deletions src/perfect/perfect_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <string>
#include <vector>

#include <types.h>

enum class CMoveType {
SetMove,
SlideMove // should be renamed to SlideOrJumpMove
Expand All @@ -58,6 +60,8 @@ struct AdvancedMove
// closure, onlyTaking only includes removal
int takeHon;

Value value {VALUE_DRAW_PERFECT};

int toBitBoard()
{
if (onlyTaking) {
Expand Down Expand Up @@ -170,10 +174,10 @@ class PerfectPlayer : public Player

template <typename T, typename K>
std::vector<T> allMaxBy(std::function<K(T)> f, const std::vector<T> &l,
K minValue);
K minValue, Value &value);

// Assuming the definition of gui_eval_elem2::min_value function
std::vector<AdvancedMove> goodMoves(const GameState &s);
std::vector<AdvancedMove> goodMoves(const GameState &s, Value &value);

int NGMAfterMove(const GameState &s, AdvancedMove &m);

Expand Down
12 changes: 8 additions & 4 deletions src/perfect/perfect_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,23 @@

int perfect_test(int argc, char *argv[])
{
Value value = VALUE_UNKNOWN;

if (argc == 2) {
sec_val_path = argv[1];
}

// int res = MalomSolutionAccess::getBestMove(0, 0, 9, 9, 0, false);
int res = MalomSolutionAccess::getBestMove(1, 2, 8, 8, 0, false); // Correct
int res = MalomSolutionAccess::getBestMove(1, 2, 8, 8, 0, false,
value); // Correct
// output:
// 16384
// int res = MalomSolutionAccess::getBestMove(1 + 2 + 4, 8 + 16 + 32, 100,
// 0, 0, false); // tests exception
// 0, 0, false, value); // tests exception
// int res = MalomSolutionAccess::getBestMove(1 + 2 + 4, 1 + 8 + 16 + 32,
// 0, 0, 0, false); // tests exception int res =
// MalomSolutionAccess::getBestMove(1 + 2 + 4, 8 + 16 + 32, 0, 0, 0, true);
// 0, 0, 0, false, value); // tests exception int res =
// MalomSolutionAccess::getBestMove(1 + 2 + 4, 8 + 16 + 32, 0, 0, 0, true,
// value);
// // Correct output: any of 8, 16, 32

printf("GetBestMove result: %d\n", res);
Expand Down
5 changes: 4 additions & 1 deletion src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,14 @@ enum Bound : uint8_t {
enum Value : int8_t {
VALUE_ZERO = 0,
VALUE_DRAW = 0,
VALUE_DRAW_PERFECT = 1,

#ifdef ENDGAME_LEARNING
VALUE_KNOWN_WIN = 25,
#endif
VALUE_MOVE_PERFECT = 1,

VALUE_MATE = 80,
VALUE_MATE_PERFECT = 79,
VALUE_UNIQUE = 100,
VALUE_INFINITE = 125,
VALUE_UNKNOWN = INT8_MIN,
Expand Down
3 changes: 2 additions & 1 deletion src/ui/flutter_app/lib/game_page/services/engine/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ extension GameResultExtension on GameResult {
}
}

const int valueMovePerfect = 1;
const int valueDrawPerfect = 1;
const int valueMatePerfect = 79;
const int valueUnique = 100;
const int valueEachPiece = 5;

Expand Down
13 changes: 8 additions & 5 deletions src/ui/flutter_app/lib/game_page/widgets/game_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ class _GameHeaderState extends State<GameHeader> {
int value =
GameController().value == null ? 0 : int.parse(GameController().value!);

if (abs(value) != valueMovePerfect &&
DB().displaySettings.isPositionalAdvantageIndicatorShown) {
final bool perfect = abs(value) == valueDrawPerfect ||
abs(value) == valueMatePerfect;
final double opacity = perfect? 0.5 : 1;

if (DB().displaySettings.isPositionalAdvantageIndicatorShown) {
const int valueLimit = 100;

// TODO: Modify engine to return suitable value
Expand Down Expand Up @@ -111,12 +114,12 @@ class _GameHeaderState extends State<GameHeader> {
Container(
height: 2,
width: dividerWhiteLength.toDouble(),
color: DB().colorSettings.whitePieceColor,
color: DB().colorSettings.whitePieceColor.withOpacity(opacity),
),
Container(
height: 2,
width: dividerBlackLength.toDouble(),
color: DB().colorSettings.blackPieceColor,
color: DB().colorSettings.blackPieceColor.withOpacity(opacity),
),
],
),
Expand All @@ -127,7 +130,7 @@ class _GameHeaderState extends State<GameHeader> {
width: 180,
margin: const EdgeInsets.only(bottom: AppTheme.boardMargin),
decoration: BoxDecoration(
color: DB().colorSettings.boardBackgroundColor,
color: DB().colorSettings.boardBackgroundColor.withOpacity(opacity),
borderRadius: BorderRadius.circular(2),
),
);
Expand Down

0 comments on commit cc5c447

Please sign in to comment.