//return move private int CalculateNextMove(bool firstPlayer, bool turnPlayer, int level, int maxLevel, ref int alpha, ref int beta, Board board) { //its just on max level if (level == maxLevel) { return(CalculateCurrentBoard(turnPlayer, board)); } int localAlpha = alpha; int localBeta = beta; int bestResult = firstPlayer == turnPlayer ? int.MinValue : int.MaxValue; int result = 0; int bestMove = 0; for (int i = 0; i < board.NumberOfColumns; i++) { Board locBoard = board.Clone(); bool? win = false; bool put = false; if (locBoard.PutToken(i)) { if (locBoard.Result == Result.Draw) { win = null; } else if (locBoard.Result == Result.None) { win = false; } else { win = true; } put = true; //time to go back in tree if (win != false || level == maxLevel) { if (win == true) { result = firstPlayer == turnPlayer ? int.MaxValue : int.MinValue; } //draw, so calculate result for turnPlayer else if (win == null) { result = 0; } } //go deeper else { //increase in case of next starting (turn) player if (firstPlayer == turnPlayer) { level++; } result = CalculateNextMove(!firstPlayer, turnPlayer, level, maxLevel, ref alpha, ref beta, locBoard); } } if (!put) { continue; } //there was minimize, so beta is new if (firstPlayer == turnPlayer) { //now we want to maximize if (result > bestResult) { bestResult = result; if (alpha < bestResult) { alpha = bestResult; } bestMove = i; } if (win == false) { level--; } if (alpha == int.MaxValue || alpha >= localBeta) { break; } beta = localBeta; } else { //minimize if (result < bestResult) { bestResult = result; if (beta > bestResult) { beta = bestResult; } bestMove = i; } if (beta == int.MinValue || beta <= localAlpha) { break; } alpha = localAlpha; } } return((level == 0 && firstPlayer == turnPlayer) ? bestMove : bestResult); }