refactor: point 改为 location 并删除无用文件
This commit is contained in:
parent
be8139f6c7
commit
ca63416b63
|
@ -89,7 +89,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Position &dummyPosition,
|
|||
ai_ab.addNode(node, VALUE_ZERO, (move_t)location, bestMove, dummyPosition.context.turn);
|
||||
} else {
|
||||
// 若为先手,则抢占星位
|
||||
if (Position::isStarPoint(location)) {
|
||||
if (Position::isStarLocation(location)) {
|
||||
ai_ab.addNode(node, VALUE_INFINITE, (move_t)location, bestMove, dummyPosition.context.turn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -447,7 +447,7 @@ bool Position::place(int location, int time_p, int8_t rs)
|
|||
context.action = ACTION_CHOOSE;
|
||||
|
||||
// 清除禁点
|
||||
cleanForbiddenPoints();
|
||||
cleanForbiddenLocations();
|
||||
|
||||
// 设置轮到谁走
|
||||
if (currentRule.isDefenderMoveFirst) {
|
||||
|
@ -609,7 +609,7 @@ bool Position::capture(int location, int time_p, int8_t cp)
|
|||
}
|
||||
|
||||
// 去子(设置禁点)
|
||||
if (currentRule.hasForbiddenPoint && context.phase == PHASE_PLACING) {
|
||||
if (currentRule.hasForbiddenLocations && context.phase == PHASE_PLACING) {
|
||||
revertHash(location);
|
||||
boardLocations[location] = '\x0f';
|
||||
updateHash(location);
|
||||
|
@ -664,7 +664,7 @@ bool Position::capture(int location, int time_p, int8_t cp)
|
|||
context.action = ACTION_CHOOSE;
|
||||
|
||||
// 清除禁点
|
||||
cleanForbiddenPoints();
|
||||
cleanForbiddenLocations();
|
||||
|
||||
// 设置轮到谁走
|
||||
if (currentRule.isDefenderMoveFirst) {
|
||||
|
@ -1066,7 +1066,7 @@ int Position::getMobilityDiff(enum player_t turn, const Rule &rule, int nPiecesO
|
|||
return diff;
|
||||
}
|
||||
|
||||
void Position::cleanForbiddenPoints()
|
||||
void Position::cleanForbiddenLocations()
|
||||
{
|
||||
int location = 0;
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ public:
|
|||
}
|
||||
|
||||
// 判断位置点是否为星位 (星位是经常会先占的位置)
|
||||
static bool isStarPoint(int location)
|
||||
static bool isStarLocation(int location)
|
||||
{
|
||||
return (location == 17 || location == 19 || location == 21 || location == 23);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ public:
|
|||
bool win(bool forceDraw);
|
||||
|
||||
// 清除所有禁点
|
||||
void cleanForbiddenPoints();
|
||||
void cleanForbiddenLocations();
|
||||
|
||||
// 改变轮流
|
||||
enum player_t changeTurn();
|
||||
|
|
|
@ -1,407 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2018-2019 MillGame authors
|
||||
*
|
||||
* Authors: liuweilhy <liuweilhy@163.com>
|
||||
* Calcitem <calcitem@outlook.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef POSITION_H
|
||||
#define POSITION_H
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <list>
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "rule.h"
|
||||
#include "board.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
// 棋局结构体,算法相关,包含当前棋盘数据
|
||||
// 单独分离出来供AI判断局面用,生成置换表时使用
|
||||
class PositionContext
|
||||
{
|
||||
public:
|
||||
Board board;
|
||||
|
||||
// 局面的哈希值
|
||||
hash_t hash{};
|
||||
|
||||
// Zobrist 数组
|
||||
hash_t zobrist[Board::N_LOCATIONS][POINT_TYPE_COUNT]{};
|
||||
|
||||
// 局面阶段标识
|
||||
enum PositionStage stage;
|
||||
|
||||
// 轮流状态标识
|
||||
enum player_t turn;
|
||||
|
||||
// 动作状态标识
|
||||
enum Action action
|
||||
{
|
||||
};
|
||||
|
||||
// 玩家1剩余未放置子数
|
||||
int nPiecesInHand_1{};
|
||||
|
||||
// 玩家2剩余未放置子数
|
||||
int nPiecesInHand_2{};
|
||||
|
||||
// 玩家1盘面剩余子数
|
||||
int nPiecesOnBoard_1{};
|
||||
|
||||
// 玩家1盘面剩余子数
|
||||
int nPiecesOnBoard_2{};
|
||||
|
||||
// 尚待去除的子数
|
||||
int nPiecesNeedRemove{};
|
||||
};
|
||||
|
||||
// 棋类(在数据模型内,玩家只分先后手,不分黑白)
|
||||
// 注意:Position 类不是线程安全的!
|
||||
// 所以不能跨线程修改 Position 类的静态成员变量,切记!
|
||||
class Position
|
||||
{
|
||||
// AI友元类
|
||||
friend class MillGameAi_ab;
|
||||
|
||||
public:
|
||||
// 赢盘数
|
||||
int score_1 {};
|
||||
int score_2 {};
|
||||
int score_draw {};
|
||||
|
||||
uint64_t rand64() {
|
||||
return static_cast<uint64_t>(rand()) ^
|
||||
(static_cast<uint64_t>(rand()) << 15) ^
|
||||
(static_cast<uint64_t>(rand()) << 30) ^
|
||||
(static_cast<uint64_t>(rand()) << 45) ^
|
||||
(static_cast<uint64_t>(rand()) << 60);
|
||||
}
|
||||
|
||||
uint64_t rand56()
|
||||
{
|
||||
return rand64() << 8;
|
||||
}
|
||||
|
||||
static int playerToId(enum player_t player);
|
||||
|
||||
static player_t getOpponent(enum player_t player);
|
||||
|
||||
private:
|
||||
|
||||
// 创建哈希值
|
||||
void constructHash();
|
||||
|
||||
public:
|
||||
explicit Position();
|
||||
virtual ~Position();
|
||||
|
||||
// 拷贝构造函数
|
||||
explicit Position(const Position &);
|
||||
|
||||
// 运算符重载
|
||||
Position &operator=(const Position &);
|
||||
|
||||
// 设置配置
|
||||
bool configure(bool giveUpIfMostLose, bool randomMove);
|
||||
|
||||
// 设置棋局状态和棋盘上下文,用于初始化
|
||||
bool setContext(const struct Rule *rule,
|
||||
step_t maxStepsLedToDraw = 0, // 限制步数
|
||||
int maxTimeLedToLose = 0, // 限制时间
|
||||
step_t initialStep = 0, // 默认起始步数为0
|
||||
int flags = GAME_NOTSTARTED | PLAYER1 | ACTION_PLACE, // 默认状态
|
||||
const char *locations = nullptr, // 默认空棋盘
|
||||
int nPiecesInHand_1 = 12, // 玩家1剩余未放置子数
|
||||
int nPiecesInHand_2 = 12, // 玩家2剩余未放置子数
|
||||
int nPiecesNeedRemove = 0 // 尚待去除的子数
|
||||
);
|
||||
|
||||
// 获取棋局状态和棋盘上下文
|
||||
void getContext(struct Rule &rule, step_t &step, int &flags, int *&locations,
|
||||
int &nPiecesInHand_1, int &nPiecesInHand_2, int &nPiecesNeedRemove);
|
||||
|
||||
// 获取当前规则
|
||||
const struct Rule *getRule() const
|
||||
{
|
||||
return ¤tRule;
|
||||
}
|
||||
|
||||
// 获取棋盘数据
|
||||
const int *getBoardLocations() const
|
||||
{
|
||||
return boardLocations;
|
||||
}
|
||||
|
||||
// 获取当前棋子位置点
|
||||
int getCurrentLocation() const
|
||||
{
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
// 判断位置点是否为星位 (星位是经常会先占的位置)
|
||||
static bool isStarPoint(int location)
|
||||
{
|
||||
return (location == 17 || location == 19 || location == 21 || location == 23);
|
||||
}
|
||||
|
||||
// 获取当前步数
|
||||
int getStep() const
|
||||
{
|
||||
return currentStep;
|
||||
}
|
||||
|
||||
// 获取从上次吃子开始经历的移动步数
|
||||
int getMoveStep() const
|
||||
{
|
||||
return moveStep;
|
||||
}
|
||||
|
||||
// 获取是否必败时认输
|
||||
bool getGiveUpIfMostLose() const
|
||||
{
|
||||
return giveUpIfMostLose_;
|
||||
}
|
||||
|
||||
// 获取 AI 是否随机走子
|
||||
bool getRandomMove() const
|
||||
{
|
||||
return randomMove_;
|
||||
}
|
||||
|
||||
// 获取局面阶段标识
|
||||
enum PositionStage getStage() const
|
||||
{
|
||||
return context.stage;
|
||||
}
|
||||
|
||||
// 获取轮流状态标识
|
||||
enum player_t whosTurn() const
|
||||
{
|
||||
return context.turn;
|
||||
}
|
||||
|
||||
// 获取动作状态标识
|
||||
enum Action getAction() const
|
||||
{
|
||||
return context.action;
|
||||
}
|
||||
|
||||
// 判断胜负
|
||||
enum player_t whoWin() const
|
||||
{
|
||||
return winner;
|
||||
}
|
||||
|
||||
// 玩家1和玩家2的用时
|
||||
void getElapsedTime(time_t &p1_ms, time_t &p2_ms);
|
||||
|
||||
// 获取棋局的字符提示
|
||||
const string getTips() const
|
||||
{
|
||||
return tips;
|
||||
}
|
||||
|
||||
// 获取当前着法
|
||||
const char *getCmdLine() const
|
||||
{
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
// 获得棋谱
|
||||
const list<string> *getCmdList() const
|
||||
{
|
||||
return &cmdlist;
|
||||
}
|
||||
|
||||
// 获取开局时间
|
||||
time_t getStartTimeb() const
|
||||
{
|
||||
return startTime;
|
||||
}
|
||||
|
||||
// 重新设置开局时间
|
||||
void setStartTime(int stimeb)
|
||||
{
|
||||
startTime = stimeb;
|
||||
}
|
||||
|
||||
// 玩家1剩余未放置子数
|
||||
int getPiecesInHandCount_1() const
|
||||
{
|
||||
return context.nPiecesInHand_1;
|
||||
}
|
||||
|
||||
// 玩家2剩余未放置子数
|
||||
int getPiecesInHandCount_2() const
|
||||
{
|
||||
return context.nPiecesInHand_2;
|
||||
}
|
||||
|
||||
// 玩家1盘面剩余子数
|
||||
int getPiecesOnBoardCount_1() const
|
||||
{
|
||||
return context.nPiecesOnBoard_1;
|
||||
}
|
||||
|
||||
// 玩家1盘面剩余子数
|
||||
int getPiecesOnBoardCount_2() const
|
||||
{
|
||||
return context.nPiecesOnBoard_2;
|
||||
}
|
||||
|
||||
// 尚待去除的子数
|
||||
int getNum_NeedRemove() const
|
||||
{
|
||||
return context.nPiecesNeedRemove;
|
||||
}
|
||||
|
||||
// 计算玩家1和玩家2的棋子活动能力之差
|
||||
int getMobilityDiff(enum player_t turn, const Rule &rule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, bool includeFobidden);
|
||||
|
||||
// 游戏重置
|
||||
bool reset();
|
||||
|
||||
// 游戏开始
|
||||
bool start();
|
||||
|
||||
// 选子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始
|
||||
bool choose(int r, int s);
|
||||
|
||||
// 落子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始
|
||||
bool _place(int r, int s, int time_p = -1);
|
||||
|
||||
// 去子,在第r圈第s个位置,为迎合日常,r和s下标都从1开始
|
||||
bool _capture(int r, int s, int time_p = -1);
|
||||
|
||||
// 认输
|
||||
bool giveup(player_t loser);
|
||||
|
||||
// 命令行解析函数
|
||||
bool command(const char *cmd);
|
||||
|
||||
// 更新时间和状态,用内联函数以提高效率
|
||||
inline int update(int time_p = -1);
|
||||
|
||||
// 是否分出胜负
|
||||
bool win();
|
||||
bool win(bool forceDraw);
|
||||
|
||||
// 清除所有禁点
|
||||
void cleanForbiddenPoints();
|
||||
|
||||
// 改变轮流
|
||||
enum player_t changeTurn();
|
||||
|
||||
// 设置提示
|
||||
void setTips();
|
||||
|
||||
// 下面几个函数没有算法无关判断和无关操作,节约算法时间
|
||||
bool command(int move);
|
||||
bool choose(int location);
|
||||
bool place(int location, int time_p = -1, int8_t cp = 0);
|
||||
bool capture(int location, int time_p = -1, int8_t cp = 0);
|
||||
|
||||
// hash 相关
|
||||
hash_t getHash();
|
||||
hash_t revertHash(int location);
|
||||
hash_t updateHash(int location);
|
||||
hash_t updateHashMisc();
|
||||
|
||||
public: /* TODO: move to private */
|
||||
// 棋局上下文
|
||||
PositionContext context;
|
||||
|
||||
// 当前使用的规则
|
||||
struct Rule currentRule
|
||||
{
|
||||
};
|
||||
|
||||
// 棋局上下文中的棋盘数据,单独提出来
|
||||
int *boardLocations;
|
||||
|
||||
// 棋谱
|
||||
list <string> cmdlist;
|
||||
|
||||
// 着法命令行用于棋谱的显示和解析, 当前着法的命令行指令,即一招棋谱
|
||||
char cmdline[64]{};
|
||||
|
||||
/*
|
||||
当前着法,AI会用到,如下表示
|
||||
0x 00 00
|
||||
location1 location2
|
||||
开局落子:0x00??,??为棋盘上的位置
|
||||
移子:0x__??,__为移动前的位置,??为移动后的位置
|
||||
去子:0xFF??,??取位置补码,即为负数
|
||||
|
||||
31 ----- 24 ----- 25
|
||||
| \ | / |
|
||||
| 23 -- 16 -- 17 |
|
||||
| | \ | / | |
|
||||
| | 15 08 09 | |
|
||||
30-22-14 10-18-26
|
||||
| | 13 12 11 | |
|
||||
| | / | \ | |
|
||||
| 21 -- 20 -- 19 |
|
||||
| / | \ |
|
||||
29 ----- 28 ----- 27
|
||||
*/
|
||||
int32_t move_{};
|
||||
|
||||
// 选中的棋子在board中的位置
|
||||
int currentLocation{};
|
||||
|
||||
private:
|
||||
// 棋局哈希值
|
||||
// uint64_t hash;
|
||||
|
||||
// 胜负标识
|
||||
enum player_t winner;
|
||||
|
||||
// 当前步数
|
||||
step_t currentStep {};
|
||||
|
||||
// 从走子阶段开始或上次吃子起的步数
|
||||
int moveStep {};
|
||||
|
||||
// 是否必败时认输
|
||||
bool giveUpIfMostLose_ {false};
|
||||
|
||||
// AI 是否随机走子
|
||||
bool randomMove_ {true};
|
||||
|
||||
// 游戏起始时间
|
||||
time_t startTime {};
|
||||
|
||||
// 当前游戏时间
|
||||
time_t currentTime {};
|
||||
|
||||
// 玩家1用时(秒)
|
||||
time_t elapsedSeconds_1 {};
|
||||
|
||||
// 玩家2用时(秒)
|
||||
time_t elapsedSeconds_2 {};
|
||||
|
||||
// 当前棋局的字符提示
|
||||
string tips;
|
||||
};
|
||||
|
||||
#endif /* POSITION_H */
|
|
@ -42,7 +42,7 @@ struct Rule
|
|||
bool hasObliqueLines;
|
||||
|
||||
// 是否有禁点(摆棋阶段被提子的点不能再摆子)
|
||||
bool hasForbiddenPoint;
|
||||
bool hasForbiddenLocations;
|
||||
|
||||
// 是否后摆棋者先行棋
|
||||
bool isDefenderMoveFirst;
|
||||
|
|
|
@ -1061,7 +1061,7 @@ bool GameController::updateScence(Position &game)
|
|||
}
|
||||
|
||||
// 添加摆棋阶段禁子点
|
||||
if (game.getRule()->hasForbiddenPoint && game.getPhase() == PHASE_PLACING) {
|
||||
if (game.getRule()->hasForbiddenLocations && game.getPhase() == PHASE_PLACING) {
|
||||
for (int j = Board::LOCATION_BEGIN; j < Board::LOCATION_END; j++) {
|
||||
if (board[j] == 0x0F) {
|
||||
pos = scene.rs2pos(j / Board::N_SEATS, j % Board::N_SEATS + 1);
|
||||
|
@ -1080,7 +1080,7 @@ bool GameController::updateScence(Position &game)
|
|||
}
|
||||
|
||||
// 走棋阶段清除禁子点
|
||||
if (game.getRule()->hasForbiddenPoint && game.getPhase() != PHASE_PLACING) {
|
||||
if (game.getRule()->hasForbiddenLocations && game.getPhase() != PHASE_PLACING) {
|
||||
while (nTotalPieces < pieceList.size()) {
|
||||
delete pieceList.at(nTotalPieces);
|
||||
pieceList.removeAt(nTotalPieces);
|
||||
|
|
Loading…
Reference in New Issue