예제 #1
0
        /// <summary>
        /// Set of client status information pushed at regular intervals
        /// </summary>
        /// <param name="g">The grid</param>
        /// <param name="p">The player</param>
        /// <param name="nei">Players neighborhood</param>
        /// <returns>A client status view</returns>
        public ClientView GetClientStatus(Grid g, Player p)
        {
            int blueCount;
            int yellowCount;

            if (p.PlayerType == 1)
            {
                blueCount = p.Neighborhood.OwnTypeCount;
                yellowCount = p.Neighborhood.OtherTypeCount;
            }
            else
            {
                blueCount = p.Neighborhood.OtherTypeCount;
                yellowCount = p.Neighborhood.OwnTypeCount;
            }

            var cv = new ClientView
            {
                Round = g.Round,
                OwnType = p.PlayerType,
                Move = p.RequestMove,
                TypeChange = p.RequestTypeChange,
                Timeout = p.HasTimeout,
                LastPayoff = p.LastPoints,
                TotalPayoff = p.GridPoints,
                BlueCount = blueCount,
                YellowCount = yellowCount,
                WhiteCount = p.Neighborhood.EmptyCount,
                OwnShare = p.Neighborhood.OwnShare.ToString("P1"),
                OtherShare = p.Neighborhood.OtherShare.ToString("P1"),
                CountDown = g.RoundTimer
            };

            return cv;
        }
예제 #2
0
        /// <summary>
        /// Adds a player on arrival
        /// </summary>
        /// <param name="accessCode">Access code of player</param>
        /// <param name="connectionId">Connection Id of player</param>
        /// <param name="connected">Connection status</param>
        /// <param name="isAdmin">True if admin connection, false if client</param>
        public void Add(string accessCode, string connectionId, bool connected, bool isAdmin, string ip, string browser, string transport)
        {
            var grid = db.Grids.FirstOrDefault(g => g.GridName.Equals("Lobby"));
            if (grid == null) throw new Exception("Lobby not found found");

            var player = new Player
            {
                AccessCode = accessCode,
                ConnectionId = connectionId,
                Connected = connected,
                Ip = ip,
                Browser = browser,
                Transport = transport,
                IsAdmin = isAdmin,
                IsBot = false,
                IsZombie = false,
                PlayerNr = 0,
                PlayerType = 0,
                Round = 0,
                IsReady = false,
                HasTimeout = false,
                RequestMove = false,
                RequestTypeChange = false,
                Neighborhood = new Neighborhood(),
                LastPoints = 0,
                GridPoints = 0,
                TotalPoints = 0,
                GridWaitingTime = 0,
                TotalWaitingTime = 0,
                WaitingPayoff = 0,
                TotalPayoff = 0,
                StartTime = DateTime.Now,
                EndTime = DateTime.Now,
                StartLobby = DateTime.Now,
                LastUpdateTime = DateTime.Now,
                GridId = grid.GridId
            };
            db.Add(player);
        }
예제 #3
0
 /// <summary>
 /// Set of lobby or waiting room status information pushed at regular intervals
 /// </summary>
 /// <param name="g">The grid</param>
 /// <param name="player">The player</param>
 /// <param name="waitingPlayerCount">Number of players waiting</param>
 /// <param name="requiredPlayerCount">Number of players required for the next grid</param>
 /// <returns></returns>
 public LobbyView GetWaitingStatus(Grid g, Player player, int waitingPlayerCount, int requiredPlayerCount)
 {
     var now = DateTime.Now;
     var lobbyView = new LobbyView
     {
         ConnectionId = player.ConnectionId,
         AccessCode = player.AccessCode,
         ServerTime = now.ToString(),
         Workers = waitingPlayerCount,
         WorkersNeeded = requiredPlayerCount,
         WaitingTime = (now - player.StartLobby).ToString(@"mm\:ss"),
         HasBonus = g.HasWaitingBonus,
         WaitingBonus = db.Player.GetWaitingBonus(g, player.StartLobby)
     };
     return lobbyView;
 }
예제 #4
0
 /// <summary>
 /// Set of grid summary info displayed at the end of a grid
 /// </summary>
 /// <param name="g">The grid</param>
 /// <param name="p">The player</param>
 /// <returns>A grid summary view</returns>
 public GridSummaryView GetGridSummaryView(Grid g, Player p)
 {
     var gsv = new GridSummaryView
     {
         GridId = g.GridId,
         PlayerId = p.PlayerId,
         RoundCount = g.RoundCount,
         Moves = db.PlayerLogs.Count(pl => pl.GridId == g.GridId & pl.PlayerId == p.PlayerId & pl.RequestMove),
         TypeChanges = db.PlayerLogs.Count(pl => pl.GridId == g.GridId & pl.PlayerId == p.PlayerId & pl.RequestTypeChange),
         GridPoints = p.GridPoints,
         GridPayoff = Math.Round((double)p.GridPoints*g.ExchangeRate, 2),
         TotalPayoff = p.TotalPayoff,
         SummaryTimer = g.SummaryTimer
     };
     return gsv;
 }
