private void ThrowIfGameNotExists(GameDomainModel game)
 {
     if (!_games.ContainsKey(game.Id))
     {
         throw GetDefaultException();
     }
 }
        public Task <GameStatsDomainModel> GetGameStats(GameDomainModel game)
        {
            ThrowIfGameNotExists(game);

            GameDomainModel localGame = _games.GetOrAdd(game.Id, id => throw GetDefaultException());

            _shots.TryGetValue(game.Id, out var localShots);
            _ships.TryGetValue(game.Id, out var localShips);

            ShipDomainModel[] destroed = localShips is null
                ? Array.Empty <ShipDomainModel>()
                : localShips.Where(s => s.Health == 0).ToArray();

            ShipDomainModel[] knoked = localShips is null
                ? Array.Empty <ShipDomainModel>()
                : localShips.Except(destroed).Where(s => s.Health != s.MaxHealth).ToArray();

            var shipCount = localShips?.Count ?? 0;
            var shotCount = localShots?.Count ?? 0;

            bool ended = shipCount == destroed.Length;
            var  stats = new GameStatsDomainModel(shipCount, destroed.Length, knoked.Length, shotCount, ended);

            return(Task.FromResult(stats));
        }
        public Task AddShot(GameDomainModel game, ShotDomainModel shot, ShipDomainModel ship = null)
        {
            ThrowIfGameNotExists(game);

            var localShot = new ShotDomainModel(new Point(shot.Point.X, shot.Point.Y));

            _shots.AddOrUpdate(game.Id, new List <ShotDomainModel> {
                localShot
            }, (id, list) =>
            {
                list.Add(localShot);
                return(list);
            });

            if (ship != null)
            {
                _ = _ships.AddOrUpdate(game.Id, id => throw GetDefaultException(), (id, list) =>
                {
                    ShipDomainModel oldShip = list.Where(s => s.Id == ship.Id).Single();
                    ShipDomainModel newShip = oldShip.With(shot);
                    list.Remove(oldShip);
                    list.Add(newShip);

                    return(list);
                });
            }

            return(Task.CompletedTask);
        }
示例#4
0
        public static List <GameDomainModel> GenerateGames()
        {
            var games = new List <GameDomainModel>();

            foreach (GameType sportType in Enum.GetValues(typeof(GameType)))
            {
                var teamNames = GetRandomTeamNames();

                for (var i = 0; i < teamNames.Length - 1; i += 2)
                {
                    var game = new GameDomainModel()
                    {
                        FirstTeamName    = GetNamePrefixBySportType(sportType) + teamNames[i],
                        SecondTeamName   = GetNamePrefixBySportType(sportType) + teamNames[i + 1],
                        DateTimeStarting = GetRandomTime(),
                        GameType         = sportType
                    };

                    game.AddCoeficients(GenerateRandomCoefficients());

                    games.Add(game);
                }
            }

            return(games);
        }
        public Task AddGame(int size)
        {
            long            id   = Interlocked.Increment(ref gameId);
            GameDomainModel game = new GameDomainModel(id, size, false, false);

            _games.AddOrUpdate(id, game, (id, g) => game);

            return(Task.CompletedTask);
        }
        // TODO UnitOfWork
        public async Task AddShips(ShipsCreationModel creationModel)
        {
            IReadOnlyCollection <ShipDomainModel> ships = _coordinatesParser.ParseShipsCoordinates(creationModel.Coordinates);
            GameDomainModel game = await GetActiveGame();

            ThrowIfCanNotAddShips(game, ships);

            await _gameStateRepository.AddShips(game, ships);
        }
示例#7
0
        public void Game_should_not_be_played_before_started()
        {
            var game = new GameDomainModel()
            {
                DateTimePlayed   = DateTime.Now.AddSeconds(-1),
                DateTimeStarting = DateTime.Now
            };

            Assert.Throws <Exception>(() => game.ErrorCheck());
        }
示例#8
0
        public async Task AddShips_WhenGameEnded_ThrowException()
        {
            TestClass service    = Create();
            var       activeGame = new GameDomainModel(id: 1, size: 1, init: false, ended: true);

            A.CallTo(() => service.GameStateRepository.GetActiveGames())
            .Returns(new[] { activeGame });

            await Assert.ThrowsAsync <DataValidationException>(() => service.AddShips(new ShipsCreationModel("")));
        }
        public Task FinishGame(GameDomainModel game)
        {
            ThrowIfGameNotExists(game);

            _ = _games.Remove(game.Id, out GameDomainModel _);
            _ = _shots.Remove(game.Id, out List <ShotDomainModel> _);
            _ = _ships.Remove(game.Id, out List <ShipDomainModel> _);

            return(Task.CompletedTask);
        }
