public async Task <PlayGameView> Play(int numberOfBots, string userId) { if (numberOfBots <= 0) { throw new CustomServiceException("NumberOfBots is 0!"); } var player = await _playerRepository.GetByUserId(userId); var shuffledDeck = await _cardHelper.Shuffle(); var winner = "No one"; var bots = await _botRepository.GetAll(); if (bots.Count == 0) { throw new CustomServiceException("Bots doesn`t exist. Add bots on Data base!"); } var botList = bots .OrderBy(x => Guid.NewGuid()) .Take(numberOfBots) .ToList(); var game = new Game() { NumberOfBots = numberOfBots, Status = StatusType.New, Winner = winner }; var gameId = game.Id; var deck = shuffledDeck .Select(x => new Card() { GameId = gameId, Rank = x.Rank, Suit = x.Suit, }) .ToList(); var playerCard = GetPlayerCard(deck); var playerStep = new PlayerStep() { Rank = playerCard.Rank, Suit = playerCard.Suit, GameId = game.Id }; var botsCards = GetCardsOfBots(botList, deck); var botsSteps = GetBotSteps(botList, botsCards, gameId); var playerInGame = new PlayerInGame() { PlayerId = player.Id, GameId = game.Id, Score = GetCardValue(playerCard.Rank) }; var botInGame = botsSteps .Select(x => new BotInGame() { GameId = game.Id, BotId = x.BotId, Score = GetCardValue(x.Rank) }) .ToList(); var cardPlayGameViewItems = new List <CardPlayGameViewItem> { new CardPlayGameViewItem() { Rank = playerStep.Rank, Suit = playerStep.Suit } }; var groupedBotSteps = botsSteps.GroupBy(x => x.BotId); var response = new PlayGameView() { NumberOfBots = numberOfBots, Status = StatusType.New, Winner = winner, Player = new PlayerPlayGameView() { Name = player.Name, Cards = cardPlayGameViewItems }, Bots = groupedBotSteps .Select(botPlayGameViewItem => new BotPlayGameViewItem { Name = botList.FirstOrDefault(bot => bot.Id == botPlayGameViewItem.Key).Name, Cards = botPlayGameViewItem .Select(cardPlayGameViewItem => new CardPlayGameViewItem() { Rank = cardPlayGameViewItem.Rank, Suit = cardPlayGameViewItem.Suit }) .ToList() }) .ToList() }; await _gameRepository.Create(game); await _playerStepRepository.Create(playerStep); await _botStepRepository.CreateRange(botsSteps); await _playerInGameRepository.Create(playerInGame); await _botInGameRepository.CreateRange(botInGame); await _cardRepository.CreateRange(deck); return(response); }