Example #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;
        }
Example #2
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;
 }
Example #3
0
 /// <summary>
 /// Remove a grid from database
 /// </summary>
 public void Remove(Grid grid)
 {
     db.Grids.Remove(grid);
     db.SaveChanges();
 }
Example #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;
 }
Example #5
0
 /// <summary>
 /// Updates a grid settings
 /// </summary>
 /// <param name="newGrid">New grid object</param>
 public void Update(Grid newGrid)
 {
     var grid = db.Grids.FirstOrDefault(g => g.GridId == newGrid.GridId);
     if(grid != null)
     {
         grid.GridName = newGrid.GridName;
         grid.GameTypeId = newGrid.GameTypeId;
         grid.TreatmentTypeId = newGrid.TreatmentTypeId;
         grid.RoundCount = newGrid.RoundCount;
         //grid.SizeX = newGrid.SizeX;
         //grid.SizeX = newGrid.SizeY;
         //grid.PlayerCount = newGrid.PlayerCount;
         //grid.BotCount = newGrid.BotCount;
         grid.FillFactor = newGrid.FillFactor;
         grid.UpperThreshold = newGrid.UpperThreshold;
         grid.LowerThreshold = newGrid.LowerThreshold;
         grid.HighPayoff = newGrid.HighPayoff;
         grid.LowPayoff = newGrid.LowPayoff;
         grid.NoiseLevel = newGrid.NoiseLevel;
         grid.RandomSeed = newGrid.RandomSeed;
         grid.ExchangeRate = newGrid.ExchangeRate;
         grid.IntroTimer = newGrid.IntroTimer;
         grid.RoundTimer = newGrid.RoundTimer;
         grid.SummaryTimer = newGrid.SummaryTimer;
         grid.EntryGrid = newGrid.EntryGrid;
         grid.ExitGrid = newGrid.ExitGrid;
         grid.PlayedMGames = newGrid.PlayedMGames;
         grid.PlayedTGames = newGrid.PlayedTGames;
         db.Save();
     }
 }
Example #6
0
 /// <summary>
 /// Add a grid to the database
 /// </summary>
 public void Add(Grid grid)
 {
     db.Grids.Add(grid);
     db.SaveChanges();
 }
Example #7
0
        /// <summary>
        /// Compute and save statistics
        /// </summary>
        /// <param name="grid">The grid</param>
        /// <param name="nei">The neighborhoods</param>
        public void GridStats(Grid grid, IList<Neighborhood> nei)
        {
            var stats = new GridStats
            {
                MoveCount = grid.Players.Count(p => p.RequestMove),
                TypeChangeCount = grid.Players.Count(p => p.RequestTypeChange),
                TimeoutCount = grid.Players.Count(p => p.HasTimeout),
                SegregAvg = nei.Average(x => x.OwnShare),
                SegregStd = nei.StdDev(x => x.OwnShare)
            };

            grid.GridStats = stats;
            db.Save();
        }
Example #8
0
        /// <summary>
        /// Counts players in a grid (excluding admins and bots) with regard to player experience
        /// </summary>
        /// <param name="grid">The destination grid</param>
        /// <returns>Number of available players</returns>
        public int PlayerCountByGrid(Grid grid)
        {
            // If destination grid is null/not found, return 0 available players
            if (grid == null) return 0;

            // Return number of available players taking care of experience levels.
            // Experience not relevant
            if (grid.PlayedMGames == -1 & grid.PlayedTGames == -1)
            {
                return db.Players.Count(p => p.GridId == grid.EntryGrid & p.Connected & !p.IsAdmin & !p.IsBot & p.IsReady);
            }
            //Only Type Game Experience relevant
            else if (grid.PlayedMGames == -1 & grid.PlayedTGames >= 0)
            {
                return db.Players.Count(p => p.GridId == grid.EntryGrid & p.Connected & !p.IsAdmin & !p.IsBot & p.IsReady & p.PlayedTGames == grid.PlayedTGames);
            }
            // Only Move Game Experience relevant
            else if (grid.PlayedMGames >= 0 & grid.PlayedTGames == -1)
            {
                return db.Players.Count(p => p.GridId == grid.EntryGrid & p.Connected & !p.IsAdmin & !p.IsBot & p.IsReady & p.PlayedMGames == grid.PlayedMGames);
            }
            // Type and move game experience relevant
            else
            {
                return db.Players.Count(p => p.GridId == grid.EntryGrid & p.Connected & !p.IsAdmin & !p.IsBot & p.IsReady & p.PlayedMGames == grid.PlayedMGames & p.PlayedTGames == grid.PlayedTGames);
            }
        }
