//--------------------------------------------------------------------------- // Algo d'exploration : MiniMax //--------------------------------------------------------------------------- public int MiniMax(int depth, int alpha, int beta) { //Double liste contenant tous les coups possibles List <List <string> > allMoves = new List <List <string> >(); int[] posPiece = new int[2]; int[] posMove = new int[2]; int valPiece = 0; //obligation de l'initialiser... int valMove; bool originList = true; //permet de changer l'origine de la pièce quand on change de liste de coups string originMove = ""; //Condition d'arrêt (profondeur limite fixée) if (depth == 0) { return(echiquier.evaluateBoard()); } //Récupérer tous les moves possibles allMoves = echiquier.GetAllMoves(); //Max ou Min joueur if (echiquier.GetColorIA()) { int bestValue = -9999; foreach (var liste in allMoves) { foreach (var move in liste) { //1er element de la liste = origine des coups suivants if (originList) { originMove = move; posPiece = echiquier.GetPosPiece(move); valPiece = echiquier.GetTabEval(posPiece[0], posPiece[1]); originList = false; } //Autres éléments de la liste else { posMove = echiquier.GetPosPiece(move); valMove = echiquier.GetTabEval(posMove[0], posMove[1]); //do move echiquier.SetTabEval(posPiece[0], posPiece[1], 0); //ancienne pos piece = 0 echiquier.SetTabEval(posMove[0], posMove[1], valPiece); //nouvelle pos piece = move //MiniMax récursif if (depth - 1 != 0) { echiquier.SetColorIA(!echiquier.GetColorIA()); //empecher le changement de tour lors de la prof max } //Profondeur initiale = garde le meilleur coup if (depth == 3) { int testMaxValue = MiniMax(depth - 1, alpha, beta); alpha = Math.Max(alpha, testMaxValue); if (bestValue < testMaxValue) { bestValue = testMaxValue; bestMove[0] = originMove; bestMove[1] = move; } } //Autres profondeurs = on s'intérèsse juste à la max value else { bestValue = Math.Max(bestValue, MiniMax(depth - 1, alpha, beta)); alpha = Math.Max(alpha, bestValue); if (beta <= alpha) { //undo move echiquier.SetTabEval(posPiece[0], posPiece[1], valPiece); //on remet val piece à l'état de départ echiquier.SetTabEval(posMove[0], posMove[1], valMove); //on remet le move à l'état de départ echiquier.SetColorIA(!echiquier.GetColorIA()); return(bestValue); } } //undo move echiquier.SetTabEval(posPiece[0], posPiece[1], valPiece); //on remet val piece à l'état de départ echiquier.SetTabEval(posMove[0], posMove[1], valMove); //on remet le move à l'état de départ } } originList = true; } echiquier.SetColorIA(!echiquier.GetColorIA()); return(bestValue); } else { int bestValue = 9999; foreach (var liste in allMoves) { foreach (var move in liste) { //1er element de la liste = origine des coups suivants if (originList) { originMove = move; posPiece = echiquier.GetPosPiece(move); valPiece = echiquier.GetTabEval(posPiece[0], posPiece[1]); originList = false; } //Autres éléments de la liste else { posMove = echiquier.GetPosPiece(move); valMove = echiquier.GetTabEval(posMove[0], posMove[1]); //do move echiquier.SetTabEval(posPiece[0], posPiece[1], 0); //ancienne pos piece = 0 echiquier.SetTabEval(posMove[0], posMove[1], valPiece); //nouvelle pos piece = moves //MiniMax récursif if (depth - 1 != 0) { echiquier.SetColorIA(!echiquier.GetColorIA()); } bestValue = Math.Min(bestValue, MiniMax(depth - 1, alpha, beta)); beta = Math.Min(beta, bestValue); if (beta <= alpha) { //undo move echiquier.SetTabEval(posPiece[0], posPiece[1], valPiece); //on remet val piece à l'état de départ echiquier.SetTabEval(posMove[0], posMove[1], valMove); //on remet le move à l'état de départ echiquier.SetColorIA(!echiquier.GetColorIA()); return(bestValue); } //undo move echiquier.SetTabEval(posPiece[0], posPiece[1], valPiece); //on remet val piece à l'état de départ echiquier.SetTabEval(posMove[0], posMove[1], valMove); //on remet le move à l'état de départ } } originList = true; } echiquier.SetColorIA(!echiquier.GetColorIA()); return(bestValue); } }