Exemplo n.º 1
0
        /// <summary>
        /// Call the AI with a status message.
        /// </summary>
        /// <param name="xmlMessage">Can be null. The remote AI XML for a message without the status or my player values set.</param>
        /// <param name="about">The player this status is about. Will be set to receiving user for status not specific to a player.</param>
        /// <param name="status">The status for this message.</param>
        /// <param name="players">All the players.</param>
        /// <param name="passengers">All the passengers.</param>
        public void GameStatus(XDocument xmlMessage, Player about, PlayerAIBase.STATUS status, List<Player> players, List<Passenger> passengers)
        {
            // only care if for me, and an action (ie not status)
            if ((status == PlayerAIBase.STATUS.UPDATE) || ((about != null) && (about.Guid != aiWorker.MyPlayerGuid)))
                return;

            Player player = players.Find(pl => pl.Guid == aiWorker.MyPlayerGuid);
            Trap.trap(about == null);
            if (about == null)
                about = player;
            aiWorker.AddMessage(status, about, AllPickups(player, passengers));
        }
Exemplo n.º 2
0
 public void AddMessage(PlayerAIBase.STATUS status, Player about, List<Passenger> pickup)
 {
     StatusMessage msg = new StatusMessage(status, about, pickup);
     lock (messages)
         messages.Enqueue(msg);
     EventThread.Set();
 }
Exemplo n.º 3
0
 public StatusMessage(PlayerAIBase.STATUS status, Player player, List<Passenger> pickup)
 {
     Status = status;
     LimoTileLocation = player.Limo.Location.TilePosition;
     PassengerDestBusStop = player.Passenger == null ? Point.Empty : player.Passenger.Destination.BusStop;
     Pickup = pickup;
 }
Exemplo n.º 4
0
        /// <summary>
        /// Called when the game starts, providing all info.
        /// </summary>
        /// <param name="map">The game map.</param>
        /// <param name="me">The player being setup..</param>
        /// <param name="players">All the players.</param>
        /// <param name="companies">All companies on the board.</param>
        /// <param name="passengers">All the passengers.</param>
        /// <param name="ordersEvent">Callback to pass orders to the engine.</param>
        public void Setup(GameMap map, Player me, List<Player> players, List<Company> companies, List<Passenger> passengers, PlayerAIBase.PlayerOrdersEvent ordersEvent)
        {
            // start the thread
            aiWorker = new AiWorker(map, me.Guid, companies, ordersEvent);
            aiThread = new Thread(aiWorker.MainLoop) {Name = me.Name.Replace(' ', '_'), IsBackground = true};
            aiThread.Start();

            // cause it to pick a passenger to pick up and calculate the path to that company.
            aiWorker.AddMessage(PlayerAIBase.STATUS.NO_PATH, me, AllPickups(me, passengers));
        }
Exemplo n.º 5
0
            public AiWorker(GameMap gameMap, string myPlayerGuid, List<Company> companies, PlayerAIBase.PlayerOrdersEvent sendOrders)
            {
                this.gameMap = gameMap;
                MyPlayerGuid = myPlayerGuid;
                Companies = companies;
                this.sendOrders = sendOrders;
                messages = new Queue<StatusMessage>();

                // get it ready to handle events.
                EventThread = new AutoResetEvent(false);
                ExitThread = false;
            }
Exemplo n.º 6
0
 /// <summary>
 /// Call the AI with a status message.
 /// </summary>
 /// <param name="xmlMessage">Can be null. The remote AI XML for a message without the status or my player values set.</param>
 /// <param name="about">The player this is about.</param>
 /// <param name="status">The status for this message.</param>
 /// <param name="players">All the players.</param>
 /// <param name="passengers">All the passengers.</param>
 public void GameStatus(XDocument xmlMessage, Player about, PlayerAIBase.STATUS status, List<Player> players, List<Passenger> passengers)
 {
     ai.GameStatus(xmlMessage, about, status, players, passengers);
 }
