public Move PlayUserMove(string sessionId, string gameId, Move userMove, out string errorMessage) { errorMessage = string.Empty; //Get the requested game from the session var session = _cacheProvider.GetValue(sessionId) as UserSession; if (session == null) { errorMessage = "Session expired! Please login again."; return null; } var game = _gameProvider.GetGame(gameId); if (game != null) { game.LastActivityTime = DateTime.UtcNow; session.GameMoves = session.GameMoves ?? new Dictionary<string, List<string>>(); session.GameMoves[gameId] = session.GameMoves.ContainsKey(gameId) ? session.GameMoves[gameId] : new List<string>(); var moves = _gameProvider.GetGameMoves(gameId); //Validate the user move if (!ValidMove(userMove, moves, out errorMessage) || !string.IsNullOrEmpty(errorMessage)) { return null; } //Save user move in database and session moves userMove = _movesDataProvider.SaveMove(gameId, userMove); moves.Add(userMove); session.GameMoves[gameId].Add(userMove.Id); //Get the player next tiles and add them to the player tiles var pIndex = game.Players.FindIndex(p => string.Equals(p.Id, userMove.Player)); var player = game.Players[pIndex]; pIndex = game.Players.FindIndex(p => !string.Equals(p.Id, userMove.Player)); var opponant = game.Players[pIndex]; GiveNextTilesToPlayer(game, ref player, userMove); //Save player tiles and points player.Points = player.Points + userMove.Points; player.IsActive = false; _gameProvider.SaveGamePlayerStatus(gameId, player); //If game is finished then save game status and game winner. if (player.TilesRemaining <= 0) { SaveGameStatus(gameId, game, opponant, player, session); } else { //set the opponant status to active. opponant.IsActive = true; _gameProvider.SetGamePlayerTurn(gameId, opponant.Id, true); } } return userMove; }
public static Move ToModelMove(this Article article) { Move move = new Move() { MoveCode = article.Get<string>("move_code"), Points = article.Get<int>("points"), Player = article.Get<string>("player"), TimeStamp = article.UtcCreateDate, Id = article.Id }; return move; }
public PassChanceRs PassChance(PassChanceRq request) { if (request == null || string.IsNullOrEmpty(request.SessionId) || string.IsNullOrEmpty(request.GameId)) return new PassChanceRs() { IsSucess = false, ErrorMessage = "Invalid PassChanceRq request!" }; var response = new PassChanceRs() { IsSucess = true, GameId = request.GameId }; try { IGameProvider gameProvider = GameProviderFactory.GetGameProvider(); var session = GetSession(request.SessionId, response); if (session == null) return response; var gameIndex = session.ActiveGames.FindIndex(g => string.Equals(g, request.GameId)); var game = gameProvider.GetGame(request.GameId); if (gameIndex != -1 && game!=null) { IMovesDataProvider movesDataProvider = MovesDataProviderFactory.GetMovesDataProvider(); Model.Move move = new Model.Move() { Points = 0, MoveCode = "", Player = session.Account.Id }; move = movesDataProvider.SaveMove(request.GameId, move); var gameMoves = gameProvider.GetGameMoves(request.GameId); gameMoves.Add(move); session.GameMoves[request.GameId].Add(move.Id); var pIndex = game.Players.FindIndex(p => string.Equals(p.Id, session.Account.Id)); var player = game.Players[pIndex]; player.IsActive = false; gameProvider.SetGamePlayerTurn(request.GameId, player.Id, false); pIndex = game.Players.FindIndex(p => !string.Equals(p.Id, session.Account.Id)); var opponant = game.Players[pIndex]; opponant.IsActive = true; gameProvider.SetGamePlayerTurn(request.GameId, opponant.Id, true); } else { response.IsSucess = false; response.ErrorMessage = "Invalid game! Please refresh."; } } catch (Exception ex) { response.IsSucess = false; response.ErrorMessage = "Failed to pass your chance!"; LoggingDataProviderFactory.GetLoggingDataProvider().LogException(ex, Source, "PassChance", Model.Severity.Critical); } return response; }
private bool ValidMove(Move userMove, List<Move> gameMoves, out string errorMessage) { errorMessage = string.Empty; var currentTiles = ToGameTiles(new List<Move>() { userMove }); var gameTiles = ToGameTiles(gameMoves); var movedTiles = new List<GameTile>(); foreach (var currentTile in currentTiles) { if (!IsValidMove(currentTile, gameTiles, movedTiles, out errorMessage) || !string.IsNullOrEmpty(errorMessage)) { return false; } gameTiles.Add(currentTile); movedTiles.Add(currentTile); } var lastMove = movedTiles[movedTiles.Count - 1]; movedTiles.RemoveAt(movedTiles.Count - 1); int calculatedPoints = CalculatePoints(gameTiles, lastMove, movedTiles); if (calculatedPoints != userMove.Points) { errorMessage = "Points calculation doesnt match! Please refresh the page."; return false; } return true; }
private Move PlayBotMove(UserSession session, Player bot, int gameIndex) { var game = _gameProvider.GetGame(session.ActiveGames[gameIndex]); var moves = _gameProvider.GetGameMoves(game.Id); var gameTiles = ToGameTiles(moves); List<string> tilesToBePlayed = GetMaxTilesCanBePlayed(bot.Tiles); int maxPoints = 0; List<GameTile> nextMoves = new List<GameTile>(); foreach (var tile in tilesToBePlayed) { //Get all tile moves which match the color of the tile List<GameTile> matchingGameTiles = GetMatchingTileMoves(tile, gameTiles); //for each tile move get all sorrounding empty tile positions. foreach (var matchingGameTile in matchingGameTiles) { //Get all empty position for the matching tile. List<GameTile> emptyPositions = GetEmptyTilePositions(gameTiles, matchingGameTile, tile); //for each empty position place all the tiles to be played in all direction and get the maximum points. var myTiles = new List<string>(); myTiles.AddRange(tilesToBePlayed); var tileIndex = myTiles.FindIndex(t => t == tile); myTiles.RemoveAt(tileIndex); foreach (var emptyPosition in emptyPositions) { GetMaxPoints("-x", gameTiles, tile, myTiles, emptyPosition, matchingGameTile, ref maxPoints, ref nextMoves); GetMaxPoints("+x", gameTiles, tile, myTiles, emptyPosition, matchingGameTile, ref maxPoints, ref nextMoves); GetMaxPoints("-y", gameTiles, tile, myTiles, emptyPosition, matchingGameTile, ref maxPoints, ref nextMoves); GetMaxPoints("+y", gameTiles, tile, myTiles, emptyPosition, matchingGameTile, ref maxPoints, ref nextMoves); } } } //parse nextmoves into bot move and return Move move = new Move() {Player = bot.Id, Points = maxPoints}; List<string> tileMoves = new List<string>(); foreach (var nextMove in nextMoves) { tileMoves.Add(string.Format("{0},{1},{2}", nextMove.Row, nextMove.Col, nextMove.Tile)); } move.MoveCode = string.Join("|", tileMoves); return move; }
private void GiveNextTilesToPlayer(Game game, ref Player player, Move userMove) { List<string> gameTiles = _gameProvider.GetGameTiles(game.Id); var parts = userMove.MoveCode.Split('|'); foreach (var part in parts) { var mvs = part.Split(','); player.Tiles.Remove(mvs[2]); } player.TilesRemaining = player.TilesRemaining - parts.Length; if (player.TilesRemaining > 6) player.Tiles.AddRange(_movesDataProvider.GetRandomTiles(parts.Length, ref gameTiles)); else player.Tiles.AddRange(_movesDataProvider.GetRandomTiles(player.TilesRemaining - player.Tiles.Count, ref gameTiles)); _gameProvider.SetGameTiles(game.Id, gameTiles); }
public Move SaveMove(string gameId, Move move) { Article moveArticle = new Article(Schemas.Moves); moveArticle.Set("move_code", move.MoveCode); moveArticle.Set("points", move.Points); moveArticle.Set("player", move.Player); var con = Connection.New(Relations.GameMove) .FromExistingArticle(Schemas.Game, gameId) .ToNewArticle(Schemas.Moves, moveArticle); con.SaveAsync().Wait(); move = moveArticle.ToModelMove(); move.TimeStamp = DateTime.UtcNow; return move; }