ai: 将评估函数分离到 evaluate.cpp
This commit is contained in:
parent
019738c7ce
commit
d2df0c1c13
|
@ -22,6 +22,7 @@ INCLUDEPATH += src/game
|
||||||
INCLUDEPATH += src/ui/qt
|
INCLUDEPATH += src/ui/qt
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
src/ai/evaluate.cpp \
|
||||||
src/game/millgame.cpp \
|
src/game/millgame.cpp \
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
src/base/thread.cpp \
|
src/base/thread.cpp \
|
||||||
|
@ -39,6 +40,7 @@ HEADERS += \
|
||||||
include/config.h \
|
include/config.h \
|
||||||
include/version.h \
|
include/version.h \
|
||||||
include/version.h.template \
|
include/version.h.template \
|
||||||
|
src/ai/evaluate.h \
|
||||||
src/base/HashNode.h \
|
src/base/HashNode.h \
|
||||||
src/base/debug.h \
|
src/base/debug.h \
|
||||||
src/base/hashMap.h \
|
src/base/hashMap.h \
|
||||||
|
|
|
@ -441,6 +441,7 @@
|
||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
</AdditionalInputs>
|
</AdditionalInputs>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<ClInclude Include="src\ai\evaluate.h" />
|
||||||
<ClInclude Include="src\ai\search.h" />
|
<ClInclude Include="src\ai\search.h" />
|
||||||
<ClInclude Include="src\ai\zobrist.h" />
|
<ClInclude Include="src\ai\zobrist.h" />
|
||||||
<ClInclude Include="src\base\debug.h" />
|
<ClInclude Include="src\base\debug.h" />
|
||||||
|
@ -690,6 +691,7 @@
|
||||||
<Text Include="..\Sample.txt" />
|
<Text Include="..\Sample.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\ai\evaluate.cpp" />
|
||||||
<ClCompile Include="src\ai\search.cpp" />
|
<ClCompile Include="src\ai\search.cpp" />
|
||||||
<ClCompile Include="src\base\thread.cpp" />
|
<ClCompile Include="src\base\thread.cpp" />
|
||||||
<ClCompile Include="src\game\millgame.cpp" />
|
<ClCompile Include="src\game\millgame.cpp" />
|
||||||
|
|
|
@ -96,6 +96,9 @@
|
||||||
<ClInclude Include="src\base\debug.h">
|
<ClInclude Include="src\base\debug.h">
|
||||||
<Filter>base</Filter>
|
<Filter>base</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\ai\evaluate.h">
|
||||||
|
<Filter>ai</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||||
|
@ -304,6 +307,9 @@
|
||||||
<ClCompile Include="src\ai\search.cpp">
|
<ClCompile Include="src\ai\search.cpp">
|
||||||
<Filter>ai</Filter>
|
<Filter>ai</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\ai\evaluate.cpp">
|
||||||
|
<Filter>ai</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="millgame.rc">
|
<ResourceCompile Include="millgame.rc">
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
#include "evaluate.h"
|
||||||
|
|
||||||
|
Evaluation::value_t Evaluation::getValue(MillGame &chessTemp, MillGame::ChessContext *chessContext, MillGameAi_ab::Node *node)
|
||||||
|
{
|
||||||
|
// 初始评估值为0,对先手有利则增大,对后手有利则减小
|
||||||
|
value_t value = 0;
|
||||||
|
|
||||||
|
int nPiecesInHandDiff = INT_MAX;
|
||||||
|
int nPiecesOnBoardDiff = INT_MAX;
|
||||||
|
int nPiecesNeedRemove = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->stage = chessContext->stage;
|
||||||
|
node->action = chessContext->action;
|
||||||
|
node->evaluated = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (chessContext->stage) {
|
||||||
|
case MillGame::GAME_NOTSTARTED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MillGame::GAME_PLACING:
|
||||||
|
// 按手中的棋子计分,不要break;
|
||||||
|
nPiecesInHandDiff = chessContext->nPiecesInHand_1 - chessContext->nPiecesInHand_2;
|
||||||
|
value += nPiecesInHandDiff * 50;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->nPiecesInHandDiff = nPiecesInHandDiff;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 按场上棋子计分
|
||||||
|
nPiecesOnBoardDiff = chessContext->nPiecesOnBoard_1 - chessContext->nPiecesOnBoard_2;
|
||||||
|
value += nPiecesOnBoardDiff * 100;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->nPiecesOnBoardDiff = nPiecesOnBoardDiff;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (chessContext->action) {
|
||||||
|
// 选子和落子使用相同的评价方法
|
||||||
|
case MillGame::ACTION_CHOOSE:
|
||||||
|
case MillGame::ACTION_PLACE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 如果形成去子状态,每有一个可去的子,算100分
|
||||||
|
case MillGame::ACTION_CAPTURE:
|
||||||
|
nPiecesNeedRemove = (chessContext->turn == MillGame::PLAYER1) ?
|
||||||
|
chessContext->nPiecesNeedRemove : -(chessContext->nPiecesNeedRemove);
|
||||||
|
value += nPiecesNeedRemove * 100;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->nPiecesNeedRemove = nPiecesNeedRemove;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MillGame::GAME_MOVING:
|
||||||
|
// 按场上棋子计分
|
||||||
|
value += chessContext->nPiecesOnBoard_1 * 100 - chessContext->nPiecesOnBoard_2 * 100;
|
||||||
|
|
||||||
|
#ifdef EVALUATE_MOBILITY
|
||||||
|
// 按棋子活动能力计分
|
||||||
|
value += chessTemp.getMobilityDiff(false) * 10;
|
||||||
|
#endif /* EVALUATE_MOBILITY */
|
||||||
|
|
||||||
|
switch (chessContext->action) {
|
||||||
|
// 选子和落子使用相同的评价方法
|
||||||
|
case MillGame::ACTION_CHOOSE:
|
||||||
|
case MillGame::ACTION_PLACE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 如果形成去子状态,每有一个可去的子,算128分
|
||||||
|
case MillGame::ACTION_CAPTURE:
|
||||||
|
nPiecesNeedRemove = (chessContext->turn == MillGame::PLAYER1) ?
|
||||||
|
chessContext->nPiecesNeedRemove : -(chessContext->nPiecesNeedRemove);
|
||||||
|
value += nPiecesNeedRemove * 128;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->nPiecesNeedRemove = nPiecesNeedRemove;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 终局评价最简单
|
||||||
|
case MillGame::GAME_OVER:
|
||||||
|
// 布局阶段闷棋判断
|
||||||
|
if (chessContext->nPiecesOnBoard_1 + chessContext->nPiecesOnBoard_2 >=
|
||||||
|
MillGame::N_SEATS * MillGame::N_RINGS) {
|
||||||
|
if (chessTemp.getRule()->isStartingPlayerLoseWhenBoardFull) {
|
||||||
|
// winner = PLAYER2;
|
||||||
|
value -= 10000;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->result = -3;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 走棋阶段被闷判断
|
||||||
|
if (chessContext->action == MillGame::ACTION_CHOOSE &&
|
||||||
|
chessTemp.isAllSurrounded(chessContext->turn) &&
|
||||||
|
chessTemp.getRule()->isLoseWhenNoWay) {
|
||||||
|
// 规则要求被“闷”判负,则对手获胜
|
||||||
|
if (chessContext->turn == MillGame::PLAYER1) {
|
||||||
|
value -= 10000;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->result = -2;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
value += 10000;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->result = 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 剩余棋子个数判断
|
||||||
|
if (chessContext->nPiecesOnBoard_1 < chessTemp.getRule()->nPiecesAtLeast) {
|
||||||
|
value -= 10000;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->result = -1;
|
||||||
|
#endif
|
||||||
|
} else if (chessContext->nPiecesOnBoard_2 < chessTemp.getRule()->nPiecesAtLeast) {
|
||||||
|
value += 10000;
|
||||||
|
#ifdef DEBUG_AB_TREE
|
||||||
|
node->result = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 赋值返回
|
||||||
|
node->value = value;
|
||||||
|
return value;
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef EVALUATE_H
|
||||||
|
#define EVALUATE_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "millgame.h"
|
||||||
|
#include "search.h"
|
||||||
|
|
||||||
|
class Evaluation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Evaluation() = delete;
|
||||||
|
|
||||||
|
Evaluation &operator=(const Evaluation &) = delete;
|
||||||
|
|
||||||
|
using value_t = MillGameAi_ab::value_t;
|
||||||
|
|
||||||
|
static value_t getValue(MillGame &chessTemp, MillGame::ChessContext *chessContext, MillGameAi_ab::Node *node);
|
||||||
|
|
||||||
|
// ÆÀ¹À×ÓÁ¦
|
||||||
|
#ifdef EVALUATE_ENABLE
|
||||||
|
|
||||||
|
#ifdef EVALUATE_MATERIAL
|
||||||
|
static value_t evaluateMaterial(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVALUATE_SPACE
|
||||||
|
static value_t evaluateSpace(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVALUATE_MOBILITY
|
||||||
|
static value_t evaluateMobility(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVALUATE_TEMPO
|
||||||
|
static value_t evaluateTempo(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVALUATE_THREAT
|
||||||
|
static value_t evaluateThreat(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVALUATE_SHAPE
|
||||||
|
static value_t evaluateShape(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EVALUATE_MOTIF
|
||||||
|
static value_t MillGameAi_ab::evaluateMotif(Node *node)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* EVALUATE_ENABLE */
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* EVALUATE_H */
|
|
@ -26,6 +26,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "search.h"
|
#include "search.h"
|
||||||
|
#include "evaluate.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
|
|
||||||
using namespace CTSL;
|
using namespace CTSL;
|
||||||
|
@ -479,204 +480,6 @@ void MillGameAi_ab::setChess(const MillGame &chess)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 评估子力
|
|
||||||
#ifdef EVALUATE_ENABLE
|
|
||||||
|
|
||||||
#ifdef EVALUATE_MATERIAL
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateMaterial(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EVALUATE_SPACE
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateSpace(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EVALUATE_MOBILITY
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateMobility(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EVALUATE_TEMPO
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateTempo(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EVALUATE_THREAT
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateThreat(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EVALUATE_SHAPE
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateShape(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EVALUATE_MOTIF
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluateMotif(Node *node)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* EVALUATE_ENABLE */
|
|
||||||
|
|
||||||
MillGameAi_ab::value_t MillGameAi_ab::evaluate(Node *node)
|
|
||||||
{
|
|
||||||
// 初始评估值为0,对先手有利则增大,对后手有利则减小
|
|
||||||
value_t value = 0;
|
|
||||||
|
|
||||||
int nPiecesInHandDiff = INT_MAX;
|
|
||||||
int nPiecesOnBoardDiff = INT_MAX;
|
|
||||||
int nPiecesNeedRemove = 0;
|
|
||||||
|
|
||||||
evaluatedNodeCount++;
|
|
||||||
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->stage = chessContext->stage;
|
|
||||||
node->action = chessContext->action;
|
|
||||||
node->evaluated = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (chessContext->stage) {
|
|
||||||
case MillGame::GAME_NOTSTARTED:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MillGame::GAME_PLACING:
|
|
||||||
// 按手中的棋子计分,不要break;
|
|
||||||
nPiecesInHandDiff = chessContext->nPiecesInHand_1 - chessContext->nPiecesInHand_2;
|
|
||||||
value += nPiecesInHandDiff * 50;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->nPiecesInHandDiff = nPiecesInHandDiff;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 按场上棋子计分
|
|
||||||
nPiecesOnBoardDiff = chessContext->nPiecesOnBoard_1 - chessContext->nPiecesOnBoard_2;
|
|
||||||
value += nPiecesOnBoardDiff * 100;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->nPiecesOnBoardDiff = nPiecesOnBoardDiff;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (chessContext->action) {
|
|
||||||
// 选子和落子使用相同的评价方法
|
|
||||||
case MillGame::ACTION_CHOOSE:
|
|
||||||
case MillGame::ACTION_PLACE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// 如果形成去子状态,每有一个可去的子,算100分
|
|
||||||
case MillGame::ACTION_CAPTURE:
|
|
||||||
nPiecesNeedRemove = (chessContext->turn == MillGame::PLAYER1) ?
|
|
||||||
chessContext->nPiecesNeedRemove : -(chessContext->nPiecesNeedRemove);
|
|
||||||
value += nPiecesNeedRemove * 100;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->nPiecesNeedRemove = nPiecesNeedRemove;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MillGame::GAME_MOVING:
|
|
||||||
// 按场上棋子计分
|
|
||||||
value += chessContext->nPiecesOnBoard_1 * 100 - chessContext->nPiecesOnBoard_2 * 100;
|
|
||||||
|
|
||||||
#ifdef EVALUATE_MOBILITY
|
|
||||||
// 按棋子活动能力计分
|
|
||||||
value += chessTemp.getMobilityDiff(false) * 10;
|
|
||||||
#endif /* EVALUATE_MOBILITY */
|
|
||||||
|
|
||||||
switch (chessContext->action) {
|
|
||||||
// 选子和落子使用相同的评价方法
|
|
||||||
case MillGame::ACTION_CHOOSE:
|
|
||||||
case MillGame::ACTION_PLACE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// 如果形成去子状态,每有一个可去的子,算128分
|
|
||||||
case MillGame::ACTION_CAPTURE:
|
|
||||||
nPiecesNeedRemove = (chessContext->turn == MillGame::PLAYER1) ?
|
|
||||||
chessContext->nPiecesNeedRemove : -(chessContext->nPiecesNeedRemove);
|
|
||||||
value += nPiecesNeedRemove * 128;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->nPiecesNeedRemove = nPiecesNeedRemove;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// 终局评价最简单
|
|
||||||
case MillGame::GAME_OVER:
|
|
||||||
// 布局阶段闷棋判断
|
|
||||||
if (chessContext->nPiecesOnBoard_1 + chessContext->nPiecesOnBoard_2 >=
|
|
||||||
MillGame::N_SEATS * MillGame::N_RINGS) {
|
|
||||||
if (chessTemp.currentRule.isStartingPlayerLoseWhenBoardFull) {
|
|
||||||
// winner = PLAYER2;
|
|
||||||
value -= 10000;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->result = -3;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 走棋阶段被闷判断
|
|
||||||
if (chessContext->action == MillGame::ACTION_CHOOSE &&
|
|
||||||
chessTemp.isAllSurrounded(chessContext->turn) &&
|
|
||||||
chessTemp.currentRule.isLoseWhenNoWay) {
|
|
||||||
// 规则要求被“闷”判负,则对手获胜
|
|
||||||
if (chessContext->turn == MillGame::PLAYER1) {
|
|
||||||
value -= 10000;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->result = -2;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
value += 10000;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->result = 2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 剩余棋子个数判断
|
|
||||||
if (chessContext->nPiecesOnBoard_1 < chessTemp.currentRule.nPiecesAtLeast) {
|
|
||||||
value -= 10000;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->result = -1;
|
|
||||||
#endif
|
|
||||||
} else if (chessContext->nPiecesOnBoard_2 < chessTemp.currentRule.nPiecesAtLeast) {
|
|
||||||
value += 10000;
|
|
||||||
#ifdef DEBUG_AB_TREE
|
|
||||||
node->result = 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 赋值返回
|
|
||||||
node->value = value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MillGameAi_ab::alphaBetaPruning(depth_t depth)
|
int MillGameAi_ab::alphaBetaPruning(depth_t depth)
|
||||||
{
|
{
|
||||||
value_t value = 0;
|
value_t value = 0;
|
||||||
|
@ -841,7 +644,8 @@ MillGameAi_ab::value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t al
|
||||||
// 搜索到叶子节点(决胜局面) // TODO: 对哈希进行特殊处理
|
// 搜索到叶子节点(决胜局面) // TODO: 对哈希进行特殊处理
|
||||||
if (chessContext->stage == MillGame::GAME_OVER) {
|
if (chessContext->stage == MillGame::GAME_OVER) {
|
||||||
// 局面评估
|
// 局面评估
|
||||||
node->value = evaluate(node);
|
node->value = Evaluation::getValue(chessTemp, chessContext, node);
|
||||||
|
evaluatedNodeCount++;
|
||||||
|
|
||||||
// 为争取速胜,value 值 +- 深度
|
// 为争取速胜,value 值 +- 深度
|
||||||
if (node->value > 0) {
|
if (node->value > 0) {
|
||||||
|
@ -865,7 +669,8 @@ MillGameAi_ab::value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t al
|
||||||
// 搜索到第0层或需要退出
|
// 搜索到第0层或需要退出
|
||||||
if (!depth || requiredQuit) {
|
if (!depth || requiredQuit) {
|
||||||
// 局面评估
|
// 局面评估
|
||||||
node->value = evaluate(node);
|
node->value = Evaluation::getValue(chessTemp, chessContext, node);
|
||||||
|
evaluatedNodeCount++;
|
||||||
|
|
||||||
// 为争取速胜,value 值 +- 深度 (有必要?)
|
// 为争取速胜,value 值 +- 深度 (有必要?)
|
||||||
if (chessContext->turn == MillGame::PLAYER1) {
|
if (chessContext->turn == MillGame::PLAYER1) {
|
||||||
|
|
|
@ -493,7 +493,6 @@ public:
|
||||||
// 局面逆时针旋转
|
// 局面逆时针旋转
|
||||||
void rotate(int degrees, bool cmdChange = true);
|
void rotate(int degrees, bool cmdChange = true);
|
||||||
|
|
||||||
protected:
|
|
||||||
// 判断棋盘pos处的棋子处于几个“三连”中
|
// 判断棋盘pos处的棋子处于几个“三连”中
|
||||||
int isInMills(int pos, bool test = false);
|
int isInMills(int pos, bool test = false);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue