예제 #1
0
        public async Task <LexLambdaResponse> Run(GameSession gameSession)
        {
            var lexSessionAttributes = LexSessionAttributes.GoFishLexSession(gameSession.GameId, gameSession.GameStartDate.ToString("s"));
            var botScore             = gameSession.Players.FirstOrDefault(x => x.IsABot).MatchedCards.Select(x => x.Name).Distinct().ToList().Count;
            var opponentScore        = gameSession.Players.FirstOrDefault(x => !x.IsABot).MatchedCards.Select(x => x.Name).Distinct().ToList().Count;
            var message = Dialogue.CurrentScore(botScore, opponentScore);

            // return message to user
            var response = Utilities.CustomResponseElicitIntent(message, lexSessionAttributes);

            return(response);
        }
예제 #2
0
 public static LexLambdaResponseTypeClose CustomResponseClose(string message, LexSessionAttributes sessionAttributes = null, string fulfillment = "Fulfilled")
 {
     return(new LexLambdaResponseTypeClose {
         DialogAction = new LexLambdaResponseDialogActionTypeClose {
             Message = new LexLambdaResponseMessage {
                 Content = message,
                 ContentType = "PlainText"
             },
             Type = "Close",
             FulfillmentState = fulfillment
         },
         SessionAttributes = sessionAttributes == null ? new Dictionary <string, string>() : sessionAttributes.ToDictionary()
     });
 }
예제 #3
0
        public async Task <LexLambdaResponse> Run(GameSession gameSession, string requestedCard)
        {
            // set variables
            var  gameId               = gameSession.GameId;
            var  gameDateTime         = gameSession.GameStartDate;
            var  totalPlayers         = gameSession.TotalPlayers;
            var  stubCards            = gameSession.StubCards;
            var  botPlayer            = gameSession.CurrentPlayer();
            var  userPlayer           = gameSession.OpponentPlayer();
            var  uriToS3Bucket        = gameSession.UriToS3Bucket;
            var  lexSessionAttributes = LexSessionAttributes.GoFishLexSession(gameId, gameDateTime.ToString("s"));
            var  message              = "";
            Card cardReceived;

            // ========================================================
            // GiveUpCard Intent is only run when it's the Bots Turn
            // ========================================================
            if (!botPlayer.IsABot)
            {
                // return message to user
                var myTurnResponse = Utilities.CustomResponseElicitIntent(Dialogue.NotBotTurn, lexSessionAttributes);
                _logger.LogInfo($"response {JsonConvert.SerializeObject(myTurnResponse)}");
                return(myTurnResponse);
            }

            // ==============
            // Play the turn
            // ==============

            // name of the card the bot asked for
            if (!botPlayer.LastIntent.Split(" ").Last().TrimEnd('?').Equals(requestedCard))
            {
                // return message to user
                var notCardAskedForResponse = Utilities.CustomResponseElicitIntent(Dialogue.NotCardAskedFor + " " + botPlayer.LastIntent, lexSessionAttributes);
                _logger.LogInfo($"response {JsonConvert.SerializeObject(notCardAskedForResponse)}");
                return(notCardAskedForResponse);
            }

            // find card in other players hand
            var cardInOtherPlayerHandFound = userPlayer.Cards.FirstOrDefault(x => String.Equals(x.Name, requestedCard, StringComparison.CurrentCultureIgnoreCase));

            if (cardInOtherPlayerHandFound != null)
            {
                // remove from other players hand
                userPlayer.Cards.Remove(cardInOtherPlayerHandFound);
                cardReceived = cardInOtherPlayerHandFound;

                // give bot the card
                message = Dialogue.GiveBotCardResponse(requestedCard);
            }
            else
            {
                // remove from stub
                cardReceived = stubCards.FirstOrDefault();
                stubCards.Remove(cardReceived);

                // tell the user they don't have that card and it got one from the stub
                message = Dialogue.LiedAboutHavingTheCardResponse;

                if (stubCards.Count > 0)
                {
                    message += " " + Dialogue.PickedCardFromStub;
                }
            }

            // add card received to current players hand
            botPlayer.Cards.Add(cardReceived);

            // ===================================================
            // find if the current player has any matching cards
            // ===================================================

            // find any matching hands in current user hand and put into matched hands pile
            var matchingCards = Utilities.FindMatchingCards(botPlayer.Cards);

            botPlayer.Cards = botPlayer.Cards.Except(matchingCards).ToList();
            botPlayer.MatchedCards.AddRange(matchingCards);
            userPlayer.LastIntent = "";

            // =====================
            // check for game over
            // =====================
            var gameOverMessage = Utilities.IsGameOver(botPlayer, userPlayer);

            if (gameOverMessage)
            {
                message = Dialogue.GameIsOver(botPlayer.MatchedCards.Count, userPlayer.MatchedCards.Count);
                await Utilities.ItemPutDatabase(_dependencyProvider, gameId, gameDateTime.ToString("s"), null, message);
            }
            else
            {
                // ==================
                // make new session
                // ==================

                // new player list
                var players = new List <Player> {
                    botPlayer, userPlayer
                };
                var newGameSession = Utilities.CreateGameSession(gameId, gameDateTime, userPlayer, players, stubCards, totalPlayers, uriToS3Bucket);

                // ==================
                // update database
                // ==================
                await Utilities.ItemPutDatabase(_dependencyProvider, gameId, gameDateTime.ToString("s"), newGameSession);
            }

            // ======================
            // send response to user
            // ======================
            var response = Utilities.CustomResponseElicitIntent(message, lexSessionAttributes);

            return(response);
        }
예제 #4
0
        public async Task <LexLambdaResponse> Run(GameSession gameSession)
        {
            // set variables
            var gameId               = gameSession.GameId;
            var gameDateTime         = gameSession.GameStartDate;
            var totalPlayers         = gameSession.TotalPlayers;
            var stubCards            = gameSession.StubCards;
            var botPlayer            = gameSession.CurrentPlayer();
            var userPlayer           = gameSession.OpponentPlayer();
            var uriToS3Bucket        = gameSession.UriToS3Bucket;
            var message              = Dialogue.NoMoreStubCards;
            var lexSessionAttributes = LexSessionAttributes.GoFishLexSession(gameId, gameDateTime.ToString("s"));

            // ========================================================
            // GoFish Intent is only run when it's the Bots Turn
            // ========================================================
            if (!botPlayer.IsABot)
            {
                // return message to user
                var myTurnResponse = Utilities.CustomResponseElicitIntent(Dialogue.NotBotTurn, lexSessionAttributes);
                _logger.LogInfo($"response {JsonConvert.SerializeObject(myTurnResponse)}");
                return(myTurnResponse);
            }

            // ==============
            // Play the turn
            // ==============

            if (stubCards.Count > 0)
            {
                // remove top card from stub
                var cardReceived = stubCards.FirstOrDefault();
                stubCards.Remove(cardReceived);

                // add card to current players hand
                botPlayer.Cards.Add(cardReceived);

                message = Dialogue.PickedCardFromStub;
            }

            // ===================================================
            // find if the current player has any matching cards
            // ===================================================

            // find any matching hands in current user hand and put into matched hands pile
            var matchingCards = Utilities.FindMatchingCards(botPlayer.Cards);

            botPlayer.Cards = botPlayer.Cards.Except(matchingCards).ToList();
            botPlayer.MatchedCards.AddRange(matchingCards);

            // =====================
            // check for game over
            // =====================
            var gameOverMessage = Utilities.IsGameOver(botPlayer, userPlayer);

            if (gameOverMessage)
            {
                message = Dialogue.GameIsOver(botPlayer.MatchedCards.Count, userPlayer.MatchedCards.Count);
                await Utilities.ItemPutDatabase(_dependencyProvider, gameId, gameDateTime.ToString("s"), null, message);
            }
            else
            {
                // ==================
                // make new session
                // ==================

                // new player list
                var players = new List <Player> {
                    botPlayer,
                    userPlayer
                };
                var newGameSession = Utilities.CreateGameSession(gameId, gameDateTime, userPlayer, players, stubCards, totalPlayers, uriToS3Bucket);
                _logger.LogInfo($"newGameSession {JsonConvert.SerializeObject(newGameSession)}");

                // ==================
                // update database
                // ==================
                await Utilities.ItemPutDatabase(_dependencyProvider, gameId, gameDateTime.ToString("s"), newGameSession);
            }

            // ======================
            // send response to user
            // ======================
            var response = Utilities.CustomResponseElicitIntent(message, lexSessionAttributes);

            return(response);
        }
예제 #5
0
        public async Task <LexLambdaResponse> Run(GameSession gameSession, string requestedCard)
        {
            // set variables
            var    gameId               = gameSession.GameId;
            var    gameDateTime         = gameSession.GameStartDate;
            var    totalPlayers         = gameSession.TotalPlayers;
            var    stubCards            = gameSession.StubCards;
            var    userPlayer           = gameSession.CurrentPlayer();
            var    botPlayer            = gameSession.OpponentPlayer();
            var    uriToS3Bucket        = gameSession.UriToS3Bucket;
            var    lexSessionAttributes = LexSessionAttributes.GoFishLexSession(gameId, gameDateTime.ToString("s"));
            string message;
            var    botCardRequest = "";
            Card   cardReceived   = null;

            // ========================================================
            // AskForCard Intent is only run when it's the User's Turn
            // ========================================================
            if (userPlayer.IsABot)
            {
                // return message to user
                var myTurnResponse = Utilities.CustomResponseElicitIntent(Dialogue.StillBotTurn(userPlayer.LastIntent), lexSessionAttributes);
                return(myTurnResponse);
            }

            // ==============
            // Play the turn
            // ==============

            // find card in other players hand
            var cardInOtherPlayerHandFound = botPlayer.Cards.FirstOrDefault(x => String.Equals(x.Name, requestedCard, StringComparison.CurrentCultureIgnoreCase));

            _logger.LogInfo($"requestedCard {requestedCard}");
            _logger.LogInfo($"cardInOtherPlayerHandFound {JsonConvert.SerializeObject(cardInOtherPlayerHandFound)}");

            if (cardInOtherPlayerHandFound != null)
            {
                // remove from other players hand
                botPlayer.Cards.Remove(cardInOtherPlayerHandFound);
                cardReceived = cardInOtherPlayerHandFound;

                // opponent has the card
                message = Dialogue.BotHasCard(requestedCard);
            }
            else
            {
                if (stubCards.Count > 0)
                {
                    // remove top card from stub
                    _logger.LogInfo($"stubCards {JsonConvert.SerializeObject(stubCards)}");
                    cardReceived = stubCards.FirstOrDefault();
                    _logger.LogInfo($"cardReceived {JsonConvert.SerializeObject(cardReceived)}");
                    stubCards.Remove(cardReceived);
                }

                // opponent doesn't have the card
                message = Dialogue.BotDoesNotHaveCard;
                _logger.LogInfo($"message {message}");
            }

            if (cardReceived != null)
            {
                // add card to current players hand
                userPlayer.Cards.Add(cardReceived);
            }

            // ===================================================
            // find if the current player has any matching cards
            // ===================================================

            // find any matching hands in current user hand and put into matched hands pile
            var matchingCards = Utilities.FindMatchingCards(userPlayer.Cards);

            _logger.LogInfo($"matchingCards {JsonConvert.SerializeObject(matchingCards)}");
            userPlayer.Cards = userPlayer.Cards.Except(matchingCards).ToList();
            userPlayer.MatchedCards.AddRange(matchingCards);

            // =====================
            // check for game over
            // =====================
            var gameOverMessage = Utilities.IsGameOver(botPlayer, userPlayer);

            if (gameOverMessage)
            {
                message = Dialogue.GameIsOver(botPlayer.MatchedCards.Count, userPlayer.MatchedCards.Count);
                await Utilities.ItemPutDatabase(_dependencyProvider, gameId, gameDateTime.ToString("s"), null, message);
            }
            else
            {
                // =============================================
                // determine which card the bot should ask for
                // =============================================
                var botCardToAsk = WhichCardToAskFor();
                _logger.LogInfo($"botCardToAsk {botCardToAsk}");
                botCardRequest       = Dialogue.DoYouHaveACard(botCardToAsk);
                botPlayer.LastIntent = botCardRequest;

                // ==================
                // make new session
                // ==================

                // new player list
                var players = new List <Player> {
                    userPlayer,
                    botPlayer
                };
                var newGameSession = Utilities.CreateGameSession(gameId, gameDateTime, botPlayer, players, stubCards, totalPlayers, uriToS3Bucket);
                _logger.LogInfo($"newGameSession {JsonConvert.SerializeObject(newGameSession)}");

                // ==================
                // update database
                // ==================
                await Utilities.ItemPutDatabase(_dependencyProvider, gameId, gameDateTime.ToString("s"), newGameSession);
            }

            // ======================
            // send response to user
            // ======================
            var response = Utilities.CustomResponseElicitIntent(message + botCardRequest, lexSessionAttributes);

            return(response);
        }
예제 #6
0
        public async Task <LexLambdaResponse> Run(string gameId, string gameStartDate)
        {
            var lexSessionAttributes = LexSessionAttributes.GoFishLexSession(gameId, gameStartDate);

            _logger.LogInfo($"lexSessionAttributes {JsonConvert.SerializeObject(lexSessionAttributes)}");

            // "mix" the cards
            var shuffledDeckOfCards = GoFishCards.Init(_uriToS3Bucket).ShuffleDeck().ToList();

            _logger.LogInfo($"shuffledDeckOfCards {JsonConvert.SerializeObject(shuffledDeckOfCards)}");

            // get the total number of players * number of init cards / remove from list
            var totalPlayers              = 2;
            var initCardPerPlayer         = 7;
            var numberOfCardsToDistribute = totalPlayers * initCardPerPlayer;

            _logger.LogInfo($"numberOfCardsToDistribute {numberOfCardsToDistribute}");

            // get the stub cards to put on the field
            var stubCards = shuffledDeckOfCards.Skip(numberOfCardsToDistribute).Take(shuffledDeckOfCards.Count).ToList();

            _logger.LogInfo($"stubCards {JsonConvert.SerializeObject(stubCards)}");

            // get the cards to distribute to the players
            var cardsToDistribute = shuffledDeckOfCards.Take(numberOfCardsToDistribute).ToList();

            _logger.LogInfo($"cardsToDistribute {JsonConvert.SerializeObject(cardsToDistribute)}");

            // create the players
            var players = new List <Player>();

            for (var playerNumber = 1; playerNumber <= totalPlayers; playerNumber++)
            {
                List <Card> filteredCardsToDistribute;
                bool        isABot;
                if (playerNumber == 1)
                {
                    filteredCardsToDistribute = cardsToDistribute.Where((x, i) => i % 2 != 0).ToList();
                    isABot = true;
                }
                else
                {
                    filteredCardsToDistribute = cardsToDistribute.Where((x, i) => i % playerNumber == 0).ToList();
                    isABot = false;
                }
                var player = new Player {
                    Cards        = filteredCardsToDistribute,
                    Id           = playerNumber.ToString(),
                    MatchedCards = new List <Card>(),
                    IsABot       = isABot
                };
                players.Add(player);
            }

            // who's turn is next -- make it the users turn
            var playerNextTurn = players[1];

            // create a new game session
            var gameSession = Utilities.CreateGameSession(lexSessionAttributes.GameId, Convert.ToDateTime(lexSessionAttributes.GameStartDate), playerNextTurn, players, stubCards, totalPlayers, _uriToS3Bucket);

            // add game session to the database
            var databaseItem = new DatabaseItem {
                GameId        = gameSession.GameId,
                GameStartDate = gameSession.GameStartDate.ToString("s"),
                GameSession   = JsonConvert.SerializeObject(gameSession)
            };

            _logger.LogInfo($"databaseItem {JsonConvert.SerializeObject(databaseItem)}");
            _logger.LogInfo($"databaseItemd {JsonConvert.SerializeObject(databaseItem.ToDictionary())}");
            await _dependencyProvider.DynamoDbPutItemAsync(databaseItem.ToDictionary());

            // return message to user
            var response = Utilities.CustomResponseElicitIntent(Dialogue.ReadyToPlay, lexSessionAttributes);

            return(response);
        }
예제 #7
0
        public async Task <LexLambdaResponse> Run(LexLambdaInputEvent lexInputEvent)
        {
            // lex session
            if (lexInputEvent.SessionAttributes == null || !lexInputEvent.SessionAttributes.TryGetValue("game_id", out var gameId))
            {
                gameId = Guid.NewGuid().ToString();
            }
            _logger.LogInfo($"gameId {gameId}");

            if (lexInputEvent.SessionAttributes == null || !lexInputEvent.SessionAttributes.TryGetValue("game_start_date", out var gameStartDate))
            {
                gameStartDate = DateTime.Now.ToString("s");
            }

            // check if there's a game in session
            var lexGameSession = new Dictionary <string, AttributeValue> {
                ["game_id"] = new AttributeValue {
                    S = gameId
                }
            };
            var gameSessionResponse = await _dependencyProvider.DynamoDbGetItemAsync(lexGameSession);

            var gameInSession = gameSessionResponse.Item.Count > 0;

            // =====================
            // Check for game over
            // =====================
            if (gameInSession && gameSessionResponse.Item.TryGetValue("game_winner", out AttributeValue gameWinnerAttribute))
            {
                // return message to user
                return(Utilities.CustomResponseClose(gameWinnerAttribute.S));
            }
            GameSession gameSession = null;

            // set existing or set new game session
            if (gameInSession && gameSessionResponse.Item.TryGetValue("game_session", out var gameSessionString))
            {
                gameSession = JsonConvert.DeserializeObject <GameSession>(gameSessionString.S);
                _logger.LogInfo($"gameSession {JsonConvert.SerializeObject(gameSession)}");
            }
            lexInputEvent.CurrentIntent.Slots.TryGetValue("GoFishCard", out var cardRequested);
            if (cardRequested != null)
            {
                _logger.LogInfo($"cardRequested {JsonConvert.SerializeObject(cardRequested)}");
            }

            // proxy request
            LexLambdaResponse response;

            switch (lexInputEvent.CurrentIntent.Name)
            {
            case "NewGame":
                var newGame = new NewGame(_dependencyProvider, _logger, _uriToCardImage);
                response = await newGame.Run(gameId, gameStartDate);

                break;

            case "AskForCard":
                if (gameInSession && gameSession != null)
                {
                    var askForCard = new AskForCard(_dependencyProvider, _logger);
                    response = await askForCard.Run(gameSession, cardRequested);
                }
                else
                {
                    response = Utilities.CustomResponseClose(Dialogue.NoGameInSession);
                }
                break;

            case "GoFish":
                if (gameInSession && gameSession != null)
                {
                    var goFish = new Intents.GoFish(_dependencyProvider, _logger);
                    response = await goFish.Run(gameSession);
                }
                else
                {
                    response = Utilities.CustomResponseClose(Dialogue.NoGameInSession);
                }
                break;

            case "GiveUpCard":
                if (gameInSession && gameSession != null)
                {
                    var giveUpCard = new GiveUpCard(_dependencyProvider, _logger);
                    response = await giveUpCard.Run(gameSession, cardRequested);
                }
                else
                {
                    response = Utilities.CustomResponseClose(Dialogue.NoGameInSession);
                }
                break;

            case "Score":
                if (gameInSession && gameSession != null)
                {
                    var score = new Score(_dependencyProvider, _logger);
                    response = await score.Run(gameSession);
                }
                else
                {
                    response = Utilities.CustomResponseClose(Dialogue.NoGameInSession);
                }
                break;

            case "EndGame":
                var endGame = new EndGame(_dependencyProvider, _logger);
                response = await endGame.Run(gameSession);

                break;

            default:
                if (gameInSession)
                {
                    var lexSessionAttributes = LexSessionAttributes.GoFishLexSession(gameId, gameStartDate);
                    response = Utilities.CustomResponseElicitIntent(Dialogue.NoIntentFound, lexSessionAttributes);
                }
                else
                {
                    response = Utilities.CustomResponseClose(Dialogue.NoGameInSession);
                }
                break;
            }
            _logger.LogInfo($"response {JsonConvert.SerializeObject(response)}");
            return(response);
        }
예제 #8
0
 public static LexLambdaResponseTypeElicitIntent CustomResponseElicitIntent(string message, LexSessionAttributes sessionAttributes = null)
 {
     return(new LexLambdaResponseTypeElicitIntent {
         DialogAction = new LexLambdaResponseDialogActionTypeElicitIntent {
             Message = new LexLambdaResponseMessage {
                 Content = message,
                 ContentType = "PlainText"
             },
             Type = "ElicitIntent"
         },
         SessionAttributes = sessionAttributes == null ? new Dictionary <string, string>() : sessionAttributes.ToDictionary()
     });
 }