예제 #5
0
 /// <summary>
 /// Remove a player from database
 /// </summary>
 public void Remove(Player player)
 {
     db.Players.Remove(player);
     db.SaveChanges();
 }
예제 #6
0
 /// <summary>
 /// Add a player to the database
 /// </summary>
 public void Add(Player player)
 {
     db.Players.Add(player);
     db.SaveChanges();
 }
예제 #7
0
        public void SwapPlayer(Player player)
        {
            var grid = db.Grids.FirstOrDefault(g => g.GridId == player.GridId);
            if (grid != null)
            {
                var bot = new Player
                {
                    GridId = player.GridId,
                    AccessCode = "Bot-" + grid.GridGuid + "-Replacement",
                    Connected = true,
                    Ip = "",
                    Browser = "",
                    IsAdmin = false,
                    IsBot = true,
                    IsZombie = true,
                    PlayerNr = player.PlayerNr,
                    PlayerType = player.PlayerType,
                    Round = player.Round,
                    IsReady = true,
                    HasTimeout = false,
                    RequestMove = false,
                    RequestTypeChange = false,
                    LastPoints = 0,
                    TotalPoints = 0,
                    TotalWaitingTime = 0,
                    WaitingPayoff = 0,
                    TotalPayoff = 0,
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now,
                    StartLobby = DateTime.Now,
                    LastUpdateTime = DateTime.Now
                };
                db.Add(bot);
                db.Save();

                var replacementBot = db.Players.FirstOrDefault(p => p.GridId == player.GridId & p.PlayerNr == player.PlayerNr & p.IsBot);
                if(replacementBot != null)
                {
                    var cell = db.Cells.FirstOrDefault(c => c.PlayerId == player.PlayerId);
                    if(cell != null)
                    {
                        cell.PlayerId = replacementBot.PlayerId;
                        db.Save();
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Returns the neighborhood of a player
        /// </summary>
        /// <param name="grid">The Grid</param>
        /// <param name="player">The player</param>
        /// <param name="cells">List of all cells on the grid</param>
        /// <returns>A neighborhood</returns>
        private Neighborhood PlayerNeighborhood(Grid grid, Player player, List<Cell> cells)
        {
            var nei = new Neighborhood();

            var sizeX = grid.SizeX;
            var sizeY = grid.SizeY;

            // Find my cell, type and coordinates
            var cell = cells.FirstOrDefault(c => c.PlayerId == player.PlayerId);
            if (cell != null)
            {
                var myCell = cell.CellNr;
                var myType = player.PlayerType;
                var myX = cell.X;
                var myY = cell.Y;

                // Find CellNr of neighbors
                List<int> neighborCells = new List<int>();
                var nCell = (myY == 1) ? myCell + (sizeY - 1) * sizeX : myCell - sizeX;      //N
                neighborCells.Add(nCell);
                var sCell = (myY == sizeY) ? myCell - (sizeY - 1) * sizeX : myCell + sizeX;
                neighborCells.Add(sCell);                                                     //S
                neighborCells.Add((myX == 1) ? myCell + (sizeX - 1) : myCell - 1);            //W
                neighborCells.Add((myX == sizeX) ? myCell - (sizeX - 1) : myCell + 1);        //E;
                neighborCells.Add((myX == 1) ? nCell + (sizeX - 1) : nCell - 1);              //NW
                neighborCells.Add((myX == sizeX) ? nCell - (sizeX - 1) : nCell + 1);          //NE
                neighborCells.Add((myX == 1) ? sCell + (sizeX - 1) : sCell - 1);              //SW
                neighborCells.Add((myX == sizeX) ? sCell - (sizeX - 1) : sCell + 1);          //SE

                // Iterate neighbors
                var ownTypeCount = 0;
                var otherTypeCount = 0;
                var empty = 0;

                foreach (var nr in neighborCells)
                {
                    var neighbor = cells.FirstOrDefault(c => c.CellNr == nr);
                    if (neighbor.Player != null)
                    {
                        if (neighbor.Player.PlayerType == myType) ownTypeCount++;
                        if (neighbor.Player.PlayerType != myType) otherTypeCount++;
                    }
                    else
                    {
                        empty++;
                    }
                }

                // Compute shares
                double ownShare = 0;
                double otherShare = 0;

                if ((ownTypeCount + otherTypeCount) > 0)
                {
                    ownShare = (double)ownTypeCount / ((double)ownTypeCount + (double)otherTypeCount);
                    otherShare = 1 - ownShare;
                }

                nei = new Neighborhood { PlayerId = player.PlayerId, OwnTypeCount = ownTypeCount, OtherTypeCount = otherTypeCount, EmptyCount = empty, OwnShare = ownShare, OtherShare = otherShare };
            }

            return nei;
        }
예제 #9
0
        /// <summary>
        /// Add artifical inteligence players
        /// </summary>
        /// <param name="gridId">Grid Id</param>
        public void AddBots(int gridId)
        {
            // Get the grid
            var grid = db.Grids.FirstOrDefault(g => g.GridId == gridId);
            if (grid != null)
            {
                // Get the total required number of players
                var totalPlayer = grid.TotalPlayerCount;

                // Get the number of bots to generate
                var targetBotCount = grid.BotCount;

                // Return instantly if bots are not allowed or required
                if (targetBotCount == 0) return;

                // Get the actual number of players
                var existingTotalPlayers = grid.Players.Count(x => x.Connected & !x.IsAdmin);
                var existingRealPlayers = grid.Players.Count(x => x.Connected & !x.IsBot & !x.IsAdmin);
                var existingBots = grid.Players.Count(x => x.Connected & x.IsBot & !x.IsAdmin);

                // Return if we have enough players
                if (existingTotalPlayers >= totalPlayer) return;

                // Generate the requested number of bots
                if (targetBotCount > 0)
                {
                    // Return if we have already spawned the required number of bots
                    if (targetBotCount == existingBots)
                    {
                        return;
                    }
                }
                // Auto-generate the required number of bots
                else if (targetBotCount == -1)
                {
                    targetBotCount = totalPlayer - existingRealPlayers - existingBots;
                }

                // Add bots to grid
                for (int i = 1 + existingBots; i <= targetBotCount + existingBots; i++)
                {
                    var bot = new Player
                    {
                        GridId = gridId,
                        AccessCode = "Bot-" + grid.GridGuid + "-" + i.ToString(),
                        Connected = true,
                        Ip = "",
                        Browser = "",
                        IsAdmin = false,
                        IsBot = true,
                        PlayerNr = 0,
                        PlayerType = 0,
                        Round = 0,
                        IsReady = true,
                        HasTimeout = false,
                        RequestMove = false,
                        RequestTypeChange = false,
                        LastPoints = 0,
                        TotalPoints = 0,
                        TotalWaitingTime = 0,
                        WaitingPayoff = 0,
                        TotalPayoff = 0,
                        StartTime = DateTime.Now,
                        EndTime = DateTime.Now,
                        StartLobby = DateTime.Now,
                        LastUpdateTime = DateTime.Now
                    };
                    db.Add(bot);
                }

                // Save numer of generated bots
                grid.BotCount = targetBotCount + existingBots;

                // Save
                db.Save();

                // Test if bots have been saved
                var existingBots2 = grid.Players.Count(x => x.Connected & x.IsBot & !x.IsAdmin);
                if (grid.BotCount != existingBots2) throw new Exception("Bots not yet saved.");
            }
        }
예제 #10
0
        /// <summary>
        /// Type change rule of bot
        /// </summary>
        /// <param name="grid">The Grid</param>
        /// <param name="player">The player and his neighborhood.</param>
        public void BotTypeChangeDecision(Grid grid, Player player)
        {
            // If neigborhood is not initialized, cannot decide
            if (player.Neighborhood.PlayerId == -1) return;

            bool typeChange = false;

            // Decision Rule
            switch (grid.TreatmentTypeId)
            {
                case 1:     // Tolerance
                    if (player.Neighborhood.OwnShare < grid.LowerThreshold) typeChange = true;
                    break;
                case 2:     // Preference for mixing
                    if (player.Neighborhood.OwnShare < grid.LowerThreshold)
                    {
                        // 100% probability to move if very unhappy
                        typeChange = true;
                    }
                    else if (player.Neighborhood.OwnShare > grid.UpperThreshold)
                    {
                        //50% probability to move if somewhat unhappy
                        double moveProb = db.Random.NextDouble();
                        if (moveProb > 0.5) typeChange = true;
                    }
                    break;
            }

            // Noise
            if (grid.NoiseLevel > 0)
            {
                double noise = db.Random.NextDouble();
                if (noise < grid.NoiseLevel)
                {
                    if (typeChange)
                    {
                        typeChange = false;
                    }
                    else
                    {
                        typeChange = true;
                    }
                }
            }

            // Zombie
            if (player.IsZombie) typeChange = false;

            if (typeChange) player.RequestTypeChange = true;
            player.LastUpdateTime = DateTime.Now;
            player.IsReady = true;
        }
예제 #11
0
 /// <summary>
 /// Compute total payoff after a grid has completed.
 /// </summary>
 /// <param name="grid">The grid</param>
 /// <param name="player">The player</param>
 public void TransferPayoff(Grid grid, Player player)
 {
     switch(grid.GameTypeId)
     {
         case 1:
             player.PlayedMGames++;
             break;
         case 2:
             player.PlayedTGames++;
             break;
         case 3:
             player.PlayedMGames++;
             break;
         case 4:
             player.PlayedTGames++;
             break;
     }
     player.TotalPayoff += Math.Round((double)player.GridPoints * (double)grid.ExchangeRate, 2);
 }