添加棋局的镜像、翻转、旋转算法,未完成,临时上传。
This commit is contained in:
parent
d762f55d70
commit
82b39b02ac
|
@ -273,6 +273,42 @@ void GameController::playSound(const QString &soundPath)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// 上下翻转
|
||||
void GameController::flip()
|
||||
{
|
||||
chess.mirror();
|
||||
chess.rotate(180);
|
||||
chessTemp = chess;
|
||||
updateScence();
|
||||
}
|
||||
|
||||
// 左右镜像
|
||||
void GameController::mirror()
|
||||
{
|
||||
chess.mirror();
|
||||
chessTemp = chess;
|
||||
updateScence();
|
||||
}
|
||||
|
||||
// 视图须时针旋转90°
|
||||
void GameController::turnRight()
|
||||
{
|
||||
chess.rotate(90);
|
||||
chessTemp = chess;
|
||||
updateScence();
|
||||
}
|
||||
|
||||
// 视图逆时针旋转90°
|
||||
void GameController::turnLeft()
|
||||
{
|
||||
chess.rotate(270);
|
||||
chessTemp = chess;
|
||||
updateScence();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//bool GameController::eventFilter(QObject * watched, QEvent * event)
|
||||
//{
|
||||
// return QObject::eventFilter(watched, event);
|
||||
|
|
|
@ -67,6 +67,15 @@ public slots:
|
|||
void setSound(bool arg = true);
|
||||
// 播放声音
|
||||
void playSound(const QString &soundPath);
|
||||
// 上下翻转
|
||||
void flip();
|
||||
// 左右镜像
|
||||
void mirror();
|
||||
// 视图须时针旋转90°
|
||||
void turnRight();
|
||||
// 视图逆时针旋转90°
|
||||
void turnLeft();
|
||||
|
||||
// 根据QGraphicsScene的信号和状态来执行选子、落子或去子
|
||||
bool actionPiece(QPointF p);
|
||||
// 认输
|
||||
|
|
|
@ -1588,3 +1588,263 @@ void NineChess::getPlayer_TimeMS(int &p1_ms, int &p2_ms)
|
|||
p1_ms = player1_MS;
|
||||
p2_ms = player2_MS;
|
||||
}
|
||||
|
||||
void NineChess::mirror(bool cmdChange /*= true*/)
|
||||
{
|
||||
char ch;
|
||||
int i, j;
|
||||
for (i = 1; i <= RING; i++) {
|
||||
for (j = 1; j < SEAT / 2; j++) {
|
||||
ch = board[i*SEAT + j];
|
||||
board[i*SEAT + j] = board[(i + 1)*SEAT - j];
|
||||
board[(i + 1)*SEAT - j] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t p1, p2, p3;
|
||||
if (move_ < 0) {
|
||||
i = (-move_) / SEAT;
|
||||
j = (-move_) % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
move_ = -(i * SEAT + j);
|
||||
}
|
||||
else {
|
||||
p1 = move_ >> 8;
|
||||
p2 = move_ & 0x00ff;
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p1 = i * SEAT + j;
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p2 = i * SEAT + j;
|
||||
move_ = (p1 << 8) | p2;
|
||||
}
|
||||
|
||||
i = currentPos / SEAT;
|
||||
j = currentPos % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
currentPos = i * SEAT + j;
|
||||
|
||||
if (rule.canRepeated) {
|
||||
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
|
||||
p1 = (*mill & 0x000000ff00000000) >> 32;
|
||||
p2 = (*mill & 0x0000000000ff0000) >> 16;
|
||||
p2 = (*mill & 0x00000000000000ff);
|
||||
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p1 = i * SEAT + j;
|
||||
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p2 = i * SEAT + j;
|
||||
|
||||
i = p3 / SEAT;
|
||||
j = p3 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p3 = i * SEAT + j;
|
||||
|
||||
*mill &= 0xffffff00ff00ff00;
|
||||
*mill |= (p1 << 32) | (p2 << 16) | p3;
|
||||
}
|
||||
}
|
||||
|
||||
// 命令行解析
|
||||
if (cmdChange) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void NineChess::turn(bool cmdChange /*= true*/)
|
||||
{
|
||||
char ch;
|
||||
int i, j;
|
||||
for (i = 0; i < SEAT; i++) {
|
||||
ch = board[SEAT + i];
|
||||
board[SEAT + i] = board[SEAT*RING + i];
|
||||
board[SEAT*RING + i] = ch;
|
||||
}
|
||||
|
||||
int16_t p1, p2, p3;
|
||||
|
||||
if (move_ < 0) {
|
||||
i = (-move_) / SEAT;
|
||||
j = (-move_) % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
move_ = -(i * SEAT + j);
|
||||
}
|
||||
else {
|
||||
p1 = move_ >> 8;
|
||||
p2 = move_ & 0x00ff;
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p1 = i * SEAT + j;
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p2 = i * SEAT + j;
|
||||
move_ = (p1 << 8) | p2;
|
||||
}
|
||||
|
||||
i = currentPos / SEAT;
|
||||
j = currentPos % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
currentPos = i * SEAT + j;
|
||||
|
||||
if (rule.canRepeated) {
|
||||
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
|
||||
p1 = (*mill & 0x000000ff00000000) >> 32;
|
||||
p2 = (*mill & 0x0000000000ff0000) >> 16;
|
||||
p2 = (*mill & 0x00000000000000ff);
|
||||
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p1 = i * SEAT + j;
|
||||
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p2 = i * SEAT + j;
|
||||
|
||||
i = p3 / SEAT;
|
||||
j = p3 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p3 = i * SEAT + j;
|
||||
|
||||
*mill &= 0xffffff00ff00ff00;
|
||||
*mill |= (p1 << 32) | (p2 << 16) | p3;
|
||||
}
|
||||
}
|
||||
|
||||
// 命令行解析
|
||||
if (cmdChange) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
||||
{
|
||||
// 将degrees转化为0~359之间的数
|
||||
degrees = degrees % 360;
|
||||
if (degrees < 0)
|
||||
degrees += 360;
|
||||
|
||||
if (degrees != 90 || degrees != 180 || degrees != 270)
|
||||
return;
|
||||
else
|
||||
degrees /= 45;
|
||||
|
||||
char ch;
|
||||
int i, j;
|
||||
for (i = 0; i < SEAT; i++) {
|
||||
ch = board[SEAT + i];
|
||||
board[SEAT + i] = board[SEAT*RING + i];
|
||||
board[SEAT*RING + i] = ch;
|
||||
}
|
||||
|
||||
int16_t p1, p2, p3;
|
||||
|
||||
if (move_ < 0) {
|
||||
i = (-move_) / SEAT;
|
||||
j = (-move_) % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
move_ = -(i * SEAT + j);
|
||||
}
|
||||
else {
|
||||
p1 = move_ >> 8;
|
||||
p2 = move_ & 0x00ff;
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p1 = i * SEAT + j;
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p2 = i * SEAT + j;
|
||||
move_ = (p1 << 8) | p2;
|
||||
}
|
||||
|
||||
i = currentPos / SEAT;
|
||||
j = currentPos % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
currentPos = i * SEAT + j;
|
||||
|
||||
if (rule.canRepeated) {
|
||||
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
|
||||
p1 = (*mill & 0x000000ff00000000) >> 32;
|
||||
p2 = (*mill & 0x0000000000ff0000) >> 16;
|
||||
p2 = (*mill & 0x00000000000000ff);
|
||||
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p1 = i * SEAT + j;
|
||||
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p2 = i * SEAT + j;
|
||||
|
||||
i = p3 / SEAT;
|
||||
j = p3 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p3 = i * SEAT + j;
|
||||
|
||||
*mill &= 0xffffff00ff00ff00;
|
||||
*mill |= (p1 << 32) | (p2 << 16) | p3;
|
||||
}
|
||||
}
|
||||
|
||||
// 命令行解析
|
||||
if (cmdChange) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
ACTION_CAPTURE = 0x0400 // 提子
|
||||
};
|
||||
|
||||
// 棋局结构体,包含当前棋盘数据
|
||||
// 棋局结构体,算法相关,包含当前棋盘数据
|
||||
// 单独分离出来供AI判断局面用,生成置换表时使用
|
||||
struct ChessData {
|
||||
// 棋局,抽象为一个(5×8)的char数组,上下两行留空
|
||||
|
@ -222,21 +222,23 @@ public:
|
|||
bool reset();
|
||||
// 游戏开始
|
||||
bool start();
|
||||
|
||||
// 选子,在第c圈第p个位置,为迎合日常,c和p下标都从1开始
|
||||
bool choose(int c, int p);
|
||||
// 落子,在第c圈第p个位置,为迎合日常,c和p下标都从1开始
|
||||
bool place(int c, int p, long time_p = -1);
|
||||
// 去子,在第c圈第p个位置,为迎合日常,c和p下标都从1开始
|
||||
bool capture(int c, int p, long time_p = -1);
|
||||
// 下面3个函数没有算法无关判断和无关操作
|
||||
bool choose(int pos);
|
||||
bool place(int pos);
|
||||
bool capture(int pos);
|
||||
// 认输
|
||||
bool giveup(Players loser);
|
||||
// 命令行解析函数
|
||||
bool command(int16_t move);
|
||||
bool command(const char *cmd);
|
||||
// 局面左右镜像
|
||||
void mirror(bool cmdChange = true);
|
||||
// 局面内外翻转
|
||||
void turn(bool cmdChange = true);
|
||||
// 局面顺时针旋转
|
||||
void rotate(int degrees, bool cmdChange = true);
|
||||
|
||||
protected:
|
||||
// 判断棋盘pos处的棋子处于几个“三连”中
|
||||
|
@ -266,6 +268,12 @@ protected:
|
|||
// 设置提示
|
||||
void setTip();
|
||||
|
||||
// 下面几个函数没有算法无关判断和无关操作,节约算法时间
|
||||
bool command(int16_t move);
|
||||
bool choose(int pos);
|
||||
bool place(int pos);
|
||||
bool capture(int pos);
|
||||
|
||||
private:
|
||||
// 当前使用的规则
|
||||
struct Rule rule;
|
||||
|
|
|
@ -120,9 +120,10 @@ void NineChessAi_ab::buildChildren(Node *node)
|
|||
void NineChessAi_ab::sortChildren(Node *node)
|
||||
{
|
||||
// 这个函数对效率的影响很大,排序好的话,剪枝较早,节省时间,但不能在此函数耗费太多时间
|
||||
// 先赋初值,初始值不会影响alpha-beta剪枝
|
||||
// 这里我用一个随机排序,使AI不至于每次走招相同
|
||||
srand((unsigned)time(0));
|
||||
for (auto i : node->children) {
|
||||
i->value = evaluate(node);
|
||||
i->value = rand();
|
||||
}
|
||||
// 排序
|
||||
if(chessTemp.whosTurn() == NineChess::PLAYER1)
|
||||
|
|
|
@ -57,20 +57,6 @@ NineChessWindow::NineChessWindow(QWidget *parent)
|
|||
ui.actionInternet_I->setDisabled(true);
|
||||
ui.actionSetting_O->setDisabled(true);
|
||||
|
||||
// 关联既有动作信号和主窗口槽
|
||||
// 视图上下翻转
|
||||
connect(ui.actionFlip_F, &QAction::triggered,
|
||||
ui.gameView, &GameView::flip);
|
||||
// 视图左右镜像
|
||||
connect(ui.actionMirror_M, &QAction::triggered,
|
||||
ui.gameView, &GameView::mirror);
|
||||
// 视图须时针旋转90°
|
||||
connect(ui.actionTurnRight_R, &QAction::triggered,
|
||||
ui.gameView, &GameView::turnRight);
|
||||
// 视图逆时针旋转90°
|
||||
connect(ui.actionTurnLeftt_L, &QAction::triggered,
|
||||
ui.gameView, &GameView::turnLeft);
|
||||
|
||||
// 初始化游戏规则菜单
|
||||
ui.menu_R->installEventFilter(this);
|
||||
|
||||
|
@ -167,6 +153,19 @@ void NineChessWindow::initialize()
|
|||
connect(ui.actionAnimation_A, SIGNAL(toggled(bool)),
|
||||
game, SLOT(setAnimation(bool)));
|
||||
|
||||
// 视图上下翻转
|
||||
connect(ui.actionFlip_F, &QAction::triggered,
|
||||
game, &GameController::flip);
|
||||
// 视图左右镜像
|
||||
connect(ui.actionMirror_M, &QAction::triggered,
|
||||
game, &GameController::mirror);
|
||||
// 视图须时针旋转90°
|
||||
connect(ui.actionTurnRight_R, &QAction::triggered,
|
||||
game, &GameController::turnRight);
|
||||
// 视图逆时针旋转90°
|
||||
connect(ui.actionTurnLeftt_L, &QAction::triggered,
|
||||
game, &GameController::turnLeft);
|
||||
|
||||
// 关联控制器的信号和主窗口控件的槽
|
||||
// 更新LCD1,显示玩家1用时
|
||||
connect(game, SIGNAL(time1Changed(QString)),
|
||||
|
|
Loading…
Reference in New Issue