Exemplo n.º 7
0
        public void Setup(GameMap map, Player me, List<Player> players, List<Company> companies, List<Passenger> passengers,
				   PlayerAIBase.PlayerOrdersEvent ordersEvent)
        {
            ai.Setup(map, me, players, companies, passengers, ordersEvent);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Called when the game starts, providing all info.
        /// </summary>
        public void Setup(GameMap map, Player me, List<Player> players, List<Company> companies, List<Passenger> passengers, PlayerAIBase.PlayerOrdersEvent ordersEvent)
        {
            sendOrders = ordersEvent;

            XDocument doc = new XDocument();
            XElement elemRoot = new XElement("setup", new XAttribute("game-start", true), new XAttribute("my-guid", me.Guid));
            doc.Add(elemRoot);

            // the map
            XElement elemMap = new XElement("map", new XAttribute("width", map.Width), new XAttribute("height", map.Height), new XAttribute("units-tile", TileMovement.UNITS_PER_TILE));
            elemRoot.Add(elemMap);
            for (int x = 0; x < map.Width; x++ )
                for (int y = 0; y < map.Height; y++)
                {
                    MapSquare square = map.Squares[x][y];
                    XElement elemRow = new XElement("tile", new XAttribute("x", x), new XAttribute("y", y),
                                                    new XAttribute("type", square.Tile.Type));
                    if (square.Tile.IsDriveable)
                    {
                        elemRow.Add(new XAttribute("direction", square.Tile.Direction));
                        if (square.StopSigns != MapSquare.STOP_SIGNS.NONE)
                            elemRow.Add(new XAttribute("stop-sign", square.StopSigns));
                        if (square.SignalDirection != MapSquare.SIGNAL_DIRECTION.NONE)
                            elemRow.Add(new XAttribute("signal", true));
                    }
                    elemMap.Add(elemRow);
                }

            // all players (including me)
            XElement elemPlayers = new XElement("players");
            elemRoot.Add(elemPlayers);
            foreach (Player plyrOn in players)
                elemPlayers.Add(new XElement("player", new XAttribute("guid", plyrOn.Guid),
                                                   new XAttribute("name", plyrOn.Name),
                                                   new XAttribute("limo-x", plyrOn.Limo.Location.TilePosition.X),
                                                   new XAttribute("limo-y", plyrOn.Limo.Location.TilePosition.Y),
                                                   new XAttribute("limo-angle", plyrOn.Limo.Location.Angle)));

            // all companies
            XElement elemCompanies = new XElement("companies");
            elemRoot.Add(elemCompanies);
            foreach (Company cmpnyOn in companies)
                elemCompanies.Add(new XElement("company", new XAttribute("name", cmpnyOn.Name),
                            new XAttribute("bus-stop-x", cmpnyOn.BusStop.X), new XAttribute("bus-stop-y", cmpnyOn.BusStop.Y)));

            // all passengers
            XElement elemPassengers = new XElement("passengers");
            elemRoot.Add(elemPassengers);
            foreach (Passenger psngrOn in passengers)
            {
                XElement elemPassenger = new XElement("passenger", new XAttribute("name", psngrOn.Name), new XAttribute("points-delivered", psngrOn.PointsDelivered));
                // if due to a re-start, these can be null
                if (psngrOn.Lobby != null)
                    elemPassenger.Add(new XAttribute("lobby", psngrOn.Lobby.Name));
                if (psngrOn.Destination != null)
                    elemPassenger.Add(new XAttribute("destination", psngrOn.Destination.Name));
                foreach (Company route in psngrOn.Companies)
                    elemPassenger.Add(new XElement("route", route.Name));
                foreach (Passenger enemy in psngrOn.Enemies)
                    elemPassenger.Add(new XElement("enemy", enemy.Name));
                elemPassengers.Add(elemPassenger);
            }

            framework.tcpServer.SendMessage(TcpGuid, doc.ToString());
        }
Exemplo n.º 9
0
        /// <summary>
        /// Call the AI with a status message.
        /// </summary>
        /// <param name="xmlMessage">Can be null. The remote AI XML for a message without the status or my player values set.</param>
        /// <param name="about">The player this status is about. Will be set to receiving user for status not specific to a player.</param>
        /// <param name="status">The status for this message.</param>
        /// <param name="players">All the players.</param>
        /// <param name="passengers">All the passengers.</param>
        public void GameStatus(XDocument xmlMessage, Player about, PlayerAIBase.STATUS status, List<Player> players, List<Passenger> passengers)
        {
            if (TcpGuid == null)
                return;

            if (xmlMessage == null)
                xmlMessage = BuildMessageXml(players, passengers);
            XAttribute attr = xmlMessage.Root.Attribute("status");
            if (attr == null)
                xmlMessage.Root.Add(new XAttribute("status", status));
            else
                attr.Value = status.ToString();

            attr = xmlMessage.Root.Attribute("player-guid");
            if (attr == null)
                xmlMessage.Root.Add(new XAttribute("player-guid", about.Guid));
            else
                attr.Value = about.Guid;

            StringBuilder buf = new StringBuilder();
            Player player = framework.GameEngine.Players.Find(pl => pl.TcpGuid == TcpGuid);
            if (player != null)
                foreach (Point ptOn in player.Limo.PathTiles)
                    buf.Append(Convert.ToString(ptOn.X) + ',' + Convert.ToString(ptOn.Y) + ';');

            XElement elem = xmlMessage.Root.Element("path");
            if (elem == null)
            {
                elem = new XElement("path");
                xmlMessage.Root.Add(elem);
                elem.Value = buf.ToString();
            }
            else
                elem.Value = buf.ToString();

            if (player != null)
            {
                buf.Clear();
                foreach (Passenger psngr in player.PickUp)
                    buf.Append(psngr.Name + ';');
            }
            elem = xmlMessage.Root.Element("pick-up");
            if (elem == null)
            {
                elem = new XElement("pick-up");
                xmlMessage.Root.Add(elem);
                elem.Value = buf.ToString();
            }
            else
                elem.Value = buf.ToString();

            framework.tcpServer.SendMessage(TcpGuid, xmlMessage.ToString());
        }
Exemplo n.º 10
0
        private List<Passenger> MakeDecision(PlayerAIBase.STATUS status, Player plyrStatus, List<Player> players, List<Passenger> passengers)
        {
            if (Me.Limo.Passenger != null)
                return Me.PickUp;
            switch (status)
            {
                // action should always be :
                // make sure action is still the desired one
                // if not, compare the scores of top actions
                // if there's not a big difference, stay on current action
                case PlayerAIBase.STATUS.UPDATE:
                // default action
                case PlayerAIBase.STATUS.NO_PATH:
                // that's fine, default action
                case PlayerAIBase.STATUS.PASSENGER_NO_ACTION:
                // if we have no passenger, decide who we want.
                // if we have a passenger, make sure we still want them.
                // that's the default action
                case PlayerAIBase.STATUS.PASSENGER_DELIVERED:
                // default action
                case PlayerAIBase.STATUS.PASSENGER_ABANDONED:
                // default action
                case PlayerAIBase.STATUS.PASSENGER_REFUSED:
                // default action
                case PlayerAIBase.STATUS.PASSENGER_DELIVERED_AND_PICKED_UP:
                //default action
                case PlayerAIBase.STATUS.PASSENGER_PICKED_UP:
                // default action
                default:
                    {

                        // Go to the best-expected company.
                        SortedDictionary<float, Company> bestBusStop = new SortedDictionary<float, Company>();
                        foreach (Company company in GameInfo.activeBusStops())
                        {
                            // Sort passengers at this stop.
                            SortedDictionary<float, Passenger> passengersAtStop = GetPassengerWeights(Me, GameInfo.PassengerAtLocation(company));

                            // TODO: Ensure descending order.
                            // Time for us to get there
                            float our_time = (float)pFinder.getTimeForPath(pFinder.computeFastestPath(Me.Limo.TilePosition, company.BusStop));
                            // Number of other players closer/same than us. Buffer time of 100sec.
                            int other_players = GameInfo.OtherPlayersWithinTimeToLocation(our_time+100f, company.BusStop).Count;

                            // If there's one enemy within range, the 2nd highest has to be good enough. If 3rd, they have to be high enough. Etc.
                            int minCount = Math.Min(other_players, passengersAtStop.Count);
                            float average = 0;
                            // have to go in descending order for this.
                            for (int i = passengersAtStop.Count-1; i >= passengersAtStop.Count-minCount; i--) {
                                average += passengersAtStop.Keys.ToList()[i];
                            }
                           /* for (int i = 0; i < minCount; i++)
                            {
                                average += passengersAtStop.Keys.ToList()[i];
                            }*/
                            average /= minCount;

                            // Add the average value & company to result
                            bestBusStop.Add(average, company);
                        }
                        // go to the best bus stop. Set the desired player_list to the top at the bus stop
                        int numberOfResults = bestBusStop.Count;
                        Company winningCompany = bestBusStop.Values.ToList()[numberOfResults-1];

                        //List<Point> path = pFinder.computeFastestPath(Me.Limo.TilePosition, winningCompany.BusStop);
                        List<Passenger> passengerList = GetPassengerWeights(Me, GameInfo.PassengerAtLocation(winningCompany)).Values.ToList();
                        passengerList.Reverse();

                        return passengerList;

                    }

            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Called at the start of the game.
        /// </summary>
        /// <param name="map">The game map.</param>
        /// <param name="me">You. This is also in the players list.</param>
        /// <param name="players">All players (including you).</param>
        /// <param name="companies">The companies on the map.</param>
        /// <param name="passengers">The passengers that need a lift.</param>
        /// <param name="ordersEvent">Method to call to send orders to the server.</param>
        public void Setup(Map map, Player me, List<Player> players, List<Company> companies, List<Passenger> passengers,
            PlayerAIBase.PlayerOrdersEvent ordersEvent)
        {
            try
            {
                pFinder = new PathFinder();
                GameMap = map;
                GameInfo = new GameStatusInfo();
                GameInfo.Setup(map, pFinder);
                Players = players;
                Me = me;
                Companies = companies;
                Passengers = passengers;
                sendOrders = ordersEvent;

                List<Passenger> pickup = AllPickups(me, passengers);
                pFinder.computeAllPaths(map);
                pFinder.generateAdjacencyMatrix();

                // get the path from where we are to the dest.
                List<Point> path = CalculatePathPlus1(me, pickup[0].Lobby.BusStop);
                sendOrders("ready", path, pickup);
            }
            catch (Exception ex)
            {
                log.Fatal(string.Format("Setup({0}, ...", me == null ? "{null}" : me.Name), ex);
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Called to send an update message to this A.I. We do NOT have to send orders in response. 
        /// </summary>
        /// <param name="status">The status message.</param>
        /// <param name="plyrStatus">The player this status is about. THIS MAY NOT BE YOU.</param>
        /// <param name="players">The status of all players.</param>
        /// <param name="passengers">The status of all passengers.</param>
        public void GameStatus(PlayerAIBase.STATUS status, Player plyrStatus, List<Player> players, List<Passenger> passengers)
        {
            // bugbug - Framework.cs updates the object's in this object's Players, Passengers, and Companies lists. This works fine as long
            // as this app is single threaded. However, if you create worker thread(s) or respond to multiple status messages simultaneously
            // then you need to split these out and synchronize access to the saved list objects.

            try
            {
                // bugbug - we return if not us because the below code is only for when we need a new path or our limo hit a bus stop.
                // if you want to act on other players arriving at bus stops, you need to remove this. But make sure you use Me, not
                // plyrStatus for the Player you are updatiing (particularly to determine what tile to start your path from).
                if (plyrStatus != Me)
                    return;

                GameInfo.update(players, passengers);

                Point ptDest;
                List<Passenger> pickup = new List<Passenger>();

               				// determine where we want to go and who we want to pick up
                switch (status)
                {
                    case PlayerAIBase.STATUS.UPDATE:
                        return;
                    case PlayerAIBase.STATUS.NO_PATH:
                    case PlayerAIBase.STATUS.PASSENGER_NO_ACTION:
                        if (plyrStatus.Limo.Passenger == null)
                        {
                            pickup = MakeDecision(status, plyrStatus, players, passengers);
                            ptDest = pickup[0].Lobby.BusStop;
                        }
                        else
                            ptDest = plyrStatus.Limo.Passenger.Destination.BusStop;
                        break;
                    case PlayerAIBase.STATUS.PASSENGER_DELIVERED:
                    case PlayerAIBase.STATUS.PASSENGER_ABANDONED:
                        pickup = MakeDecision(status, plyrStatus, players, passengers);
                        ptDest = pickup[0].Lobby.BusStop;
                        break;
                    case PlayerAIBase.STATUS.PASSENGER_REFUSED:
                        pickup = MakeDecision(status, plyrStatus, players, passengers);
                        ptDest = pickup[0].Lobby.BusStop;
                        break;
                    case PlayerAIBase.STATUS.PASSENGER_DELIVERED_AND_PICKED_UP:
                    case PlayerAIBase.STATUS.PASSENGER_PICKED_UP:
                        pickup = MakeDecision(status, plyrStatus, players, passengers);
                        ptDest = pickup[0].Lobby.BusStop;
                        break;
                    default:
                        throw new ApplicationException("unknown status");
                }

                // get the path from where we are to the dest.
                List<Point> path = CalculatePathPlus1(plyrStatus, ptDest);

                if (log.IsDebugEnabled)
                    log.Debug(string.Format("{0}; Path:{1}-{2}, {3} steps; Pickup:{4}, {5} total",
                        status,
                        path.Count > 0 ? path[0].ToString() : "{n/a}",
                        path.Count > 0 ? path[path.Count - 1].ToString() : "{n/a}",
                        path.Count,
                        pickup.Count == 0 ? "{none}" : pickup[0].Name,
                        pickup.Count));

                // update our saved Player to match new settings
                if (path.Count > 0)
                {
                    Me.Limo.Path.Clear();
                    Me.Limo.Path.AddRange(path);
                }
                if (pickup.Count > 0)
                {
                    Me.PickUp.Clear();
                    Me.PickUp.AddRange(pickup);
                }

                sendOrders("move", path, pickup);
            }
            catch (Exception ex)
            {
                log.Error(string.Format("GameStatus({0}, {1}, ...", status, plyrStatus == null ? "{null}" : plyrStatus.Name), ex);
            }
        }