Example #9
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;
        }
Example #10
0
        /// <summary>
        /// Add a new grid
        /// </summary>
        /// <param name="gridName">Name of grid</param>
        /// <param name="gameTypeId">Id of GameType</padram>
        /// <param name="treatmentTypeId">Id of Treatment</param>
        /// <param name="roundCount">Number of rounds to play</param>
        /// <param name="x">Size of grid on x dimension</param>
        /// <param name="y">Size of grid on y dimension</param>
        /// <param name="playerCount">Number of players on the grid</param>
        /// <param name="botCount">Number of artifical / simulated players on the grid</param>
        /// <param name="fillFactor">Number of fields to fill</param>
        /// <param name="upperThreshold">High threshold for number of same type players</param>
        /// <param name="lowerThreshold">Lower threshold for number of same type players</param>
        /// <param name="highPayoff">High payoff setting</param>
        /// <param name="lowPayoff">Low payoff setting</param>
        /// <param name="noiseLevel">Level of noise for bots</param>
        /// <param name="randomSeed">Random seed</param>
        /// <param name="exchangeRate">Exchange rate points to USD</param>
        /// <param name="entryGrid">Entry grid to recruit from</param>
        /// <param name="exitGrid">Exit grid to move players to</param>
        /// <param name="gridId">Returns Id of the grid</param>
        public void Add(string gridName, int gameTypeId, int treatmentTypeId, int roundCount, int x, int y, int playerCount, int botCount, double fillFactor, double lowerThreshold, double upperThreshold, double highPayoff, double lowPayoff, double noiseLevel, int randomSeed, double exchangeRate, int introTimer, int roundTimer, int summaryTimer, int entryGrid, int exitGrid, int playedMGames, int playedTGames, int chained, out int gridId)
        {
            // Add Grid
            var grid = new Grid
            {
                GridName = gridName,
                GridState = -1,
                GameTypeId = gameTypeId,
                TreatmentTypeId = treatmentTypeId,
                RoundCount = roundCount,
                SizeX = x,
                SizeY = y,
                TotalPlayerCount = Convert.ToInt32(Math.Round(x * y * fillFactor, 0)),
                PlayerCount = playerCount,
                BotCount = botCount,
                FillFactor = fillFactor,
                UpperThreshold = upperThreshold,
                LowerThreshold = lowerThreshold,
                HighPayoff = highPayoff,
                LowPayoff = lowPayoff,
                NoiseLevel = noiseLevel,
                RandomSeed = randomSeed,
                ExchangeRate = exchangeRate,
                IntroTimer = introTimer,
                RoundTimer = roundTimer,
                SummaryTimer = summaryTimer,
                EntryGrid = entryGrid,
                ExitGrid = exitGrid,
                PlayedMGames = playedMGames,
                PlayedTGames = playedTGames,
                IsStatic = false,
                Chained = chained,
                HasChat = false,
                HasWaitingBonus = false,
                Round = 0,
                GridStats = new GridStats(),
                StartTime = DateTime.Now,
                EndTime = DateTime.Now,
                LastUpdateTime = DateTime.Now
            };

            // Add grid to database
            db.Add(grid);
            gridId = grid.GridId;

            // Add cells for the grid
            db.Cell.Add(gridId, x, y);

            // Save cells to database
            db.Save();

            // Set state
            // If grid is part of a chain, we set GridState == -1
            // The grid state will be set to ready from a calling grid in a chain
            if(grid.Chained == 0)
            {
                SetState(gridId, 0);
            }
            else
            {
                SetState(gridId, -1);
            }
        }
