private lineAndScore findBestMove(bool usToPlay, int depthLeft) { lineAndScore bestLineSoFar; if (usToPlay) bestLineSoFar = new lineAndScore(new move[searchDepth + 1], int.MinValue, null); else bestLineSoFar = new lineAndScore(new move[searchDepth + 1], int.MaxValue, null); // Find a list of possible moves.. sizableArray<move> movesToConsider = getMoves(colToMove); foreach (move consideredMove in movesToConsider) { pieceColour movingCol = colToMove; doMove(consideredMove); // If this move would leave us in check, we can ignore it // TODO: optimise this. if (isPlayerInCheck(movingCol)) { undoMove(consideredMove); continue; } if (depthLeft == 0) { boardScorer scorer = new boardScorer(this, movingCol); int score = scorer.getScore(); if ((usToPlay && (score > bestLineSoFar.finalScore)) || (!usToPlay && (score < bestLineSoFar.finalScore))) { bestLineSoFar.finalScore = score; bestLineSoFar.line[searchDepth] = consideredMove; bestLineSoFar._scorer = scorer; } } else { lineAndScore thisMove = findBestMove(!usToPlay, depthLeft - 1); if ((usToPlay && (thisMove.finalScore > bestLineSoFar.finalScore)) || (!usToPlay && (thisMove.finalScore < bestLineSoFar.finalScore))) { bestLineSoFar.finalScore = thisMove.finalScore; bestLineSoFar._scorer = thisMove._scorer; bestLineSoFar.line[searchDepth - depthLeft] = consideredMove; for (int index = 0; index < thisMove.line.Length; index++) { if (thisMove.line[index] != null) bestLineSoFar.line[index] = thisMove.line[index]; } } } undoMove(consideredMove); } return bestLineSoFar; }
private void findBestMoveWithTimeoutThread() { try { bestLine = findBestMoveBoard.findBestMove(); } catch (Exception newEx) { ex = newEx; evnt.Set(); return; } evnt.Set(); }