private Point GetBestPointToHide(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board) { var allValidMoves = GetValidMoves(allPlayers, board, this.GetInfo() as SpleefPlayerInfo); var playersPositions = GetAlivePlayers(allPlayers, board) .Where(x => x.ID != this.GetInfo().ID) .Select(p => p.CurrentLocation); var list = playersPositions.ToList(); var enemyCentroid = new Polygon(list).FindCentroid(); var enemyCentroidPoint = new Point((int)enemyCentroid.X, (int)enemyCentroid.Y); var solidSquares = GetSolidSquares(allPlayers, board); var solidSquaresCentroid = new Polygon(solidSquares.ToList()).FindCentroid(); var solidSquaresCentroidPoint = new Point((int)solidSquaresCentroid.X, (int)solidSquaresCentroid.Y); Point move = Point.Empty; var bestMovesByDescending = allValidMoves.Select(x => new { Move = x, Value = (GetDistance(solidSquaresCentroidPoint, x) * _centerOfMassSolidWeight) - (GetDistance(enemyCentroidPoint, x) * _centerOfMassEnemiesWeight) + 100 }) .ToList(); if (bestMovesByDescending.Any()) { move = bestMovesByDescending.First().Move; } return(move); }
private bool CanGoDirection(SpleefBoard.SpleefBoard board, Point myLocation) { var destination = GetTargetSquare(myLocation, currentDirection); return((destination.X >= 0 && destination.Y >= 0 && destination.X < board.Width && destination.Y < board.Height) && board[destination.X, destination.Y].IsSolid); }
private SpleefDecision ChooseRandomSurvivalDirection(SpleefBoard.SpleefBoard board, Point myLocation) { var possibilities = new List <SpleefDecision>(); possibilities.Add(SpleefDecision.DefaultDecision); for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (j != 0 || i != 0) { var moveAction = new SpleefDecision(SpleefAction.Move, new Point(i, j)); if (moveAction.IsValid) { var dest = new Point(myLocation.X + moveAction.Target.X, myLocation.Y + moveAction.Target.Y); if (dest.X >= 0 && dest.X < board.Width && dest.Y >= 0 && dest.Y < board.Height) { if (board[dest.X, dest.Y].IsSolid) { possibilities.Add(moveAction); } } } } } } return(possibilities[RandomGen.Next(0, possibilities.Count)]); }
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); }
public IEnumerable <Point> GetSolidSquares(List <SpleefPlayerInfo> players, SpleefBoard.SpleefBoard board) { for (var i = 0; i < board.Width; i++) { for (var j = 0; j < board.Height; j++) { if (board[i, j].IsSolid && FindShortestPathAStar(board, GetMyLocation(), new Point(i, j)) != null) { yield return(new Point(i, j)); } } } }
public IEnumerable <Point> GetValidMoves(List <SpleefPlayerInfo> players, SpleefBoard.SpleefBoard board, SpleefPlayerInfo currentPlayer) { var alivePlayers = GetAlivePlayers(players, board); var otherAlivePlayers = alivePlayers.Where(x => x.ID != currentPlayer.ID).ToList(); foreach (var point in GetAllMoves(board, currentPlayer.CurrentLocation)) { if (board[point.X, point.Y].IsSolid && otherAlivePlayers.All(x => x.CurrentLocation != point)) { yield return(point); } } }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard spleefBoard) { _currentBoard = spleefBoard; var myLocation = GetMyLocation(); var aliveEnemies = GetAlivePlayers(allPlayers, spleefBoard).Where(x => x.ID != Info.ID).ToList(); var closestPlayers = FindClosestPlayersByDistance(aliveEnemies, myLocation); if (!closestPlayers.Any()) { return(SpleefDecision.DefaultDecision); } var target = closestPlayers[RandomGen.Next(0, closestPlayers.Count)]; var targetLocation = GetPlayerLocation(target); var distance = GetDistance(targetLocation, myLocation); if (distance > 0 && distance < 3 && timeSpentHere < 3) { timeSpentHere++; var offsetFromMe = new Point(targetLocation.X - myLocation.X, targetLocation.Y - myLocation.Y); return(new SpleefDecision(SpleefAction.Hole, offsetFromMe)); } List <Point> targetPath = null; var easiestToReachPlayers = FindClosestPlayersByPath(aliveEnemies, myLocation); while (targetPath == null && easiestToReachPlayers.Any()) { var targetToRunAfter = easiestToReachPlayers[RandomGen.Next(0, easiestToReachPlayers.Count)]; targetLocation = GetPlayerLocation(targetToRunAfter); targetPath = FindShortestPathAStar(spleefBoard, myLocation, targetLocation); easiestToReachPlayers.Remove(targetToRunAfter); } if (targetPath != null && targetPath.Count > 1) { var thisTurnDest = targetPath[1]; var offsetFromMe = new Point(thisTurnDest.X - myLocation.X, thisTurnDest.Y - myLocation.Y); timeSpentHere = 0; return(new SpleefDecision(SpleefAction.Move, offsetFromMe)); } timeSpentHere = 0; return(ChooseRandomSurvivalDirection(spleefBoard, myLocation)); }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard spleefBoard) { var possibilities = new List <SpleefDecision>(); possibilities.Add(SpleefDecision.DefaultDecision); var myLocation = GetMyLocation(); for (int i = -2; i < 3; i++) { for (int j = -2; j < 3; j++) { if (j != 0 || i != 0) { var moveAction = new SpleefDecision(SpleefAction.Move, new Point(i, j)); var holeAction = new SpleefDecision(SpleefAction.Hole, new Point(i, j)); if (moveAction.IsValid) { var dest = new Point(myLocation.X + moveAction.Target.X, myLocation.Y + moveAction.Target.Y); if (dest.X >= 0 && dest.X < spleefBoard.Width && dest.Y >= 0 && dest.Y < spleefBoard.Height) { if (spleefBoard[dest.X, dest.Y].IsSolid) { possibilities.Add(moveAction); } } } if (holeAction.IsValid) { var dest = new Point(myLocation.X + holeAction.Target.X, myLocation.Y + holeAction.Target.Y); if (dest.X >= 0 && dest.X < spleefBoard.Width && dest.Y >= 0 && dest.Y < spleefBoard.Height) { if (spleefBoard[dest.X, dest.Y].IsSolid) { possibilities.Add(holeAction); } } } } } } return(possibilities[RandomGen.Next(0, possibilities.Count)]); }
public IEnumerable <Point> GetAllMoves(SpleefBoard.SpleefBoard board, Point currentPosition) { var baseValidMoves = new List <Point>() { new Point(currentPosition.X - 1, currentPosition.Y - 1), new Point(currentPosition.X, currentPosition.Y - 1), new Point(currentPosition.X + 1, currentPosition.Y - 1), new Point(currentPosition.X - 1, currentPosition.Y), new Point(currentPosition.X + 1, currentPosition.Y), new Point(currentPosition.X - 1, currentPosition.Y + 1), new Point(currentPosition.X, currentPosition.Y + 1), new Point(currentPosition.X + 1, currentPosition.Y + 1), }; var validMoves = baseValidMoves.Where(m => m.X >= 0 && m.Y >= 0 && m.X < board.Width && m.Y < board.Height); return(validMoves); }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard spleefBoard) { if (currentDirection == Point.Empty) { ChooseDirection(); } var myLocation = GetMyLocation(); var tries = 20; while (tries > 0 && (!CanGoDirection(spleefBoard, myLocation) || currentDirection == Point.Empty)) { ChooseDirection(); tries--; } return(new SpleefDecision(SpleefAction.Move, currentDirection)); }
private List <Point> GetCasesAround(SpleefBoard.SpleefBoard board, Point pos) { var cases = new List <Point>(); for (var x = -1; x < 2; x++) { for (var y = -1; y < 2; y++) { var realCoordX = pos.X + x; var realCoordY = pos.Y + y; if ((x != 0 || y != 0) && (realCoordX > -1 && realCoordY > -1 && realCoordX < board.Width && realCoordY < board.Height && board[realCoordX, realCoordY].IsSolid)) { cases.Add(new Point(realCoordX, realCoordY)); } } } return(cases); }
private List <Point> GetCasesAround2Dis(SpleefBoard.SpleefBoard board, Point pos) { var cases = new List <Point>(); var casestempo = new List <Point>() { new Point(pos.X + 2, pos.Y), new Point(pos.X - 2, pos.Y), new Point(pos.X, pos.Y + 2), new Point(pos.X, pos.Y - 2) }; foreach (var c in casestempo) { var laCase = c; if ((laCase.X > -1 && laCase.Y > -1 && laCase.X < board.Width && laCase.Y < board.Height && board[laCase.X, laCase.Y].IsSolid) && (FindShortestPathAStar(board, pos, laCase) == null)) { cases.Add(laCase); } } return(cases); }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board) { var bestHidingPosition = GetBestPointToHide(allPlayers, board); var currentPosition = GetMyLocation(); var alivePlayers = GetAlivePlayers(allPlayers, board); var aliveEnemies = alivePlayers.Where(x => x.ID != this.GetInfo().ID); if (aliveEnemies.Any(x => FindShortestPathAStar(board, x.CurrentLocation, bestHidingPosition) != null)) { return(new SpleefDecision(SpleefAction.Move, new Point(bestHidingPosition.X - currentPosition.X, bestHidingPosition.Y - currentPosition.Y))); } if (board[currentPosition.X, currentPosition.Y].HealthRemaining >= 2) { return(new SpleefDecision(SpleefAction.Wait, Point.Empty)); } return(new SpleefDecision(SpleefAction.Move, new Point(bestHidingPosition.X - currentPosition.X, bestHidingPosition.Y - currentPosition.Y))); }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board) { var highestTotalOpponentDistance = double.MinValue; var bestSquare = Point.Empty; var myLocation = GetMyLocation(); var alivePlayers = GetAlivePlayers(allPlayers, board).Where(x => x.ID != Info.ID).ToList(); for (var i = -1; i < 2; i++) { for (var j = -1; j < 2; j++) { var sqrX = myLocation.X + i; var sqrY = myLocation.Y + j; if (sqrX >= 0 && sqrY >= 0 && sqrX < board.Width && sqrY < board.Height && board[sqrX, sqrY].IsSolid && (i != 0 || j != 0)) { var targetSquare = new Point(sqrX, sqrY); var totOpponentDistance = 0.0; foreach (var p in alivePlayers) { var path = FindShortestPathAStar(board, targetSquare, p.CurrentLocation); if (path != null && path.Count > 1) { totOpponentDistance += Math.Sqrt(path.Count); } } if (totOpponentDistance > highestTotalOpponentDistance) { highestTotalOpponentDistance = totOpponentDistance; bestSquare = new Point(i, j); } } } } return(new SpleefDecision(SpleefAction.Move, bestSquare)); }
private bool seeIfAlone(Point currentPosition, List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board, List <Point> alreadyUsedPoint) { foreach (Point move in possibleMove) { 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) && !pointWePassed.Contains(newPosition)) { pointWePassed.Add(newPosition); if (otherPlayersPosition.Contains(newPosition)) { return(false); } bool alone = seeIfAlone(newPosition, allPlayers, board, alreadyUsedPoint); if (!alone) { return(alone); } pointWePassed.Remove(alreadyUsedPoint[alreadyUsedPoint.Count - 1]); } } return(true); }
public List <SpleefPlayerInfo> GetAlivePlayers(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board) { return(allPlayers.Where(x => board[x.CurrentLocation.X, x.CurrentLocation.Y].IsSolid).ToList()); }
public abstract SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board);
/// <summary> /// Finds the shortest path containing no holes to go from one point to another /// </summary> /// <param name="board">The Spleef board, including holes</param> /// <param name="startPoint">The starting point</param> /// <param name="goal">The point to reach</param> /// <returns>The List of point from the start to the goal that the shortest path takes. Includes the start point and the goal.</returns> protected List <Point> FindShortestPathAStar(SpleefBoard.SpleefBoard board, Point startPoint, Point goal) { // The set of nodes already evaluated var closedSet = new List <Point>(); // The set of currently discovered nodes that are not evaluated yet. // Initially, only the start node is known. var openSet = new List <Point>() { startPoint }; // For each node, which node it can most efficiently be reached from. // If a node can be reached from many nodes, cameFrom will eventually contain the // most efficient previous step. var cameFrom = new Dictionary <Point, Point>(); // For each node, the cost of getting from the start node to that node. var gScore = new Dictionary <Point, int>(); // The cost of going from start to start is zero. gScore.Add(startPoint, 0); // For each node, the total cost of getting from the start node to the goal // by passing by that node. That value is partly known, partly heuristic. var fScore = new Dictionary <Point, int>(); // For the first node, that value is completely heuristic. fScore.Add(startPoint, GetDistance(startPoint, goal)); while (openSet.Any()) { var current = Point.Empty; var lowestfScore = int.MaxValue; foreach (var os in openSet) { if (fScore.ContainsKey(os)) { if (fScore[os] < lowestfScore) { lowestfScore = fScore[os]; current = os; } } } if (current == goal) { return(RebuildPath(cameFrom, current)); } openSet.RemoveAt(openSet.IndexOf(current)); closedSet.Add(current); var neighbors = new List <Point>(); for (var i = -1; i < 2; i++) { for (var j = -1; j < 2; j++) { var neighX = current.X + i; var neighY = current.Y + j; if ((i != 0 || j != 0) && (neighX > -1 && neighY > -1 && neighX < board.Width && neighY < board.Height)) { if (board[neighX, neighY].IsSolid) { neighbors.Add(new Point(neighX, neighY)); } } } } foreach (var n in neighbors) { if (!closedSet.Contains(n)) { // The distance from start to a neighbor var tentativeGScore = gScore[current] + 1; if (!openSet.Contains(n)) // Discover a new node { openSet.Add(n); } if (!(gScore.ContainsKey(n)) || tentativeGScore < gScore[n]) { // This path is the best until now. Record it! cameFrom[n] = current; gScore[n] = tentativeGScore; var ds = GetDistance(n, goal); fScore[n] = gScore[n] + ds; } } } } return(null); }
/// <summary> /// Gets the list of all alive players from a list of players and a board they are on /// </summary> /// <param name="players">The players to check</param> /// <param name="board">The board they are on</param> /// <returns>The list of the players who are actually alive</returns> protected List <SpleefPlayerInfo> GetAlivePlayers(List <PlayerInfo> players, SpleefBoard.SpleefBoard board) { return(players.Where(x => IsAlive(x, board)).OfType <SpleefPlayerInfo>().ToList()); }
/// <summary> /// Tests if a bot on a given square is still alive on a specific board /// </summary> /// <param name="info">The square to check</param> /// <param name="board">The board</param> /// <returns>true if a bot that would be on that square would be alive</returns> protected bool IsAlive(Point location, SpleefBoard.SpleefBoard board) { return(board[location.X, location.Y].IsSolid); }
/// <summary> /// Tests if a bot is still alive on a specific board /// </summary> /// <param name="info">The bot to check</param> /// <param name="board">The board</param> /// <returns>true if it is alive</returns> protected bool IsAlive(PlayerInfo info, SpleefBoard.SpleefBoard board) { return(IsAlive(GetPlayerLocation(info), board)); }
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); }
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) { var myLocation = GetMyLocation(); var enemies = GetAlivePlayers(allPlayers, board).Where(x => x.ID != Info.ID).ToList(); var sharingArea = true; if (enemies.Count < 4) { sharingArea = false; foreach (var e in enemies) { var path = FindShortestPathAStar(board, myLocation, e.CurrentLocation); if (path != null) { sharingArea = true; } } } var myPossibilities = GenerateDecisions(enemies, board, myLocation.X, myLocation.Y, timeSpentHere); if (myPossibilities.Count == 0) { return(SpleefDecision.DefaultDecision); } var bestDecisions = new List <SpleefDecision>(); var bestScore = double.MinValue; if (sharingArea) { foreach (var decision in myPossibilities) { var score = EvaluateDecision(decision, enemies, board, myLocation.X, myLocation.Y, timeSpentHere, MaxDepth); if (score > bestScore) { bestScore = score; bestDecisions.Clear(); bestDecisions.Add(decision); } else if (score == bestScore) { bestDecisions.Add(decision); } } } else { if (myPossibilities.Any(x => x.Action == SpleefAction.Wait)) { bestDecisions.Add(SpleefDecision.DefaultDecision); } else { foreach (var decision in myPossibilities) { var numNextTurn = GetNumMovesNextTurn(decision, board, myLocation.X, myLocation.Y); var score = 0; if (numNextTurn > 0) { score = 8 - numNextTurn; } if (score > bestScore) { bestScore = score; bestDecisions.Clear(); bestDecisions.Add(decision); } else if (score == bestScore) { bestDecisions.Add(decision); } } } } var choice = bestDecisions[RandomGen.Next(0, bestDecisions.Count)]; if (choice.Action == SpleefAction.Move) { timeSpentHere = 0; } else { timeSpentHere++; } return(choice); }
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 List <SpleefDecision> GenerateDecisions(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board, int myLocX, int myLocY, int turnsSpentHere) { var decisions = new List <SpleefDecision>(); var closestPlayerDistance = int.MaxValue; foreach (var p in allPlayers) { var dist = GetDistance(p.CurrentLocation.X, p.CurrentLocation.Y, myLocX, myLocY); if (dist < closestPlayerDistance) { closestPlayerDistance = dist; } } if (turnsSpentHere < 3 && closestPlayerDistance > 2) { decisions.Add(new SpleefDecision(SpleefAction.Wait, Point.Empty)); } for (var i = -1; i < 2; i++) { for (var j = -1; j < 2; j++) { var destX = myLocX + i; var destY = myLocY + j; if ((i != 0 || j != 0) && destX >= 0 && destY >= 0 && destX < board.Width && destY < board.Height) { if (board[destX, destY].IsSolid && allPlayers.All(p => p.CurrentLocation.X != destX || p.CurrentLocation.Y != destY)) { decisions.Add(new SpleefDecision(SpleefAction.Move, new Point(i, j))); } } } } return(decisions); }
private int seeTheFuture(int numberOfTime, Point currentPosition, List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard board, List <Point> alreadyUsedPoint) { int bestValue = numberOfTime; if (bestValue < PRECISION) { foreach (Point move in possibleMove) { 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) && !alreadyUsedPoint.Contains(newPosition)) { alreadyUsedPoint.Add(newPosition); int value = seeTheFuture(numberOfTime + 1, newPosition, allPlayers, board, alreadyUsedPoint); if (value > bestValue) { bestValue = value; } if (bestValue == PRECISION) { return(bestValue); } alreadyUsedPoint.Remove(alreadyUsedPoint[alreadyUsedPoint.Count - 1]); } } } return(bestValue); }
public override SpleefDecision PlayTurn(List <SpleefPlayerInfo> allPlayers, SpleefBoard.SpleefBoard spleefBoard) { return(SpleefDecision.DefaultDecision); }
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)); } }