Example #11
0
 /// <summary>
 /// Return the 
 /// </summary>
 /// <param name="treatmentType"></param>
 /// <param name="nei"></param>
 /// <returns></returns>
 public double GetPayoffOld(Grid grid, Neighborhood nei)
 {
     switch (grid.TreatmentTypeId)
     {
         case 0: // Treatment is not set, make same as 1
             if (nei.OtherShare <= grid.UpperThreshold)
             {
                 return grid.HighPayoff;
             }
             else
             {
                 return 0;
             }
         case 1: // High Tolerance
             if (nei.OtherShare <= grid.UpperThreshold)
             {
                 return grid.HighPayoff;
             }
             else
             {
                 return 0;
             }
         case 2: // Extreme Tolerance
             if (nei.OtherShare <= grid.UpperThreshold)
             {
                 return grid.HighPayoff;
             }
             else
             {
                 return 0;
             }
         case 3: // Preference for mixing
             if (nei.OtherShare <= grid.LowerThreshold)
             {
                 return grid.LowPayoff;
             }
             else if (nei.OtherShare <= grid.UpperThreshold)
             {
                 return grid.HighPayoff;
             }
             else
             {
                 return 0;
             }
     }
     return -1;
 }
Example #12
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;
        }
Example #13
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);
 }
Example #14
0
        /// <summary>
        /// Send Message to Console and Log
        /// </summary>
        /// <param name="g"></param>
        /// <param name="message"></param>
        /// <param name="method"></param>
        /// <param name="runtime"></param>
        public void GridMessageAsync(Grid g, string message, string method, long runtime, int debugLevel)
        {
            if (debugLevel <= DebugLevel)
            {
                if (DebugMethod.Length > 0)
                {
                    if (DebugMethod == method)
                    {
                        // Send to admin
                        string adminMessage = string.Format("Grid {0} : {1} : {2} : {3} [{4}]", g.GridId, g.GridState, g.Round, message, runtime);
                        Console.WriteLine(adminMessage);
                    }
                }
                else
                {
                    // Send to admin
                    string adminMessage = string.Format("Grid {0} : {1} : {2} : {3} [{4}]", g.GridId, g.GridState, g.Round, message, runtime);
                    Console.WriteLine(adminMessage);
                }

                if (Logging)
                {
                    using (var db = new PersistedRepository(Connect))
                    {
                        // Add to message log
                        var messageLog = new MessageLog(g, message, method, runtime);
                        db.Add(messageLog);
                        db.Save();
                    }
                }

            }
        }
Example #15
0
 /// <summary>
 /// Unlocks the next grid in the chain
 /// </summary>
 /// <param name="gridId">The Grid Id</param>
 public void StartNextInChain(Grid grid)
 {
     // Chainging Modus 0/1
     if(grid.Chained == 1)
     {
         var nextGrid = db.Grids.FirstOrDefault(g => g.GridState < 0 & g.Chained == 1);
         if(nextGrid != null)
         {
             nextGrid.GridState = 0;
             db.Save();
         }
     }
     // Chaining Modus Chained > 1: Chained = GridId of next grid
     else if (grid.Chained > 1)
     {
         var nextGrids = db.Grids.Where(g => g.GridState < 0 & g.Chained == grid.Chained);
         foreach(var g in nextGrids)
         {
             g.GridState = 0;
             db.Save();
         }
     }
 }
Example #16
0
        /// <summary>
        /// Adds message to log and broadcasts to admin
        /// </summary>
        /// <param name="g">The calling grid.</param>
        /// <param name="message">The message to save to the log file.</param>
        /// <param name="method">The method that called the grid message.</param>
        /// <param name="runtime">Runtime of the calling method.</param>
        /// <param name="verbosity">Verbosity level</param>
        private async Task GridMessageAsync(Grid g, string message, string method, long runtime, int verbosity)
        {
            using (var db = new PersistedRepository())
            {
                // Add to message log
                var messageLog = new MessageLog(g, message, method, runtime);
                db.Add(messageLog);
                await db.SaveAsync();
            }

            if(_engine.Verbosity >= verbosity)
            {
                // Send to admin
                string adminMessage = string.Format("Grid {0} : {1} : {2} : {3} [{4}]", g.GridId, g.GridState, g.Round, message, runtime);
                if (verbosity < 2) AdminMessage(adminMessage);
            }
        }
Example #17
0
 /// <summary>
 /// Computes and returns current bonus payment for waiting time
 /// </summary>
 /// <param name="startTime">StartTime of Waiting Time</param>
 /// <returns>Double with bonus amout</returns>
 public double GetWaitingBonus(Grid grid, DateTime startTime)
 {
     var waitPayRate = grid.ExchangeRate;
     return Math.Round(((DateTime.Now - startTime).TotalMinutes) * waitPayRate, 2);
 }