示例#10
0
        public void Game_should_not_have_score_if_not_played()
        {
            var game = new GameDomainModel()
            {
                FirstTeamScore  = 3,
                SecondTeamScore = 2
            };

            Assert.Throws <Exception>(() => game.ErrorCheck());
        }
        public async Task <GameStatsModel> GetGameStats()
        {
            GameDomainModel game = await GetActiveGame();

            GameStatsDomainModel stats = await _gameStateRepository.GetGameStats(game);

            GameStatsModel result = _modelMapper.Map(stats);

            return(result);
        }
示例#12
0
        public Task FinishGame(GameDomainModel game)
        {
            GameEntity gameEntity = new GameEntity
            {
                Id       = game.Id,
                Finished = true
            };

            _context.Entry(gameEntity).Property(x => x.Finished).IsModified = true;

            return(_context.SaveChangesAsync());
        }
示例#13
0
        public Task EndGame(GameDomainModel board)
        {
            GameEntity entity = new GameEntity
            {
                Id    = board.Id,
                Ended = true
            };

            _context.Entry(entity).Property(x => x.Ended).IsModified = true;

            return(_context.SaveChangesAsync());
        }
        public Task EndGame(GameDomainModel game)
        {
            ThrowIfGameNotExists(game);

            _games.AddOrUpdate(
                game.Id,
                id => throw GetDefaultException(),
                (id, g) => new GameDomainModel(g.Id, g.Size, g.Init, true)
                );

            return(Task.CompletedTask);
        }
        public Task <ShotDomainModel> TryGetShot(GameDomainModel game, int x, int y)
        {
            ThrowIfGameNotExists(game);

            _shots.TryGetValue(game.Id, out var localShots);

            var shot = localShots?
                       .Where(s => s.Point.X == x)
                       .Where(s => s.Point.Y == y)
                       .FirstOrDefault();

            return(Task.FromResult(shot));
        }
示例#16
0
        public Task AddShot(GameDomainModel game, ShotDomainModel shot, ShipDomainModel ship = null)
        {
            ShotEntity shotEntity = new ShotEntity
            {
                ShipId = ship?.Id,
                GameId = game.Id,
                X      = shot.Point.X,
                Y      = shot.Point.Y
            };

            _context.Shots.Add(shotEntity);

            return(_context.SaveChangesAsync());
        }
示例#17
0
        public async Task <ShotDomainModel> TryGetShot(GameDomainModel game, int x, int y)
        {
            ShotEntity entity = await _context.Shots
                                .Where(shot => shot.GameId == game.Id)
                                .Where(shot => shot.X == x)
                                .Where(shot => shot.Y == y)
                                .OrderBy(shot => shot.Id)
                                .AsNoTracking()
                                .FirstOrDefaultAsync();

            if (entity is null)
            {
                return(null);
            }

            return(new ShotDomainModel(new Point(entity.X, entity.Y)));
        }
 private void ThrowIfCanNotAddShips(GameDomainModel game, IEnumerable <ShipDomainModel> ships)
 {
     if (game.Init)
     {
         throw new DataValidationException("Sheeps was already added.");
     }
     if (game.Ended)
     {
         throw new DataValidationException("The game is over.");
     }
     if (!game.CanAddShips(ships))
     {
         // TODO if needs to get specific errors, then you need to add a service to the domain
         //      that will calculate the result of adding ships
         throw new DataValidationException("The specified ships cannot be added to the game.");
     }
 }
        public Task AddShips(GameDomainModel game, IReadOnlyCollection <ShipDomainModel> ships)
        {
            ThrowIfGameNotExists(game);

            IEnumerable <ShipDomainModel> localShips = ships.Select(ship => ship.With(Interlocked.Increment(ref shipId)));

            _ships.AddOrUpdate(game.Id, localShips.ToList(), (id, list) =>
            {
                list.AddRange(localShips);
                return(list);
            });

            var newGame = new GameDomainModel(game.Id, game.Size, true, game.Ended);

            _games.AddOrUpdate(game.Id, id => newGame, (id, g) => newGame);

            return(Task.CompletedTask);
        }
        private async Task ThrowIfShotCanNotAdded(ShotDomainModel shot, GameDomainModel game)
        {
            if (!game.Init)
            {
                throw new DataValidationException("The game is not ready to play.");
            }
            if (game.Ended)
            {
                throw new DataValidationException("The game is ended.");
            }
            if (!game.CanTakeShot(shot))
            {
                throw new DataValidationException("The shot does not match the parameters of the game.");
            }

            ShotDomainModel existShot = await _gameStateRepository.TryGetShot(game, shot.Point.X, shot.Point.Y);

            if (existShot != null)
            {
                throw new DataValidationException("You can not repeat shots.");
            }
        }
        // TODO UnitOfWork
        public async Task <ShotResultModel> Shot(ShotModel shotModel)
        {
            ShotDomainModel shot = _coordinatesParser.ParseCoordinate(shotModel.Coord);
            GameDomainModel game = await GetActiveGame();

            await ThrowIfShotCanNotAdded(shot, game);

            ShipDomainModel ship = await TryKnockShip(game, shot);

            await _gameStateRepository.AddShot(game, shot, ship);

            GameStatsDomainModel stats = await _gameStateRepository.GetGameStats(game);

            if (stats.IsEnded)
            {
                await _gameStateRepository.EndGame(game);
            }

            return(ship is null
                ? _modelMapper.CreateShotResult(stats)
                : _modelMapper.CreateShotResult(ship.With(shot), stats));
        }
