private double EvaluateDecision(SpleefDecision decision, List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board, int myLocX, int myLocY, int turnsSpenthere, int depth) { if (depth <= 0) { return(1); } double score = 1; var newLocX = myLocX + decision.Target.X; var newLocY = myLocY + decision.Target.Y; var newBoard = board.Clone(); var newTurnsSpent = turnsSpenthere + 1; if (decision.Action == SpleefAction.Move) { newTurnsSpent = 0; newBoard[myLocX, myLocY].Destroy(); } var decisionsFromThere = GenerateDecisions(allPlayers, newBoard, newLocX, newLocY, newTurnsSpent); foreach (var deci in decisionsFromThere) { score += EvaluateDecision(deci, allPlayers, board, newLocX, newLocY, newTurnsSpent, depth - 1) / 5; } return(score); }
private int GetNumMovesNextTurn(SpleefDecision decision, SpleefBoard.SpleefBoard board, int myLocX, int myLocY) { if (decision.Action != SpleefAction.Move) { return(0); } var newBoard = board.Clone(); newBoard[myLocX, myLocY].Destroy(); var destX = myLocX + decision.Target.X; var destY = myLocY + decision.Target.Y; var num = 0; for (var i = -1; i < 2; i++) { for (var j = -1; j < 2; j++) { var destXAfter = destX + i; var destYAfter = destY + j; if ((i != 0 || j != 0) && destXAfter >= 0 && destYAfter >= 0 && destXAfter < board.Width && destYAfter < board.Height) { if (board[destX, destY].IsSolid) { num++; } } } } return(num); }
private double EvaluateDecision(SpleefDecision decision, List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board, int myLocX, int myLocY, int turnsSpenthere, int depth, Dictionary <SpleefPlayerInfo, List <Point> > paths) { if (depth <= 0) { return(_brain.LeafMoveValue); } double score = _brain.DefaultMoveValue; var newLocX = myLocX + decision.Target.X; var newLocY = myLocY + decision.Target.Y; var newBoard = board.Clone(); var newTurnsSpent = turnsSpenthere + 1; if (decision.Action == SpleefAction.Move) { newTurnsSpent = 0; newBoard[myLocX, myLocY].Destroy(); score += _brain.MoveValue; } else if (decision.Action == SpleefAction.Wait) { score += _brain.WaitValue; } foreach (var enemy in allPlayers) { var hisPos = GetPlayerLocation(enemy); var myPos = GetMyLocation(); var distBird = GetDistance(hisPos, myPos); score += (distBird * _brain.EnemyBirdDistance) + ((distBird * distBird) * _brain.EnemyBirdDistancePow2); if (paths.ContainsKey(enemy)) { var path = paths[enemy]; if (path == null) { score += _brain.CantReachValue; } else { score += (path.Count * _brain.PathDistValue) + ((path.Count * path.Count) * _brain.PathDistValuePow2); } } } var decisionsFromThere = GenerateDecisions(allPlayers, newBoard, newLocX, newLocY, newTurnsSpent); foreach (var deci in decisionsFromThere) { score += EvaluateDecision(deci, allPlayers, board, newLocX, newLocY, newTurnsSpent, depth - 1, paths) / _brain.DepthValue; } return(score); }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board) { Point currentPosition = this.GetMyLocation(); allMoveValue = new Dictionary <Point, int>(); List <Point> usedPosition = new List <Point>(); otherPlayersPosition = new List <Point>(); foreach (SpleefPlayerInfo player in allPlayers) { if (player != this.Info) { usedPosition.Add(player.CurrentLocation); otherPlayersPosition.Add(player.CurrentLocation); } } foreach (Point move in possibleMove) { SpleefBoard.SpleefBoard boardClone = board.Clone(); Point newPosition = new Point(currentPosition.X + move.X, currentPosition.Y + move.Y); if (newPosition.X >= 0 && newPosition.Y >= 0 && newPosition.X < board.Width && newPosition.Y < board.Height && this.IsAlive(newPosition, board)) { allMoveValue.Add(move, seeTheFuture(1, newPosition, allPlayers, boardClone, usedPosition)); } else { allMoveValue.Add(move, 0); } } Point bestMove = new Point(0, 0); int bestValue = 0; foreach (var move in allMoveValue) { if (move.Value > bestValue) { bestMove = move.Key; bestValue = move.Value; } } if (bestValue == 0) { //If we reach this point, we cry and stop moving hoping the other die before us return(new SpleefDecision(SpleefAction.Wait, new Point())); } else { // if true, it mean that there is not a lot of point left if (bestValue != PRECISION) { pointWePassed = new HashSet <Point>(); if (board[currentPosition.X, currentPosition.Y].HealthRemaining > 1 && (isAlone || seeIfAlone(bestMove, allPlayers, board.Clone(), usedPosition))) { isAlone = true; return(new SpleefDecision(SpleefAction.Wait, new Point())); } } //We simply play our best move return(new SpleefDecision(SpleefAction.Move, bestMove)); } }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board) { var choix = SpleefDecision.DefaultDecision; turnNumber++; if (gameNumber == 1 && turnNumber == 1) { foreach (var p in allPlayers) { playerArray.Add(p.ID, new PlayerPersonality(p.ID)); } } var players = GetAlivePlayers(allPlayers, board); var me = (SpleefPlayerInfo)Info; // Need history /*if (roundNum !== 0 && me.History.length > 0) * { * foreach (var p in players) * { * if (players[p].History[players[p].History.length - 1].indexOf("HOLE") !== -1) * { * playerArray[players[p].ID].Aggr++; * totAggr++; * playerArray[players[p].ID].Echec == 0.5; * } * else if (players[p].History[players[p].History.length - 1].indexOf("MOVE") !== -1) * { * playerArray[players[p].ID].Echec == 0.5; * } * if (roundNum == 5) * { * playerArray[players[p].ID].Echec == 0.5; * } * else if (players[p].History[players[p].History.length - 1] == ("I suck at this game") && playerArray[players[p].ID].Echec != 0.5) * { * playerArray[players[p].ID].Echec == 2; * } * } * }*/ //Moves bitches var canStay = true; if (stayCpt == 0) { canStay = false; } // ajouter et si bot agressif à proximité, ne pas stay, sen éloigner ou le bloquer var myBoard = board.Clone(); var myBoard2 = board.Clone(); foreach (var p in players) { if (p.ID != me.ID) { myBoard[p.CurrentLocation.X, p.CurrentLocation.Y].Status = SpleefSquareStatus.Hole; } myBoard2[p.CurrentLocation.X, p.CurrentLocation.Y].Status = SpleefSquareStatus.Hole; } var myLongArray = new List <List <Point> >(); for (var i = 0; i < myBoard2.Width; i++) { for (var j = 0; j < myBoard2.Height; j++) { if (myBoard2[i, j].IsSolid) { var arrP = new List <Point>(); arrP.Add(new Point(i, j)); myLongArray.Add(arrP); } } } var longeurArray = -1; while (longeurArray != myLongArray.Count) { longeurArray = myLongArray.Count; for (var m = 0; m < myLongArray.Count; m++) { for (var n = m + 1; n < myLongArray.Count; n++) { var isAnyAdjacent = false; for (var k = 0; k < myLongArray[n].Count; k++) { for (var l = 0; l < myLongArray[m].Count; l++) { var dis = GetDistance(myLongArray[n][k], myLongArray[m][l]); if (dis == 1 || (dis == 2 && myLongArray[n][k].X != myLongArray[m][l].X && myLongArray[n][k].Y != myLongArray[m][l].Y)) { isAnyAdjacent = true; } } } if (isAnyAdjacent) { for (var l = 0; l < myLongArray[m].Count; l++) { myLongArray[n].Add(myLongArray[m][l]); } myLongArray.RemoveAt(m); n = myLongArray.Count + 1; m = myLongArray.Count + 1; } } } } //code temporaire var monArray8CaseCancer = GetCasesAround(myBoard, me.CurrentLocation); var array8CaseCancerScores = new Dictionary <Point, double>(); if (monArray8CaseCancer.Count > 0) { foreach (var cancer in monArray8CaseCancer) { var arraySecondaire = GetCasesAround(myBoard, cancer); var nombreCasesTourSuivant = arraySecondaire.Count; var lesProfondeurs = 0; if (nombreCasesTourSuivant > 0) { foreach (var sdf in arraySecondaire) { var arrayTertiere = GetCasesAround(myBoard, sdf); lesProfondeurs += arrayTertiere.Count; } } var distanceEnnemi = 0.0; var multipli = 1.0; foreach (var dude in players) { if (dude.ID != me.ID) { var pathEnemi = FindShortestPathAStar(board, cancer, dude.CurrentLocation); if (pathEnemi != null) { multipli = ((1 + (playerArray[dude.ID].Aggr / totAggr)) * playerArray[dude.ID].Failure) * ratiosBalance[2]; distanceEnnemi += (Math.Sqrt(pathEnemi.Count)) * multipli / players.Count; } } } var sizeZone = 0; for (var m = 0; m < myLongArray.Count; m++) { for (var n = 0; n < myLongArray[m].Count; n++) { if (myLongArray[m][n].X == cancer.X && myLongArray[m][n].Y == cancer.Y) { sizeZone = myLongArray[m].Count; } } } array8CaseCancerScores.Add(cancer, (ratiosBalance[0] * nombreCasesTourSuivant) + (ratiosBalance[1] * distanceEnnemi) + (ratiosBalance[3] * lesProfondeurs) + (ratiosBalance[4] * sizeZone / players.Count)); } var bestMoves = new List <Point>(); var bestMovesScore = double.MinValue; foreach (var m in monArray8CaseCancer) { if (array8CaseCancerScores[m] > bestMovesScore) { bestMovesScore = array8CaseCancerScores[m]; bestMoves = new List <Point>() { m }; } else if (Math.Abs(array8CaseCancerScores[m] - bestMovesScore) < 0.01) { bestMoves.Add(m); } } var chosenMove = bestMoves[RandomGen.Next(0, bestMoves.Count)]; var isSafe = true; foreach (var dude in players) { if (dude.ID != me.ID) { if (FindShortestPathAStar(board, me.CurrentLocation, dude.CurrentLocation) != null) { isSafe = false; } } } if (players.Count < 4) { foreach (var p in players) { } } if (isSafe && stayCpt > 0) { choix = SpleefDecision.DefaultDecision; } else { choix = new SpleefDecision(SpleefAction.Move, new Point(chosenMove.X, chosenMove.Y)); } } if (choix.Action == SpleefAction.Wait) { var caseAttaque = GetCasesAround2Dis(myBoard, me.CurrentLocation); if (caseAttaque.Count > 0) { var chosenAttack = caseAttaque[RandomGen.Next(0, caseAttaque.Count)]; choix = new SpleefDecision(SpleefAction.Hole, new Point(chosenAttack.X, chosenAttack.Y)); } SpleefPlayerInfo closestOpponent = null; var closestOpponentDistance = double.MaxValue; foreach (var p in players) { if (p.ID != me.ID) { var dist = GetDistance(me.CurrentLocation, p.CurrentLocation); if (dist < closestOpponentDistance && dist > 0) { closestOpponentDistance = dist; closestOpponent = p; } } } if (closestOpponentDistance < 3) { choix = new SpleefDecision(SpleefAction.Hole, new Point(closestOpponent.CurrentLocation.X, closestOpponent.CurrentLocation.Y)); } } // Retours possibles // Si une action invalide est retournée, l'action "WAIT" sera effectuée à la place // Faire un trou sur un trou existant, faire un trou trop loin // Bouger sur une case trop loin, bouger sur sa propre case // faire un trou ou bouger en dehors du board // sont toutes des actions invalides // Actions quand on est au sol // WAIT Ne rien faire pour ce tour // MOVE X Y Bouger sur une case (et détruire la case d'ou vous venez) dans un range de 1 de toi incluant les diagonales. Ni X ni Y ne peuvent être à plus de 1 de ta coordonnée. // HOLE X Y Exploser une case au choix dans un range de 1-2 (Distance de Manhattan) if (choix.Action == SpleefAction.Wait || choix.Action == SpleefAction.Hole) { stayCpt--; } else { stayCpt = 3; } if (choix.Action == SpleefAction.Wait) { choix = new SpleefDecision(SpleefAction.Hole, new Point(-9999, -9999)); } choix.Target = new Point(choix.Target.X - me.CurrentLocation.X, choix.Target.Y - me.CurrentLocation.Y); return(choix); }