public JsonResult FindGame() { // Model to return if game found var model = new GameViewModel(); // Initialise the context using (var context = new RockPaperWinnersContext()) { // Set the current user as available if (!context.ActiveUsers.Where(a => a.UserID == WebSecurity.CurrentUserId).Any()) { context.ActiveUsers.Add(new ActiveUser { IsInGame = false, LastActionDate = DateTime.UtcNow, UserID = WebSecurity.CurrentUserId }); context.SaveChanges(); } // Record the current datetimeutc, set variable to be a time when we will give up trying to find someone DateTime waitUntilTime = DateTime.UtcNow.AddSeconds(10); // BEGIN TRAN // While not timed out, check the game result entities to find any active game results with my id while (DateTime.UtcNow <= waitUntilTime) { // Get the current user var me = context.UserProfiles.Find(WebSecurity.CurrentUserId); // Look to see if there are any active games for the current user var activeGame = (from gp in context.GameResultPlayers where gp.GameResult.IsActive && gp.UserID == me.ID select gp).FirstOrDefault(); if (activeGame != null) { var game = context.GameResults.Include("GameResultPlayers").Where(g => g.ID == activeGame.GameResultID).FirstOrDefault(); // Find the opponent var opponentGame = game.GameResultPlayers.Where(gp => gp.UserID != me.ID).FirstOrDefault(); var opponent = context.UserProfiles.Find(opponentGame.UserID); var myGame = game.GameResultPlayers.Where(gp => gp.UserID == me.ID).FirstOrDefault(); // Build the model // TODO: Generate random bet amounts model = new GameViewModel { GameResultID = game.ID, MyUserID = me.ID, OpponentID = opponentGame.UserID, MyBetAmount = myGame.BetAmount, OpponentBetAmount = opponentGame.BetAmount, MyName = me.FullName, OpponentName = context.UserProfiles.Find(opponentGame.UserID).FullName, TotalMoney = me.Money, OpponentImageSource = GravatarHelper.GravatarHelper.CreateGravatarUrl(opponent.Email, 128, "identicon", null, null, null) }; // Set the current user to be in a game var activeUser = context.ActiveUsers.Where(a => a.UserID == me.ID).FirstOrDefault(); activeUser.IsInGame = true; activeUser.LastActionDate = DateTime.UtcNow; context.SaveChanges(); // Return the model return(Json(model, JsonRequestBehavior.AllowGet)); } else { // Get a list of possible opponents var possibleOpponents = context.ActiveUsers.Where(a => !a.IsInGame && a.UserID != me.ID).ToList(); if (possibleOpponents.Count() > 0) { // Generate a random indexer for the opponent Random opponentID = new Random(); int opponentIndex = opponentID.Next(0, possibleOpponents.Count()); var opponentChosen = possibleOpponents[opponentIndex]; // Get the opponents details var opponent = context.UserProfiles.Find(opponentChosen.UserID); // Build a new game, together with both players var newGame = new GameResult { GameDateTime = DateTime.UtcNow, IsActive = true }; var myGameRecord = new GameResultPlayer { BetAmount = 1.00m, GameResultID = newGame.ID, UserID = me.ID }; var opponentGameRecord = new GameResultPlayer { BetAmount = 1.00m, GameResultID = newGame.ID, UserID = opponent.ID }; context.GameResults.Add(newGame); context.GameResultPlayers.Add(myGameRecord); context.GameResultPlayers.Add(opponentGameRecord); context.SaveChanges(); // Build the model model = new GameViewModel { GameResultID = newGame.ID, MyBetAmount = myGameRecord.BetAmount, MyName = me.FullName, MyUserID = me.ID, OpponentBetAmount = opponentGameRecord.BetAmount, OpponentID = opponent.ID, OpponentName = opponent.FullName, TotalMoney = me.Money, OpponentImageSource = GravatarHelper.GravatarHelper.CreateGravatarUrl(opponent.Email, 128, "identicon", null, null, null) }; // Set both the current player and opponent to be in a game var myActiveUser = context.ActiveUsers.Where(a => a.UserID == me.ID).FirstOrDefault(); myActiveUser.IsInGame = true; myActiveUser.LastActionDate = DateTime.UtcNow; var myActiveOpponent = context.ActiveUsers.Where(a => a.UserID == opponent.ID).FirstOrDefault(); myActiveUser.IsInGame = true; myActiveOpponent.LastActionDate = DateTime.UtcNow; context.SaveChanges(); // Complete the transaction // scope.Complete(); return(Json(model, JsonRequestBehavior.AllowGet)); } } // Nobody found, so try again in 1 seconds Thread.Sleep(1000); } // We've been going 2 minutes now and noone is playing, so remove the user from looking for a game and return false var dormantUser = context.ActiveUsers.Where(u => u.UserID == WebSecurity.CurrentUserId).FirstOrDefault(); context.ActiveUsers.Remove(dormantUser); context.SaveChanges(); return(Json(false, JsonRequestBehavior.AllowGet)); } }
public JsonResult SubmitAction(int gameResultID, int playerID, string gameActionString) { GameResultPlayer gameResult = null; using (RockPaperWinnersContext context = new RockPaperWinnersContext()) { GameAction gameAction; gameResult = context.GameResultPlayers.Where(g => g.GameResultID == gameResultID && g.UserID == playerID).FirstOrDefault(); // If there is already an action, just end if (gameResult.Action.HasValue) { return(Json("This action has already been processed", JsonRequestBehavior.AllowGet)); } // If the action supplied is invalid, just end if (!Enum.TryParse(gameActionString, true, out gameAction)) { return(Json("Invalid action supplied", JsonRequestBehavior.AllowGet)); } gameResult.Action = gameAction; context.SaveChanges(); } // Record the current datetimeutc, set variable to be a time when we will give up trying to find someone DateTime waitUntilTime = DateTime.UtcNow.AddSeconds(15); // BEGIN TRAN // While not timed out, check the game result entities to find any active game results with my id while (DateTime.UtcNow <= waitUntilTime) { using (RockPaperWinnersContext context = new RockPaperWinnersContext()) { // Get the opponents action var opponentGameResult = context.GameResultPlayers.Where(g => g.GameResultID == gameResultID && g.UserID != playerID).FirstOrDefault(); if (opponentGameResult != null && opponentGameResult.Action.HasValue && !opponentGameResult.ResultOutcome.HasValue) { int winner = (3 + (int)gameResult.Action.Value - (int)opponentGameResult.Action.Value) % 3; var myProfile = context.UserProfiles.Find(playerID); var opponentProfile = context.UserProfiles.Where(u => u.ID == opponentGameResult.UserID).FirstOrDefault(); switch (winner) { case 1: gameResult.ResultOutcome = GamePlayerResultOutcome.IWin; opponentGameResult.ResultOutcome = GamePlayerResultOutcome.OpponentWin; myProfile.Money = myProfile.Money + gameResult.BetAmount; opponentProfile.Money = opponentProfile.Money - opponentGameResult.BetAmount; context.SaveChanges(); break; case 2: gameResult.ResultOutcome = GamePlayerResultOutcome.OpponentWin; opponentGameResult.ResultOutcome = GamePlayerResultOutcome.IWin; myProfile.Money = myProfile.Money - gameResult.BetAmount; opponentProfile.Money = opponentProfile.Money + opponentGameResult.BetAmount; context.SaveChanges(); break; case 0: gameResult.ResultOutcome = GamePlayerResultOutcome.Draw; opponentGameResult.ResultOutcome = GamePlayerResultOutcome.Draw; break; } var game = context.GameResults.Find(gameResultID); game.IsActive = false; var activeUser = context.ActiveUsers.Where(u => u.UserID == playerID).FirstOrDefault(); if (activeUser != null) { context.ActiveUsers.Remove(activeUser); } context.SaveChanges(); var result = new GameResultModel() { GameResult = (int)gameResult.ResultOutcome, MyFunds = myProfile.Money }; return(Json(result, JsonRequestBehavior.AllowGet)); } else if (opponentGameResult != null && opponentGameResult.Action.HasValue && opponentGameResult.ResultOutcome.HasValue) { var activeUser = context.ActiveUsers.Where(u => u.UserID == playerID).FirstOrDefault(); if (activeUser != null) { context.ActiveUsers.Remove(activeUser); } context.SaveChanges(); var result = new GameResultModel() { GameResult = (int)gameResult.ResultOutcome, MyFunds = context.UserProfiles.Find(playerID).Money }; return(Json(result, JsonRequestBehavior.AllowGet)); } else if (opponentGameResult != null && opponentGameResult.Action.HasValue) { return(Json("Has Opponent Action, but result outcome is screwed.", JsonRequestBehavior.AllowGet)); } else if (opponentGameResult == null) { return(Json("opponent game result is null???", JsonRequestBehavior.AllowGet)); } } // Nobody found, so try again in 1 seconds Thread.Sleep(1000); } // The opponent has buggered off, or something went wrong using (RockPaperWinnersContext context = new RockPaperWinnersContext()) { var gameResultPlayers = context.GameResultPlayers.Where(g => g.GameResultID == gameResultID).ToList(); // Set the game result as a draw and remove both players from active users as one has gone and the other needs to find a new opponent foreach (var player in gameResultPlayers) { player.ResultOutcome = GamePlayerResultOutcome.Draw; context.SaveChanges(); var activeUser = context.ActiveUsers.Where(u => u.UserID == player.UserID).FirstOrDefault(); context.ActiveUsers.Remove(activeUser); context.SaveChanges(); } // Mark game as inactive var game = context.GameResults.Find(gameResultID); game.IsActive = false; context.SaveChanges(); // Return the draw result to the person who submitted the action var result = new GameResultModel() { GameResult = 3, MyFunds = context.UserProfiles.Find(playerID).Money }; return(Json(result, JsonRequestBehavior.AllowGet)); } }