示例#22
0
        public Task AddShips(GameDomainModel game, IReadOnlyCollection <ShipDomainModel> ships)
        {
            GameEntity gameEntity = new GameEntity
            {
                Id   = game.Id,
                Init = true
            };

            IEnumerable <ShipEntity> entities = ships.Select(ship => new ShipEntity
            {
                GameId = game.Id,
                XStart = ship.Start.X,
                YStart = ship.Start.Y,
                XEnd   = ship.End.X,
                YEnd   = ship.End.Y
            });

            _context.Entry(gameEntity).Property(game => game.Init).IsModified = true;
            _context.Ships.AddRange(entities);

            return(_context.SaveChangesAsync());
        }
示例#23
0
        public async Task <GameStatsDomainModel> GetGameStats(GameDomainModel game)
        {
            long gameId = game.Id;

            int shotsCount = await _context.Games
                             .Where(game => game.Id == gameId)
                             .SelectMany(game => game.Shots)
                             .CountAsync();

            List <ShipEntity> shipsEntities = await _context.Ships
                                              .Where(ship => ship.GameId == gameId)
                                              .Include(ship => ship.Shots)
                                              .OrderBy(ship => ship.Id)
                                              .AsNoTracking()
                                              .AsSplitQuery()
                                              .ToListAsync();

            List <ShipDomainModel> ships    = shipsEntities.Select(CreateShip).ToList();
            List <ShipDomainModel> destroed = ships.Where(s => s.Health == 0).ToList();
            List <ShipDomainModel> knoked   = ships.Except(destroed).Where(s => s.Health != s.MaxHealth).ToList();
            bool ended = ships.Count == destroed.Count;

            return(new GameStatsDomainModel(ships.Count, destroed.Count, knoked.Count, shotsCount, ended));
        }
示例#24
0
 public async Task AddShips_WhenGameSuitable_InvokeRepo()
 {
     TestClass service    = Create();
     var       activeGame = new GameDomainModel(id: 1, size: 1, init: false, ended: false);
     var       call       = A.CallTo(() => service.GameStateRepository.AddShips(default, default)).WithAnyArguments();
示例#25
0
        public void CanAddShips_WhenArgIsNull_ReturnTrue()
        {
            var model = new GameDomainModel(id: 7, size: 10, init: false, ended: false);

            var result = model.CanAddShips(default);
示例#26
0
        public void Game_should_not_have_two_same_types_of_coefficients()
        {
            var game = new GameDomainModel();

            Assert.Throws <Exception>(() => game.AddCoeficients(new CoefficientDomainModel[] { new CoefficientDomainModel(BetType.One, 3), new CoefficientDomainModel(BetType.One, 2) }));
        }
 public SearchShipCriteria(GameDomainModel game, Point coordinate)
 {
     Game       = game.NotNull(nameof(game));
     Coordinate = coordinate.NotNull(nameof(coordinate));
 }
        public async Task FinishGame()
        {
            GameDomainModel game = await GetActiveGame();

            await _gameStateRepository.FinishGame(game);
        }
        private Task <ShipDomainModel> TryKnockShip(GameDomainModel game, ShotDomainModel shot)
        {
            SearchShipCriteria criteria = new SearchShipCriteria(game, shot.Point);

            return(_gameStateRepository.TryGetShip(criteria));
        }