public int Negamax(int depth, int alpha, int beta, bool estBlancTour) { if (depth == 0) { return(Evaluer(estBlancTour)); } if (EstTermine()) { return(int.MinValue + 10); } GetMouvementsPossibles(estBlancTour, out List <Mouvement> mouvementsPossibles); PlateauIA tmp; int maxi = int.MinValue; int tmpVal; for (int i = 0; i < mouvementsPossibles.Count; i++) { tmp = new PlateauIA(this); tmp.Effectuer(mouvementsPossibles[i]); tmpVal = -tmp.Negamax(depth - 1, -beta, -alpha, !estBlancTour); maxi = Math.Max(tmpVal, maxi); alpha = Math.Max(tmpVal, alpha); if (alpha >= beta) { break; } } return(maxi); }
private bool EstMinimalementValide(PlateauIA plateau, Coords origine, Coords fin, Coords unitaire, ref int nbPrises, ref PieceIA sautee) { if (!Plateau.EstDansLePlateau(fin)) { return(false); } bool dejaPrise = false; var tmp = origine; PieceIA tmpPiece = null; while (tmp != fin)//on se déplace en diagonale, pas besoin de tout comparer TODO: { tmp += unitaire; tmpPiece = plateau.Get(tmp); if (tmpPiece != null) { if (dejaPrise || tmpPiece.flag) { return(false); } else { dejaPrise = true; sautee = tmpPiece; } if (tmpPiece.EstBlanc == EstBlanc) { return(false); } } } if (tmpPiece == null) { if (dejaPrise) { nbPrises++; } return(true); } return(false); }
private void GetMouvementsPossiblesRec(PlateauIA plateau, Stack <Tuple <int, Mouvement> > possibles, ref Coords origine, Mouvement coups, int nbPrises = 0) { Coords tmpPos; PieceIA tmpPiece; Coords[] directions = GetDirections(); if (coups.Sauts.Count > 0) { possibles.Push(new Tuple <int, Mouvement>(nbPrises, coups)); } for (int i = 0; i < 4; i++) { tmpPos = origine + directions[i]; if (Plateau.EstDansLePlateau(tmpPos)) { tmpPiece = plateau.Get(tmpPos); if (i < 2 && nbPrises == 0)//si le mouvement est vers l'avant, sans prise { if (tmpPiece == null) { var tmp = new Mouvement(coups); tmp.Sauts.Enqueue(tmpPos); possibles.Push(new Tuple <int, Mouvement>(0, tmp)); } } if (tmpPiece != null && tmpPiece.EstBlanc != EstBlanc && !tmpPiece.flag) { tmpPos = tmpPos + directions[i]; if (Plateau.EstDansLePlateau(tmpPos) && plateau.Get(tmpPos) == null) { // flag pour ne pas ressauter des pieces var tmp = new Mouvement(coups); tmp.Sauts.Enqueue(tmpPos); tmpPiece.flag = true; GetMouvementsPossiblesRec(plateau, possibles, ref tmpPos, tmp, nbPrises + 1); tmpPiece.flag = false; } } } } }
public PlateauIA(PlateauIA autre) { Grille = new PieceIA[Plateau.TAILLE, Plateau.TAILLE]; for (int i = 0; i < Plateau.TAILLE; i++) { for (int j = 0; j < Plateau.TAILLE; j++) { if (autre.Grille[i, j] == null) { continue; } if (autre.Grille[i, j] is PionIA) { Grille[i, j] = new PionIA(autre.Grille[i, j].EstBlanc); } else if (autre.Grille[i, j] is DameIA) { Grille[i, j] = new DameIA(autre.Grille[i, j].EstBlanc); } } } }
internal override void MajMouvementsPossibles(PlateauIA plateau, Coords position, ref List <Mouvement> autresMouvements, ref int valeurDesPrecedents) { Stack <Tuple <int, Mouvement> > possibles = new Stack <Tuple <int, Mouvement> >(); GetMouvementsPossiblesRec(plateau, possibles, ref position, new Mouvement(position)); Tuple <int, Mouvement> tmp; while (possibles.Count > 0) { tmp = possibles.Pop(); if (tmp.Item1 > valeurDesPrecedents) { autresMouvements.Clear(); valeurDesPrecedents = tmp.Item1; autresMouvements.Add(tmp.Item2); } else if (tmp.Item1 == valeurDesPrecedents) { autresMouvements.Add(tmp.Item2); } } }
internal abstract void MajMouvementsPossibles(PlateauIA plateau, Coords position, ref List <Mouvement> autresMouvements, ref int valeurDesPrecedents);//prend en compte la piece dans la liste des mouvements possibles
private void GetMouvementsPossiblesRec(PlateauIA plateau, Stack <Tuple <int, Mouvement> > possibles, Mouvement coups, ref Coords origine, Coords directionOrigineDirecteur, int nbPrises = 0) { if (coups.Sauts.Count > 0) { possibles.Push(new Tuple <int, Mouvement>(nbPrises, coups)); } Coords tmpPos = origine; PieceIA tmpPiece = null; Coords direction = directionOrigineDirecteur; int tmpPrises = 0; bool invalideUneFois = false; while (true) { tmpPos += direction; tmpPrises = nbPrises; if (EstMinimalementValide(plateau, origine, tmpPos, direction, ref tmpPrises, ref tmpPiece)) { if (tmpPrises > nbPrises) { tmpPiece.flag = true; var tmpCoups = new Mouvement(coups); tmpCoups.Sauts.Enqueue(tmpPos); GetMouvementsPossiblesRec(plateau, possibles, tmpCoups, ref tmpPos, direction, tmpPrises); tmpPiece.flag = false; } else { var tmpCoups = new Mouvement(coups); tmpCoups.Sauts.Enqueue(tmpPos); possibles.Push(new Tuple <int, Mouvement>(nbPrises, tmpCoups)); } } else { if (invalideUneFois) { invalideUneFois = false; break; } invalideUneFois = true; } } if (directionOrigineDirecteur.GetVraiUnitaire() == DIAG1) { direction = DIAG2; } else { direction = DIAG1; } tmpPos = origine; while (true) { tmpPos += direction; tmpPrises = nbPrises; if (EstMinimalementValide(plateau, origine, tmpPos, direction, ref tmpPrises, ref tmpPiece)) { if (tmpPrises > nbPrises) { var tmpCoups = new Mouvement(coups); tmpCoups.Sauts.Enqueue(tmpPos); tmpPiece.flag = true; GetMouvementsPossiblesRec(plateau, possibles, tmpCoups, ref tmpPos, direction, tmpPrises); tmpPiece.flag = false; } else if (coups.Sauts.Count == 0) { var tmpCoups = new Mouvement(coups); tmpCoups.Sauts.Enqueue(tmpPos); possibles.Push(new Tuple <int, Mouvement>(nbPrises, tmpCoups)); } } else { if (invalideUneFois) { invalideUneFois = false; break; } invalideUneFois = true; } } tmpPos = origine; while (true) { tmpPos -= direction; // la difference est la tmpPrises = nbPrises; if (EstMinimalementValide(plateau, origine, tmpPos, -direction, ref tmpPrises, ref tmpPiece)) { if (tmpPrises > nbPrises) { var tmpCoups = new Mouvement(coups); tmpCoups.Sauts.Enqueue(tmpPos); tmpPiece.flag = true; GetMouvementsPossiblesRec(plateau, possibles, tmpCoups, ref tmpPos, -direction, tmpPrises); tmpPiece.flag = false; } else if (coups.Sauts.Count == 0) { var tmpCoups = new Mouvement(coups); tmpCoups.Sauts.Enqueue(tmpPos); possibles.Push(new Tuple <int, Mouvement>(nbPrises, tmpCoups)); } } else { if (invalideUneFois) { invalideUneFois = false; break; } invalideUneFois = true; } } }