Beispiel #1
0
// 点击格子事件处理
static void ClickSquare(int sq) {
  int pc;
  Xqwl.hdc = GetDC(Xqwl.hWnd);
  Xqwl.hdcTmp = CreateCompatibleDC(Xqwl.hdc);
  sq = Xqwl.bFlipped ? SQUARE_FLIP(sq) : sq;
  pc = pos.ucpcSquares[sq];

  if ((pc & SIDE_TAG(pos.sdPlayer)) != 0) {
    // 如果点击自己的子,那么直接选中该子
    if (Xqwl.sqSelected != 0) {
      DrawSquare(Xqwl.sqSelected);
    }
    Xqwl.sqSelected = sq;
    DrawSquare(sq, DRAW_SELECTED);
    if (Xqwl.mvLast != 0) {
      DrawSquare(SRC(Xqwl.mvLast));
      DrawSquare(DST(Xqwl.mvLast));
    }
    PlayResWav(IDR_CLICK); // 播放点击的声音

  } else if (Xqwl.sqSelected != 0) {
    // 如果点击的不是自己的子,但有子选中了(一定是自己的子),那么走这个子
    Xqwl.mvLast = MOVE(Xqwl.sqSelected, sq);
    pos.MakeMove(Xqwl.mvLast);
    DrawSquare(Xqwl.sqSelected, DRAW_SELECTED);
    DrawSquare(sq, DRAW_SELECTED);
    Xqwl.sqSelected = 0;
    PlayResWav(pc == 0 ? IDR_MOVE : IDR_CAPTURE); // 播放走子或吃子的声音
  }
  DeleteDC(Xqwl.hdcTmp);
  ReleaseDC(Xqwl.hWnd, Xqwl.hdc);
}
Beispiel #2
0
void BuildPos(PositionStruct &pos, const UcciCommStruct &UcciComm) {
  int i, mv;
  pos.FromFen(UcciComm.szFenStr);
  for (i = 0; i < UcciComm.nMoveNum; i ++) {
    mv = COORD_MOVE(UcciComm.lpdwMovesCoord[i]);
    if (mv == 0) {
      break;
    }
    if (pos.LegalMove(mv) && pos.MakeMove(mv) && pos.LastMove().CptDrw > 0) {
      // 始终让pos.nMoveNum反映没吃子的步数
      pos.SetIrrev();
    }
  }
}
Beispiel #3
0
void BuildPos(PositionStruct &pos, const UcciCommStruct &UcciComm) {
    int i, mv;
    pos.FromFen(UcciComm.szFenStr);
    for (i = 0; i < UcciComm.nMoveNum; i ++) {
        mv = COORD_MOVE(UcciComm.lpdwMovesCoord[i]);
        if (mv == 0) {
            break;
        }
        if (pos.ucpcSquares[SRC(mv)] == 0) {
            break;
        }
        pos.MakeMove(mv);
    }
}
Beispiel #4
0
// 检测下一个着法是否稳定,有助于减少置换表的不稳定性
inline bool MoveStable(PositionStruct &pos, int mv) {
  // 判断下一个着法是否稳定的依据是:
  // 1. 没有后续着法,则假定是稳定的;
  if (mv == 0) {
    return true;
  }
  // 2. 吃子着法是稳定的;
  __ASSERT(pos.LegalMove(mv));
  if (pos.ucpcSquares[DST(mv)] != 0) {
    return true;
  }
  // 3. 可能因置换表引起路线迁移,使得路线超过"MAX_MOVE_NUM",此时应立刻终止路线,并假定是稳定的。
  if (!pos.MakeMove(mv)) {
    return true;
  }
  return false;
}
Beispiel #5
0
// 尝试某个着法,并返回着法状态,参阅"cchess.h"
bool TryMove(PositionStruct &pos, int &nStatus, int mv) {
  if (!pos.LegalMove(mv)) {
    nStatus = MOVE_ILLEGAL;
    return false;
  }
  if (!pos.MakeMove(mv)) {
    nStatus = MOVE_INCHECK;
    return false;
  }
  nStatus = 0;
  nStatus += (pos.LastMove().CptDrw > 0 ? MOVE_CAPTURE : 0);
  nStatus += (pos.LastMove().ChkChs > 0 ? MOVE_CHECK : 0);
  nStatus += (pos.IsMate() ? MOVE_MATE : 0);
  nStatus += pos.RepStatus(3) * MOVE_PERPETUAL; // 提示:参阅"position.cpp"中的"IsRep()"函数
  nStatus += (pos.IsDraw() ? MOVE_DRAW : 0);
  pos.UndoMakeMove();
  return true;
}
Beispiel #6
0
int Node::playRollout(){
	PositionStruct p = pos;
	int player = p.sdPlayer;
	int k = K;
	int mv[128];
	int i;
	for (i = 0; i < k; i++){
		mv[k] = move[k];
	}
	while (1){
		p.MakeMove(mv[ppi(pos2fen(&p), k, mv)]);
		genMove(&p, k, mv);
		if (k == 0){ //无子可走被将死
			if (p.sdPlayer == player){ //自己被将死
				return 0;
			}
			else{
				return 1;
			}
		}
	}
}
Beispiel #7
0
// 静态搜索例程
static int SearchQuiesc(PositionStruct &pos, int vlAlpha, int vlBeta) {
  int vlBest, vl, mv;
  bool bInCheck;
  MoveSortStruct MoveSort;  
  // 静态搜索例程包括以下几个步骤:
  Search2.nAllNodes ++;

  // 1. 无害裁剪;
  vl = HarmlessPruning(pos, vlBeta);
  if (vl > -MATE_VALUE) {
    return vl;
  }

#ifdef HASH_QUIESC
  // 3. 置换裁剪;
  vl = ProbeHashQ(pos, vlAlpha, vlBeta);
  if (Search.bUseHash && vl > -MATE_VALUE) {
    return vl;
  }
#endif

  // 4. 达到极限深度,直接返回评价值;
  if (pos.nDistance == LIMIT_DEPTH) {
    return Evaluate(pos, vlAlpha, vlBeta);
  }
  __ASSERT(Search.pos.nDistance < LIMIT_DEPTH);

  // 5. 初始化;
  vlBest = -MATE_VALUE;
  bInCheck = (pos.LastMove().ChkChs > 0);

  // 6. 对于被将军的局面,生成全部着法;
  if (bInCheck) {
    MoveSort.InitAll(pos);
  } else {

    // 7. 对于未被将军的局面,在生成着法前首先尝试空着(空着启发),即对局面作评价;
    vl = Evaluate(pos, vlAlpha, vlBeta);
    __ASSERT_BOUND(1 - WIN_VALUE, vl, WIN_VALUE - 1);
    __ASSERT(vl > vlBest);
    if (vl >= vlBeta) {
#ifdef HASH_QUIESC
      RecordHashQ(pos, vl, MATE_VALUE);
#endif
      return vl;
    }
    vlBest = vl;
    vlAlpha = MAX(vl, vlAlpha);

    // 8. 对于未被将军的局面,生成并排序所有吃子着法(MVV(LVA)启发);
    MoveSort.InitQuiesc(pos);
  }

  // 9. 用Alpha-Beta算法搜索这些着法;
  while ((mv = MoveSort.NextQuiesc(bInCheck)) != 0) {
    __ASSERT(bInCheck || pos.ucpcSquares[DST(mv)] > 0);
    if (pos.MakeMove(mv)) {
      vl = -SearchQuiesc(pos, -vlBeta, -vlAlpha);
      pos.UndoMakeMove();
      if (vl > vlBest) {
        if (vl >= vlBeta) {
#ifdef HASH_QUIESC
          if (vl > -WIN_VALUE && vl < WIN_VALUE) {
            RecordHashQ(pos, vl, MATE_VALUE);
          }
#endif
          return vl;
        }
        vlBest = vl;
        vlAlpha = MAX(vl, vlAlpha);
      }
    }
  }

  // 10. 返回分值。
  if (vlBest == -MATE_VALUE) {
    __ASSERT(pos.IsMate());
    return pos.nDistance - MATE_VALUE;
  } else {
#ifdef HASH_QUIESC
    if (vlBest > -WIN_VALUE && vlBest < WIN_VALUE) {
      RecordHashQ(pos, vlBest > vlAlpha ? vlBest : -MATE_VALUE, vlBest);
    }
#endif
    return vlBest;
  }
}
Beispiel #8
0
// 静态搜索
int SearchQuiesc ( int alpha, int beta ) {
	int mv, vl;
	int bvl = - MATE_VALUE;
	MoveSortStruct mvsort;

	if ( TimeOut() ) { // 超时
		return bvl;
	}

	// 无害裁剪
	vl = HarmlessPruning ();
	if ( vl > - MATE_VALUE ) {
		return vl;
	}

	// 置换裁剪
	vl = QueryValueInHashTableQC ( alpha, beta );
	if ( vl > - MATE_VALUE ) {
		return vl;
	}

	// 生成着法
	if ( pos.checked ) {
		mvsort.InitMove ();
	}
	else {
		bvl = pos.Evaluate ();
		if ( bvl >= beta ) {
			InsertInfoToHashTableQC ( bvl, MATE_VALUE );
			return bvl;
		}
		if ( bvl > alpha ) {
			alpha = bvl;
		}
		mvsort.InitGoodCapMove ();
	}

	// 大搜索
	while ( (mv = mvsort.NextMove()) != 0 ) {
		pos.MakeMove (mv);
		vl = - SearchQuiesc ( -beta, -alpha );
		pos.UndoMakeMove ();

		if ( TimeOut() ) { // 超时
			return bvl;
		}

		if ( vl > bvl ) {
			bvl = vl;
			if ( bvl >= beta ) {
				if ( bvl > - BAN_VALUE && bvl < BAN_VALUE ) {
					InsertInfoToHashTableQC ( bvl, MATE_VALUE );
				}
				return vl;
			}
			if ( bvl > alpha ) {
				alpha = bvl;
			}
		}
	}

	// 最后
	if ( bvl > - BAN_VALUE && bvl < BAN_VALUE ) {
		InsertInfoToHashTableQC ( bvl, bvl );
	}
	return bvl;
}
Beispiel #9
0
// Alpha-Beta 搜索
int SearchAlphaBeta ( int depth, int alpha, int beta ) {
	int mv, vl;
	int bmv[nBest], bvl[nBest];
	ClearBmvBvl ( bmv, bvl );
	int hash_type = HASH_TYPE_ALPHA;
	MoveSortStruct mvsort;

	if ( TimeOut() ) { // 超时
		return bvl[0];
	}

	// 无害裁剪
	vl = HarmlessPruning ();
	if ( vl > - MATE_VALUE ) {
		return vl;
	}

	// 置换裁剪
	vl = QueryValueInHashTable ( depth, alpha, beta );
	if ( vl > - MATE_VALUE ) {
		Search.bmv[0] = QueryMoveInHashTable ( depth, alpha, beta );
		Search.bvl[0] = vl;
		return vl;
	}

	// 达到极限深度
	if ( depth <= 0 ) {
		return SearchQuiesc ( alpha, beta );
	}

	// 内部迭代加深启发
	if ( depth > 2 ) {
		mv = QueryMoveInHashTableWithoutLimit ();
		if ( mv == 0 ) {
			SearchAlphaBeta ( depth / 2, alpha, beta );
			if ( TimeOut() ) { // 超时
				return bvl[0];
			}
		}
	}

	// 生成着法
	int nMoveNum = mvsort.InitMove ();
	Search.nNode ++;

	// 大搜索
	while ( (mv = mvsort.NextMove()) != 0 ) {
		pos.MakeMove ( mv );
		int newDepth = ( pos.checked || nMoveNum == 1 ) ? depth : depth - 1;
		vl = - SearchCut ( newDepth, - alpha );
		if ( vl > alpha && vl < beta ) {
			vl = - SearchAlphaBeta ( newDepth, -beta, -alpha );
		}
		pos.UndoMakeMove ();

		if ( TimeOut() ) {
			return bvl[0];
		}

		UpdateBmvBvl ( bmv, bvl, mv, vl );

		if ( bvl[0] >= beta ) {
			Search.nBeta ++;
			hash_type = HASH_TYPE_BETA;
			break;
		}
		if ( bvl[0] > alpha ) {
			alpha = bvl[0];
			hash_type = HASH_TYPE_PV;
		}
	}

	// 最后
	InsertInfoToHashTable ( depth, bmv[0], bvl[0], hash_type );
	InsertHistoryTable ( bmv[0], depth );
	CopyBmvBvl ( Search.bmv, Search.bvl, bmv, bvl );
	return bvl[0];
}
Beispiel #10
0
// 零窗口搜索
int SearchCut ( int depth, int beta, bool bNoNull = false ) {
	int mv, vl;
	int bmv = 0;
	int bvl = - MATE_VALUE;
	MoveSortStruct mvsort;

	if ( TimeOut() ) { // 超时
		return bvl;
	}

	// 无害裁剪
	vl = HarmlessPruning ();
	if ( vl > - MATE_VALUE ) {
		return vl;
	}

	// 置换裁剪
	vl = QueryValueInHashTable ( depth, beta - 1, beta );
	if ( vl > - MATE_VALUE ) {
		return vl;
	}

	// 达到极限深度
	if ( depth <= 0 ) {
		return SearchQuiesc ( beta - 1, beta );
	}

	// 空着裁剪 : 大切に
	if ( !bNoNull && pos.checked == false && pos.NullOkay() ) {
		pos.NullMove ();
		vl = - SearchCut ( depth - NULL_DEPTH - 1, beta, true );
		pos.UndoNullMove ();
		if ( TimeOut() ) { // 超时
			return bvl;
		}

		if ( vl >= beta ) {
			if ( pos.NullSafe() ) {
				InsertInfoToHashTable ( MAX(depth, NULL_DEPTH + 1), 0, vl, HASH_TYPE_BETA );
				return vl;
			}
			else if ( SearchCut(depth - NULL_DEPTH, beta, true) >= beta ) {
				InsertInfoToHashTable ( MAX(depth, NULL_DEPTH), 0, vl, HASH_TYPE_BETA );
				return vl;
			}
		}
	}

	// 生成着法
	int nMoveNum = mvsort.InitMove ();
	Search.nNode ++;

	// 大搜索
	while ( (mv = mvsort.NextMove()) != 0 ) {
		pos.MakeMove ( mv );
		int newDepth = ( pos.checked || nMoveNum == 1 ) ? depth : depth - 1;
		vl = - SearchCut ( newDepth, 1 - beta );
		pos.UndoMakeMove ();

		if ( TimeOut() ) { // 超时
			return bvl;
		}

		// 边界
		if ( vl > bvl ) {
			bvl = vl;
			bmv = mv;
			if ( bvl >= beta ) {
				Search.nBeta ++;
				InsertInfoToHashTable ( depth, bmv, bvl, HASH_TYPE_BETA );
				InsertHistoryTable ( bmv, depth );
				return bvl;
			}
		}
	}

	// 最后
	InsertInfoToHashTable ( depth, bmv, bvl, HASH_TYPE_ALPHA );
	return bvl;
}