parent
cbf88aeed0
commit
a350fd9641
|
@ -69,7 +69,7 @@
|
|||
|
||||
//#define DEBUG_MODE
|
||||
|
||||
#define DEFAULT_RULE_NUMBER 1
|
||||
#define DEFAULT_RULE_NUMBER 2
|
||||
|
||||
#define DEPTH_ADJUST (0)
|
||||
|
||||
|
|
|
@ -58,9 +58,6 @@ extern uint8_t PopCnt16[1 << 16];
|
|||
|
||||
extern Bitboard SquareBB[SQ_32];
|
||||
|
||||
extern Bitboard StarSquareBB9;
|
||||
extern Bitboard StarSquareBB12;
|
||||
|
||||
inline Bitboard square_bb(Square s) noexcept
|
||||
{
|
||||
if (!(SQ_BEGIN <= s && s < SQ_END))
|
||||
|
|
|
@ -502,16 +502,16 @@ Depth get_search_depth(const Position *pos)
|
|||
if (pos->phase == Phase::placing) {
|
||||
const int index = rule.piecesCount * 2 - pos->count<IN_HAND>(WHITE) - pos->count<IN_HAND>(BLACK);
|
||||
|
||||
if (rule.piecesCount == 12) {
|
||||
assert(0 <= index && index <= 24);
|
||||
if (rule.piecesCount == 9) {
|
||||
assert(0 <= index && index <= 19);
|
||||
d = placingDepthTable_9[index];
|
||||
} else {
|
||||
assert(0 <= index && index <= rule.piecesCount * 2);
|
||||
if (!rule.hasBannedLocations && !rule.hasDiagonalLines) {
|
||||
d = placingDepthTable_12_special[index];
|
||||
} else {
|
||||
d = placingDepthTable_12[index];
|
||||
}
|
||||
} else {
|
||||
assert(0 <= index && index <= 19);
|
||||
d = placingDepthTable_9[index];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ void MovePicker::score()
|
|||
|
||||
//cur->value += bannedCount; // placing phrase, place nearby ban point
|
||||
|
||||
// for 12 men's morris (has diagonal), black 2nd move place star point is as important as close mill (TODO)
|
||||
// If has Diagonal Lines, black 2nd move place star point is as important as close mill (TODO)
|
||||
if (rule.hasDiagonalLines &&
|
||||
pos.count<ON_BOARD>(BLACK) < 2 && // patch: only when black 2nd move
|
||||
Position::is_star_square(static_cast<Square>(m))) {
|
||||
|
|
|
@ -169,7 +169,7 @@ public:
|
|||
Piece board[SQUARE_NB];
|
||||
Bitboard byTypeBB[PIECE_TYPE_NB];
|
||||
Bitboard byColorBB[COLOR_NB];
|
||||
int pieceInHandCount[COLOR_NB] { 0, 12, 12 };
|
||||
int pieceInHandCount[COLOR_NB] { 0, 9, 9 };
|
||||
int pieceOnBoardCount[COLOR_NB] { 0, 0, 0 };
|
||||
int pieceToRemoveCount{ 0 };
|
||||
int gamePly { 0 };
|
||||
|
|
21
src/rule.cpp
21
src/rule.cpp
|
@ -21,24 +21,19 @@
|
|||
#include "rule.h"
|
||||
|
||||
struct Rule rule = {
|
||||
"打三棋(12连棋)", // 打三棋
|
||||
"Nine men's morris", // 莫里斯九子棋
|
||||
// 规则说明
|
||||
"1. 双方各12颗子,棋盘有斜线;\n"
|
||||
"2. 摆棋阶段被提子的位置不能再摆子,直到走棋阶段;\n"
|
||||
"3. 摆棋阶段,摆满棋盘算先手负;\n"
|
||||
"4. 走棋阶段,后摆棋的一方先走;\n"
|
||||
"5. 同时出现两个“三连”只能提一子;\n"
|
||||
"6. 其它规则与成三棋基本相同。",
|
||||
12, // 双方各12子
|
||||
"规则与成三棋基本相同,只是在走子阶段,当一方仅剩3子时,他可以飞子到任意空位。",
|
||||
9, // 双方各9子
|
||||
3, // 赛点子数为3
|
||||
true, // 有斜线
|
||||
true, // 有禁点,摆棋阶段被提子的点不能再摆子
|
||||
true, // 后摆棋者先行棋
|
||||
false, // 没有斜线
|
||||
false, // 没有禁点,摆棋阶段被提子的点可以再摆子
|
||||
false, // 先摆棋者先行棋
|
||||
false, // 多个“三连”只能提一子
|
||||
true, // 可以提对手的“三连”子
|
||||
false, // 不能提对手的“三连”子,除非无子可提;
|
||||
true, // 摆棋满子(闷棋,只有12子棋才出现)算先手负
|
||||
true, // 走棋阶段不能行动(被“闷”)算负
|
||||
false, // 剩三子时不可以飞棋
|
||||
true, // 剩三子时可以飞棋
|
||||
99 // 99半步即50回合
|
||||
};
|
||||
|
||||
|
|
21
src/uci.cpp
21
src/uci.cpp
|
@ -37,8 +37,11 @@ namespace
|
|||
{
|
||||
|
||||
// FEN string of the initial position, normal mill game
|
||||
const char *StartFEN9 = "********/********/******** w p p 0 9 0 9 0 0 1";
|
||||
const char *StartFEN10 = "********/********/******** w p p 0 10 0 10 0 0 1";
|
||||
const char *StartFEN11 = "********/********/******** w p p 0 11 0 11 0 0 1";
|
||||
const char *StartFEN12 = "********/********/******** w p p 0 12 0 12 0 0 1";
|
||||
const char *StartFEN9 = "********/********/******** w p p 0 9 0 9 0 0 1";
|
||||
|
||||
char StartFEN[BUFSIZ];
|
||||
|
||||
// position() is called when engine receives the "position" UCI command.
|
||||
|
@ -157,10 +160,22 @@ void UCI::loop(int argc, char *argv[])
|
|||
Position *pos = new Position;
|
||||
string token, cmd;
|
||||
|
||||
if (rule.piecesCount == 9) {
|
||||
switch (rule.piecesCount) {
|
||||
case 9:
|
||||
strncpy(StartFEN, StartFEN9, BUFSIZ);
|
||||
} else if (rule.piecesCount == 12) {
|
||||
break;
|
||||
case 10:
|
||||
strncpy(StartFEN, StartFEN10, BUFSIZ);
|
||||
break;
|
||||
case 11:
|
||||
strncpy(StartFEN, StartFEN11, BUFSIZ);
|
||||
break;
|
||||
case 12:
|
||||
strncpy(StartFEN, StartFEN12, BUFSIZ);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
pos->set(StartFEN, Threads.main());
|
||||
|
|
|
@ -174,16 +174,16 @@ void init(OptionsMap &o)
|
|||
o["DeveloperMode"] << Option(true, on_developerMode);
|
||||
|
||||
// Rules
|
||||
o["PiecesCount"] << Option(12, 6, 12, on_piecesCount);
|
||||
o["PiecesCount"] << Option(9, 9, 12, on_piecesCount);
|
||||
o["PiecesAtLeastCount"] << Option(3, 3, 5, on_piecesAtLeastCount);
|
||||
o["HasDiagonalLines"] << Option(true, on_hasDiagonalLines);
|
||||
o["HasBannedLocations"] << Option(true, on_hasBannedLocations);
|
||||
o["IsDefenderMoveFirst"] << Option(true, on_isDefenderMoveFirst);
|
||||
o["HasDiagonalLines"] << Option(false, on_hasDiagonalLines);
|
||||
o["HasBannedLocations"] << Option(false, on_hasBannedLocations);
|
||||
o["IsDefenderMoveFirst"] << Option(false, on_isDefenderMoveFirst);
|
||||
o["MayRemoveMultiple"] << Option(false, on_mayRemoveMultiple);
|
||||
o["MayRemoveFromMillsAlways"] << Option(true, on_mayRemoveFromMillsAlways);
|
||||
o["MayRemoveFromMillsAlways"] << Option(false, on_mayRemoveFromMillsAlways);
|
||||
o["IsWhiteLoseButNotDrawWhenBoardFull"] << Option(true, on_isWhiteLoseButNotDrawWhenBoardFull);
|
||||
o["IsLoseButNotChangeSideWhenNoWay"] << Option(true, on_isLoseButNotChangeSideWhenNoWay);
|
||||
o["MayFly"] << Option(false, on_mayFly);
|
||||
o["MayFly"] << Option(true, on_mayFly);
|
||||
o["MaxStepsLedToDraw"] << Option(50, 30, 50, on_maxStepsLedToDraw);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,54 +22,7 @@ import 'rule.dart';
|
|||
class Mills {
|
||||
static void adjacentSquaresInit() {
|
||||
// Note: Not follow order of MoveDirection array
|
||||
const adjacentSquares12 = [
|
||||
/* 0 */ [0, 0, 0, 0],
|
||||
/* 1 */ [0, 0, 0, 0],
|
||||
/* 2 */ [0, 0, 0, 0],
|
||||
/* 3 */ [0, 0, 0, 0],
|
||||
/* 4 */ [0, 0, 0, 0],
|
||||
/* 5 */ [0, 0, 0, 0],
|
||||
/* 6 */ [0, 0, 0, 0],
|
||||
/* 7 */ [0, 0, 0, 0],
|
||||
|
||||
/* 8 */ [9, 15, 16, 0],
|
||||
/* 9 */ [17, 8, 10, 0],
|
||||
/* 10 */ [9, 11, 18, 0],
|
||||
/* 11 */ [19, 10, 12, 0],
|
||||
/* 12 */ [11, 13, 20, 0],
|
||||
/* 13 */ [21, 12, 14, 0],
|
||||
/* 14 */ [13, 15, 22, 0],
|
||||
/* 15 */ [23, 8, 14, 0],
|
||||
|
||||
/* 16 */ [17, 23, 8, 24],
|
||||
/* 17 */ [9, 25, 16, 18],
|
||||
/* 18 */ [17, 19, 10, 26],
|
||||
/* 19 */ [11, 27, 18, 20],
|
||||
/* 20 */ [19, 21, 12, 28],
|
||||
/* 21 */ [13, 29, 20, 22],
|
||||
/* 22 */ [21, 23, 14, 30],
|
||||
/* 23 */ [15, 31, 16, 22],
|
||||
|
||||
/* 24 */ [25, 31, 16, 0],
|
||||
/* 25 */ [17, 24, 26, 0],
|
||||
/* 26 */ [25, 27, 18, 0],
|
||||
/* 27 */ [19, 26, 28, 0],
|
||||
/* 28 */ [27, 29, 20, 0],
|
||||
/* 29 */ [21, 28, 30, 0],
|
||||
/* 30 */ [29, 31, 22, 0],
|
||||
/* 31 */ [23, 24, 30, 0],
|
||||
|
||||
/* 32 */ [0, 0, 0, 0],
|
||||
/* 33 */ [0, 0, 0, 0],
|
||||
/* 34 */ [0, 0, 0, 0],
|
||||
/* 35 */ [0, 0, 0, 0],
|
||||
/* 36 */ [0, 0, 0, 0],
|
||||
/* 37 */ [0, 0, 0, 0],
|
||||
/* 38 */ [0, 0, 0, 0],
|
||||
/* 39 */ [0, 0, 0, 0],
|
||||
];
|
||||
|
||||
const adjacentSquares9 = [
|
||||
const adjacentSquares = [
|
||||
/* 0 */ [0, 0, 0, 0],
|
||||
/* 1 */ [0, 0, 0, 0],
|
||||
/* 2 */ [0, 0, 0, 0],
|
||||
|
@ -116,15 +69,62 @@ class Mills {
|
|||
/* 39 */ [0, 0, 0, 0],
|
||||
];
|
||||
|
||||
const adjacentSquares_diagonal = [
|
||||
/* 0 */ [0, 0, 0, 0],
|
||||
/* 1 */ [0, 0, 0, 0],
|
||||
/* 2 */ [0, 0, 0, 0],
|
||||
/* 3 */ [0, 0, 0, 0],
|
||||
/* 4 */ [0, 0, 0, 0],
|
||||
/* 5 */ [0, 0, 0, 0],
|
||||
/* 6 */ [0, 0, 0, 0],
|
||||
/* 7 */ [0, 0, 0, 0],
|
||||
|
||||
/* 8 */ [9, 15, 16, 0],
|
||||
/* 9 */ [17, 8, 10, 0],
|
||||
/* 10 */ [9, 11, 18, 0],
|
||||
/* 11 */ [19, 10, 12, 0],
|
||||
/* 12 */ [11, 13, 20, 0],
|
||||
/* 13 */ [21, 12, 14, 0],
|
||||
/* 14 */ [13, 15, 22, 0],
|
||||
/* 15 */ [23, 8, 14, 0],
|
||||
|
||||
/* 16 */ [17, 23, 8, 24],
|
||||
/* 17 */ [9, 25, 16, 18],
|
||||
/* 18 */ [17, 19, 10, 26],
|
||||
/* 19 */ [11, 27, 18, 20],
|
||||
/* 20 */ [19, 21, 12, 28],
|
||||
/* 21 */ [13, 29, 20, 22],
|
||||
/* 22 */ [21, 23, 14, 30],
|
||||
/* 23 */ [15, 31, 16, 22],
|
||||
|
||||
/* 24 */ [25, 31, 16, 0],
|
||||
/* 25 */ [17, 24, 26, 0],
|
||||
/* 26 */ [25, 27, 18, 0],
|
||||
/* 27 */ [19, 26, 28, 0],
|
||||
/* 28 */ [27, 29, 20, 0],
|
||||
/* 29 */ [21, 28, 30, 0],
|
||||
/* 30 */ [29, 31, 22, 0],
|
||||
/* 31 */ [23, 24, 30, 0],
|
||||
|
||||
/* 32 */ [0, 0, 0, 0],
|
||||
/* 33 */ [0, 0, 0, 0],
|
||||
/* 34 */ [0, 0, 0, 0],
|
||||
/* 35 */ [0, 0, 0, 0],
|
||||
/* 36 */ [0, 0, 0, 0],
|
||||
/* 37 */ [0, 0, 0, 0],
|
||||
/* 38 */ [0, 0, 0, 0],
|
||||
/* 39 */ [0, 0, 0, 0],
|
||||
];
|
||||
|
||||
if (rule.hasDiagonalLines) {
|
||||
Position.adjacentSquares = adjacentSquares12;
|
||||
Position.adjacentSquares = adjacentSquares_diagonal;
|
||||
} else {
|
||||
Position.adjacentSquares = adjacentSquares9;
|
||||
Position.adjacentSquares = adjacentSquares;
|
||||
}
|
||||
}
|
||||
|
||||
static void millTableInit() {
|
||||
const millTable9 = [
|
||||
const millTable = [
|
||||
/* 0 */ [
|
||||
[0, 0],
|
||||
[0, 0],
|
||||
|
@ -331,7 +331,7 @@ class Mills {
|
|||
]
|
||||
];
|
||||
|
||||
const millTable12 = [
|
||||
const millTable_diagonal = [
|
||||
/* 0 */ [
|
||||
[0, 0],
|
||||
[0, 0],
|
||||
|
@ -539,9 +539,9 @@ class Mills {
|
|||
];
|
||||
|
||||
if (rule.hasDiagonalLines) {
|
||||
Position.millTable = millTable12;
|
||||
Position.millTable = millTable_diagonal;
|
||||
} else {
|
||||
Position.millTable = millTable9;
|
||||
Position.millTable = millTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -799,6 +799,17 @@ class Position {
|
|||
setSideToMove(PieceColor.opponent(_sideToMove));
|
||||
st.key ^= Zobrist.side;
|
||||
print("[position] $_sideToMove to move.");
|
||||
|
||||
/*
|
||||
if (phase == Phase.moving &&
|
||||
!rule.isLoseButNotChangeSideWhenNoWay &&
|
||||
isAllSurrounded() &&
|
||||
!rule.mayFly &&
|
||||
pieceOnBoardCount[sideToMove()]! >= rule.piecesAtLeastCount) {
|
||||
print("[position] $_sideToMove is no way to go.");
|
||||
changeSideToMove();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int updateKey(int s) {
|
||||
|
|
|
@ -205,6 +205,8 @@ class _GamePageState extends State<GamePage>
|
|||
return;
|
||||
}
|
||||
|
||||
// If nobody has placed, start to go.
|
||||
|
||||
// TODO
|
||||
// WAR: Fix first tap response slow when piece count changed
|
||||
if (position.phase == Phase.placing &&
|
||||
|
@ -233,6 +235,8 @@ class _GamePageState extends State<GamePage>
|
|||
Game.instance.start();
|
||||
}
|
||||
|
||||
// Human to go
|
||||
|
||||
bool ret = false;
|
||||
Chain.capture(() {
|
||||
switch (position.action) {
|
||||
|
@ -431,7 +435,7 @@ class _GamePageState extends State<GamePage>
|
|||
Game.instance.sideToMove = position.sideToMove() ?? PieceColor.nobody;
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
}); // Chain.capture
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ class _RuleSettingsPageState extends State<RuleSettingsPage> {
|
|||
context: context,
|
||||
titleString: S.of(context).piecesCount,
|
||||
subtitleString: S.of(context).piecesCount_Detail,
|
||||
trailingString: Config.piecesCount == 9 ? '9' : '12',
|
||||
trailingString: Config.piecesCount.toString(),
|
||||
onTap: setNTotalPiecesEachSide,
|
||||
),
|
||||
ListItemDivider(),
|
||||
|
@ -197,6 +197,22 @@ class _RuleSettingsPageState extends State<RuleSettingsPage> {
|
|||
onChanged: callback,
|
||||
),
|
||||
ListItemDivider(),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text('10'),
|
||||
groupValue: Config.piecesCount,
|
||||
value: 10,
|
||||
onChanged: callback,
|
||||
),
|
||||
ListItemDivider(),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text('11'),
|
||||
groupValue: Config.piecesCount,
|
||||
value: 11,
|
||||
onChanged: callback,
|
||||
),
|
||||
ListItemDivider(),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text('12'),
|
||||
|
|
Loading…
Reference in New Issue