예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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);
        }