/* * ChessDlgShowGameStatus: Display a message giving state of game * (stalemate, checkmate, etc.) * Return True iff any message was displayed. */ void ChessDlgShowGameStatus(void) { if (hChessDlg == NULL) return; b.game_over = False; // Give a message for various situations if (b.white_resigned) { ChessDlgShowMessage(GetString(hInst, IDS_WHITERESIGN)); b.game_over = True; } else if (b.black_resigned) { ChessDlgShowMessage(GetString(hInst, IDS_BLACKRESIGN)); b.game_over = True; } else if (!HasLegalMove(&b, b.move_color)) { // Give a message if checkmated if (IsInCheck(&b, b.move_color)) ChessDlgShowMessage(GetString(hInst, IDS_CHECKMATE)); else ChessDlgShowMessage(GetString(hInst, IDS_STALEMATE)); b.game_over = True; } else if (IsInCheck(&b, b.move_color)) { ChessDlgShowMessage(GetString(hInst, IDS_CHECK)); } else ChessDlgShowMessage(""); // Observers can't reset game EnableWindow(GetDlgItem(hChessDlg, IDC_RESTART_GAME), b.game_over && (b.color != OBSERVER)); EnableWindow(GetDlgItem(hChessDlg, IDC_RESETPLAYERS), b.game_over && (b.color != OBSERVER)); EnableWindow(GetDlgItem(hChessDlg, IDC_RESIGN), !b.game_over && (b.color != OBSERVER)); }
/* * ChessMoveIsLegal: Return True iff the move from p1 to p2 is legal for the player * of the given color. * Assumes that p1 contains a piece of the player's color. */ Bool ChessMoveIsLegal(Board *b, POINT p1, POINT p2, BYTE color) { Board new_board; if (!PieceCanMove(b, p1, p2, color)) return False; // Move must not leave king in check -- see if king attacked after move performed memcpy(&new_board, b, sizeof(Board)); ChessMovePerform(&new_board, p1, p2, False); if (IsInCheck(&new_board, color)) return False; return True; }
int Search (int alpha, int beta, int depth, MOVE * pBestMove, LINE * pline) { /* Vars deffinition */ int i; int value; /* To store the evaluation */ int havemove; /* Either we have or not a legal move available */ int movecnt; /* The number of available moves */ // int score; MOVE moveBuf[200]; /* List of movements */ MOVE tmpMove; LINE line; nodes++; countSearchCalls++; /* Do some housekeeping every 1024 nodes */ if ((nodes & 1023) == 0) checkup(stop_time); if (must_stop) return 0; havemove = 0; /* is there a move available? */ pBestMove->type_of_move = MOVE_TYPE_NONE; /* If we are in a leaf node we cal quiescence instead of eval */ if (depth == 0) { pline->cmove = 0; return Quiescent(alpha, beta); /* Uncomment nest line if want to make tests avoiding qsearch */ //return Eval(alpha, beta); } /* If we're in check we want to search deeper */ if (IsInCheck(side)) ++depth; /* Static null move prunning */ if (ply && !IsInCheck(side)) { int ev = Eval(-MATE, MATE); int evalua = ev - 150; if (evalua >= beta) return beta; } /* Generate and count all moves for current position */ movecnt = GenMoves (side, moveBuf); /* Once we have all the moves available, we loop through the posible * moves and apply an alpha-beta search */ for (i = 0; i < movecnt; ++i) { /* Here must be called OrderMove, so we have the moves are ordered before picking one up from the list*/ MoveOrder(i, movecnt, moveBuf); /* If the current move isn't legal, we take it back * and take the next move in the list */ if (!MakeMove (moveBuf[i])) { TakeBack (); continue; } /* If we've reached this far, then we have a move available */ havemove = 1; value = -Search(-beta, -alpha, depth - 1, &tmpMove, &line); /* We've evaluated the position, so we return to the previous position in such a way that when we take the next move from moveBuf everything is in order */ TakeBack (); /* Once we have an evaluation, we use it in in an alpha-beta search */ if (value > alpha) { /* Este movimiento causo un cutoff, asi que incrementamos el valor de historia para que sea ordenado antes la proxima vez que se busque */ history[moveBuf[i].from][moveBuf[i].dest] += depth; /* This move is so good and caused a cutoff */ if (value >= beta) { return beta; } alpha = value; /* So far, current move is the best reaction for current position */ *pBestMove = moveBuf[i]; /* Update the principal line */ pline->argmove[0] = moveBuf[i]; memcpy(pline->argmove + 1, line.argmove, line.cmove * sizeof(MOVE)); pline->cmove = line.cmove + 1; } } /* Once we've checked all the moves, if we have no legal moves, * then that's checkmate or stalemate */ if (!havemove) { if (IsInCheck (side)) return -MATE + ply; /* add ply to find the longest path to lose or shortest path to win */ else return 0; } /* 3 vecez la misma posicion */ if (reps() >= 2) return 0; if (fifty >= 100) /* 50 jugadas o mas */ return 0; /* Finally we return alpha, the score value */ return alpha; }