/// <summary>
        /// Simulates the battle between the attacking army and the defending army.
        /// </summary>
        /// <returns>A <see cref="BattleResult"/> representing the result of the battle.</returns>
        public BattleResult Simulate()
        {
            // Instantiate the list of round results.
            var rounds = new List <RoundResult>();

            // Simulate battle rounds until:
            //   1) A winner has been declared (attacker, defender, or tie), or
            //   2) Neither side is able to hit the other, at which point the simulation is stopped with no winner declared.
            while (Winner() == BattleWinner.None)
            {
                // Simulate a battle round.
                var result = DoRound();
                rounds.Add(result);

                // Check if neither side was able to hit the other. If so, stop the simulation.
                if (result.AttackerResult.TotalEffectiveHits == 0 &&
                    result.DefenderResult.TotalEffectiveHits == 0 &&
                    FireResult.Safe(result.AttackerSurpriseResult).TotalEffectiveHits == 0 &&
                    FireResult.Safe(result.DefenderSurpriseResult).TotalEffectiveHits == 0)
                {
                    break;
                }
            }

            // Return an appropriate battle result.
            return(new BattleResult(rounds, Winner(), Attacker.Clone(), Defender.Clone()));
        }
Exemplo n.º 2
0
        public virtual async Task <FireResult> FireCannon(string gameId, int cellId)
        {
            GameState g = await FindActiveGameAsync(gameId);

            if (g == null)
            {
                return(null);
            }

            FireResult ret = new FireResult
            {
                IsHit = g.ServerBoard.Board[cellId] == (int)ServerCellState.CellHasShip
            };

            if (ret.IsHit)
            {
                var ship = g.ServerBoard.Ships.First(x => x.Cells.Any(c => c == cellId));
                ship.Hits++;
                if (ship.Hits == ship.Cells.Count())
                {
                    ret.ShipDestroyed = ship;
                }

                ret.IsGameOver = !g.ServerBoard.Ships.Any(x => x.Hits < x.Cells.Count());
            }
            else
            {
                g.IsAwaitingServerTurn = true;
            }

            await _storage.UpdateGameAsync(g);

            return(ret);
        }
 private static void PrintSurpriseStrikeResult(FireResult result, string side)
 {
     if (result != null)
     {
         Console.WriteLine($"{side} Surprise Hits: {result}");
     }
 }
Exemplo n.º 4
0
        public (int x, int y) GetNextMove(FireResult lastResult)
        {
            if (lastResult == FireResult.Hit && lastLastLastResult != FireResult.Hit)
            {
                initialHitX = targetX;
                initialHitY = targetY;
            }
            if (lastResult == FireResult.None)
            {
                targetX = firstMiddleX;
                targetY = firstMiddleY;
            }
            else if (lastResult == FireResult.Sink)
            {
                initialHitX = -1;
                initialHitY = -1;
                if (!MiddleComplete())
                {
                    SearchMiddle();
                }
                else
                {
                    SearchEdge();
                }
            }
            else if (lastResult == FireResult.Hit && lastResult != FireResult.Sink)
            {
                MoveDirection();
            }
            else if (lastResult == FireResult.Miss && lastLastResult == FireResult.Hit && lastLastLastResult == FireResult.Hit)
            {
                targetX = initialHitX;
                targetY = initialHitY;
                InvertDirection();
                MoveDirection();
            }
            else if (lastResult == FireResult.Miss && lastLastResult == FireResult.Hit)
            {
                InvertDirection();
                MoveDirection();
                InvertDirection();
                RotateDirection();
            }
            else
            {
                if (!MiddleComplete())
                {
                    SearchMiddle();
                }
                else
                {
                    SearchEdge();
                }
            }

            lastLastResult = lastResult;
            return(targetX, targetY);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Constructs a new <see cref="RoundResult"/> with the given attacking army, defending army, surprise strike results, and general
 /// fire results.
 /// </summary>
 /// <param name="attacker">The attacking army (at the beginning of the round).</param>
 /// <param name="defender">The defending army (at the beginning of the round).</param>
 /// <param name="attackerSurpriseResult">The result of the attacking army's surprise strike, or null if no surprise strike
 /// occurred.</param>
 /// <param name="defenderSurpriseResult">The result of the defending army's surprise strike, or null if no surprise strike
 /// occurred.</param>
 /// <param name="attackerResult">The result of the attacking army's general fire.</param>
 /// <param name="defenderResult">The result of the defending army's general fire.</param>
 public RoundResult(Army attacker, Army defender, FireResult attackerSurpriseResult,
                    FireResult defenderSurpriseResult, FireResult attackerResult, FireResult defenderResult)
 {
     Attacker = attacker;
     Defender = defender;
     AttackerSurpriseResult = attackerSurpriseResult;
     DefenderSurpriseResult = defenderSurpriseResult;
     AttackerResult         = attackerResult;
     DefenderResult         = defenderResult;
 }
Exemplo n.º 6
0
        //Called by client when its move
        public async Task <IActionResult> FireCannon([FromBody] FireCannonDto dto)
        {
            FireResult res = await _gameSvc.FireCannon(dto.GameId, dto.CellId);

            if (res == null)
            {
                return(BadRequest());
            }

            FireCannonResultDto respDto = _mapper.Map <FireCannonResultDto>(res);

            respDto.CellId = dto.CellId;
            respDto.GameId = dto.GameId;

            return(Ok(respDto));
        }
Exemplo n.º 7
0
        public void broadcastRPCMove(FireResult result, ConnectedPlayer playingPlayer)
        {
            RPCMove move;

            if (result.statusType == FireType.sunk)
            {
                move = new RPCMove(result.target, playingPlayer.color, Player.fireTypeToChar(result.statusType), result.ship.type, result.ship.startPos, result.ship.horizontal);
            }
            else
            {
                move = new RPCMove(result.target, playingPlayer.color, Player.fireTypeToChar(result.statusType), ShipType.battle);                  //Send Battleship if not sunk, because we don't wanna send all that sweet info just yet.
            }
            foreach (ConnectedClient c in clients)
            {
                protocol.sendRPCMove(c.peerID, move);
            }
        }
        public async Task FireCannon_BadRequest()
        {
            FireResult res         = null;
            var        gameService = new Mock <IGameService>();

            gameService.Setup(x => x.FireCannon(It.IsAny <string>(), It.IsAny <int>()))
            .ReturnsAsync(res);

            var inputDto = new FireCannonDto {
                CellId = 1, GameId = ""
            };

            var controller = new GameController(gameService.Object, _mapper, _statisticsSvcMock.Object);
            var output     = await controller.FireCannon(inputDto);

            Assert.AreEqual(output.GetType(), typeof(BadRequestResult));
        }
Exemplo n.º 9
0
        public (int x, int y) GetNextMove(FireResult lastResult)
        {
            if (lastResult == FireResult.None)
            {
                targetX = 0;
                targetY = 0;
            }
            else
            {
                targetX++;
                if (targetX >= MaxColumns)
                {
                    targetX = 0;
                    targetY++;
                }
            }

            return(targetX, targetY);
        }
Exemplo n.º 10
0
    public string onFireCommand(string col, string row)
    {
        if (gameState == GameState.END)
        {
            return("The game is over");
        }
        if (gameState == GameState.PLACEMENT)
        {
            return("Can't fire in placement phase");
        }
        int parsedCol;
        int parsedRow;

        try
        {
            parsedCol = getColumnFromUserInput(col);
            parsedRow = getRowFromUserInput(row);
        }
        catch (Exception e)
        {
            return(e.Message);
        }

        GridSpace playerTarget = aiBoard[parsedRow, parsedCol];

        if (playerTarget.hitState == HitState.HIT)
        {
            return("You have already hit this target, Additonaly strikes are not helpful");
        }
        if (playerTarget.hitState == HitState.MISS)
        {
            return("You have already confirmed there's no one there");
        }

        Coord aiCoords = AITargets[0];

        AITargets.RemoveAt(0);
        GridSpace aiTarget = userBoard[aiCoords.row, aiCoords.col];

        FireResult playerResult = ProcessMove(playerTarget, true, col, parsedRow);
        FireResult aiResult     = ProcessMove(aiTarget, false, null, null);

        if (playerResult == FireResult.WIN || aiResult == FireResult.WIN)
        {
            gameState = GameState.END;
        }

        if (playerResult == FireResult.WIN && aiResult == FireResult.WIN)
        {
            return("Both players have simultaneously died. Perhaps you will have better luck next time");
        }

        if (playerResult == FireResult.WIN)
        {
            return("All the enemy ships have been sunk. Congratulations on your victory!");
        }

        if (aiResult == FireResult.WIN)
        {
            return("All your ships have been sunk. Perhaps you will have better luck next time");
        }

        if (playerResult == FireResult.MISS && aiResult == FireResult.MISS)
        {
            return("You have both missed");
        }

        if (playerResult == FireResult.MISS && aiResult == FireResult.HIT)
        {
            return("You missed but the enemy has hit one of our ships");
        }


        if (playerResult == FireResult.MISS && aiResult == FireResult.SINK)
        {
            return("You missed but the enemy has sunk one of our ships");
        }

        if (playerResult == FireResult.HIT && aiResult == FireResult.MISS)
        {
            return("You hit and your enemy has missed");
        }

        if (playerResult == FireResult.HIT && aiResult == FireResult.HIT)
        {
            return("You have both hit ships");
        }


        if (playerResult == FireResult.HIT && aiResult == FireResult.SINK)
        {
            return("You hit the enemy they have sunk one of our ships");
        }

        if (playerResult == FireResult.SINK && aiResult == FireResult.MISS)
        {
            return("You sunk a ship and your enemy has missed");
        }

        if (playerResult == FireResult.SINK && aiResult == FireResult.HIT)
        {
            return("You sunk a ship but have been hit");
        }

        if (playerResult == FireResult.SINK && aiResult == FireResult.SINK)
        {
            return("You have both sunk ships");
        }

        return("IMPOSSIBLE OUTCOME");
    }
Exemplo n.º 11
0
    static void Main()
    {
        Console.InputEncoding  = System.Text.Encoding.UTF8;
        Console.OutputEncoding = System.Text.Encoding.UTF8;
        Console.WriteLine("========================================================================");
        Console.WriteLine("Моорской бой!");
        Console.WriteLine("========================================================================");
        Console.WriteLine();
appBegin:


        #region Перменные
        Player player1 = new Player("Компьютер1", (PlayerType)2);
        Player     player2    = new Player("Компьютер", (PlayerType)2);
        FireResult fireResult = FireResult.Miss;
        int        gameMode   = 0;
        #endregion

        #region Выбор игры
        Console.WriteLine($"Выберите против кого вы будете играть:\n0-человек против человека\n1-человек против робота" +
                          $"\n2-робот против робота");
inputOpp:
        try
        {
            gameMode = int.Parse(Console.ReadLine());
            if (gameMode == 0)
            {
                player1.Type = (PlayerType)1; player2.Type = (PlayerType)1;
            }
            else if (gameMode == 1)
            {
                player1.Type = (PlayerType)1;
            }
            else
            {
                player2.Name = "Компьютер2";
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine("Повторите:");
            goto inputOpp;
        }
        Game game = new Game(player1, player2, gameMode);
        #endregion

        #region Ввод имен пользователей
        if (player1.Type == PlayerType.Human)
        {
            Console.WriteLine($"Введите имя первого игрока:");
inputName1:
            try
            {
                player1.Name = Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine("Повторите:");
                goto inputName1;
            }
        }
        if (player2.Type == PlayerType.Human)
        {
            {
                Console.WriteLine($"Введите имя второго игрока:");
inputName2:
                try
                {
                    player2.Name = Console.ReadLine();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine("Повторите:");
                    goto inputName2;
                }
            }
        }
        #endregion

        #region ХОД ИГРЫ
        Console.WriteLine(game.Image());
        while (!game.IsFinal)
        {
            Console.WriteLine();
            string coords;
            if (game.CurrentPlayer.Type == PlayerType.Human)
            {
                Console.WriteLine($"Ходит {game.CurrentPlayer.Name}. Введите координаты ячейки:");
                coords = Console.ReadLine();
            }
            else
            {
                Console.WriteLine($"Ходит {game.CurrentPlayer.Name}:");
                coords = null;
                Console.ReadKey();
            }
            try { fireResult = game.Fire(game.CurrentPlayer, coords); }
            catch (Exception e)
            {
            }


            switch (fireResult)
            {
            case FireResult.Wound:
                Console.WriteLine("Ранен");
                break;

            case FireResult.Killed:
                Console.WriteLine("Убит");
                break;

            case FireResult.Double:
                Console.WriteLine("Ячейка уже бита");
                break;

            default:
                Console.WriteLine("Промах");
                break;
            }
            Console.WriteLine();
            Console.WriteLine(game.Image());
        }

        Console.ReadKey();
        #endregion

        #region Финиш
        Console.WriteLine("========================================================================");
        Console.WriteLine("Игра окончена.");
        if (game.Winner == null)
        {
            Console.WriteLine("Ничья!");
        }
        else
        {
            Console.WriteLine($"Победил {game.Winner.Name}");
        }
        #endregion
appExit:
        Console.WriteLine();
        Console.WriteLine("========================================================================");
        Console.WriteLine("Выйти из программы [y/n]?");
        if (Console.ReadLine().Trim().ToLower() == "n")
        {
            goto appBegin;
        }
    }
Exemplo n.º 12
0
    public FireResult Fire(Player player, string coords)
    {
        //        Sea currentPlayerSea = player == _player1 ? _playerOneSea : _playerTwoSea;
        Sea opponentPlayerSea = player == _player1 ? _playerTwoSea : _playerOneSea;


        if (IsFinal)
        {
            return(FireResult.GameFinished);
        }
        if (player.Type == PlayerType.None)
        {
            return(FireResult.NullPlayer);
        }
        if (player.Type == PlayerType.None)
        {
            player.Type = player.Type;
        }
        if (player.Type != player.Type)
        {
            return(FireResult.NotOrderPlayer);
        }

        FireResult playerFireResult = 0;

        if (player.Type == PlayerType.Human)
        {
            playerFireResult = opponentPlayerSea.Fire(coords);
            goto makeReturn;
        }

        int    fireCol   = 0;
        char   fireRow   = ' ';
        Cell   fireCell  = null;
        string rowLetter = "abcdefghij";

        if (_lastWoundShip.WoundCount == null)
        {
            do
            {
                fireRow  = rowLetter[Random.Next(0, 10)];
                fireCol  = Random.Next(0, 10);
                fireCell = opponentPlayerSea.Cells[fireRow + "" + fireCol];
            }while (fireCell.IsDead);

            playerFireResult = opponentPlayerSea.Fire(fireCell);
            if (playerFireResult == FireResult.Killed)
            {
                _lastWoundShip   = null;               //однопалубные корабли
                _lastWoundedCell = null;
            }
            else if (playerFireResult == FireResult.Wound)
            {
                _lastWoundedCell.Add(fireCell);

                if (fireCell.Col - 1 > 0)
                {
                    _fireCells.Add(opponentPlayerSea.Cells[fireCell.Row + "" + (fireCell.Col - 1)]);
                }
                if (fireCell.Row - 1 > 97)
                {
                    _fireCells.Add(opponentPlayerSea.Cells[fireCell.Row - 1 + "" + fireCell.Col]);
                }
                if (fireCell.Col + 1 < 107)
                {
                    _fireCells.Add(opponentPlayerSea.Cells[fireCell.Row + "" + (fireCell.Col + 1)]);
                }
                if (fireCell.Row + 1 < 10)
                {
                    _fireCells.Add(opponentPlayerSea.Cells[fireCell.Row + 1 + "" + fireCell.Col]);
                }
            }
            foreach (Ship ship in opponentPlayerSea.Ships)
            {
                if (!ship.Cells.Contains(fireCell))
                {
                    continue;
                }
                _lastWoundShip = ship;
            }
            goto makeReturn;
        }



        if (_lastWoundShip.WoundCount > 0)
        {
            if (_lastWoundShip.WoundCount == 1)
            {
                fireCell         = _fireCells[Random.Next(0, _fireCells.Count)]; _fireCells.Remove(fireCell);
                playerFireResult = opponentPlayerSea.Fire(fireCell);
                if (playerFireResult == FireResult.Killed)
                {
                    _lastWoundShip   = null;                   //однопалубные корабли
                    _lastWoundedCell = null;
                }
                else if (playerFireResult == FireResult.Wound)
                {
                    _orientation = _lastWoundShip.Orientation;
                    if (_lastWoundShip.Orientation == ShipOrientation.Horizontal)
                    {
                    }
                    if (fireCell._lastWoundedCell[_lastWoundedCell.Count - 1])
                    {
                        _lastWoundedCell.Add(fireCell);
                    }
                }
            }
            else
            {
                if (_lastWoundShip.Orientation == ShipOrientation.Horizontal)
                {
                    fireRow = _lastWoundedCell[_lastWoundedCell.Count - 1].Row;
                    fireCol = Random.Next(0, 2) == 0 ?
                              _lastWoundedCell[0].Col - 1 > 0 ? _lastWoundedCell[0].Col - 1 : _lastWoundedCell[_lastWoundedCell.Count - 1].Col + 1 :
                              _lastWoundedCell[_lastWoundedCell.Count - 1].Col + 1 < 10 ? _lastWoundedCell[_lastWoundedCell.Count - 1].Col + 1 : _lastWoundedCell[0].Col - 1;

                    fireCell = opponentPlayerSea.Cells[fireRow + "" + fireCol];
                }
                else
                {
                    fireCol = _lastWoundedCell[_lastWoundedCell.Count - 1].Col;
                    int rnd = Random.Next(0, 2);

                    if (rnd == 0)
                    {
                        if (_lastWoundedCell[_lastWoundedCell.Count - 1].Row - 1 > 96)
                        {
                            fireRow = (char)(_lastWoundedCell[_lastWoundedCell.Count - 1].Row - 1);
                        }
                        else
                        {
                            fireRow = (char)(_lastWoundedCell[_lastWoundedCell.Count - 1].Row + 1);
                        }
                    }
                    else
                    {
                    }

                    //fireRow = Random.Next(0, 2) == 0 ?
                    //	_lastWoundedCell[_lastWoundedCell.Count - 1].Row - 1 > 96 ? _lastWoundedCell[_lastWoundedCell.Count - 1].Row - 1 : _lastWoundedCell[_lastWoundedCell.Count - 1].Row + 1 :
                    //_lastWoundedCell[_lastWoundedCell.Count - 1].Row + 1 < 107 ? _lastWoundedCell[_lastWoundedCell.Count - 1].Row + 1 : _lastWoundedCell[_lastWoundedCell.Count - 1].Row - 1;

                    fireCell = opponentPlayerSea.Cells[fireRow + "" + fireCol];
                }
            }

            playerFireResult = opponentPlayerSea.Fire(fireCell);
            if (playerFireResult == FireResult.Wound)
            {
                _orientation = _lastWoundShip.Orientation;



                if (_orientation == ShipOrientation.Horizontal)
                {
                    int maxCellCol = 0;
                    foreach (Cell woundedCell in _lastWoundedCell)
                    {
                        if (fireCell.Col > woundedCell.Col)
                        {
                            maxCellCol = fireCell.Col;
                        }
                    }

                    if (fireCell.Col > _lastWoundedCell[_lastWoundedCell.Count - 1].Col)
                    {
                        _lastWoundedCell.Add(fireCell);
                    }
                    else
                    {
                        _lastWoundedCell.Insert(0, fireCell);
                    }
                }
                else
                {
                    if (fireCell.Row > _lastWoundedCell[_lastWoundedCell.Count - 1].Row)
                    {
                        _lastWoundedCell.Add(fireCell);
                    }
                    else
                    {
                        _lastWoundedCell.Insert(0, fireCell);
                    }
                }
            }



            int  prevCol = _lastWoundedCell[_lastWoundedCell.Count - 1].Col;
            char prevRaw = _lastWoundedCell[_lastWoundedCell.Count - 1].Row;
            if (prevCol < fireCell.Col || prevCol > fireCell.Col)
            {
                _orientation = ShipOrientation.Horizontal;
                if (_orientation == ShipOrientation.Horizontal)
                {
                }
            }
            else if (prevRaw < fireCell.Col || prevRaw > fireCell.Col)
            {
                _orientation = ShipOrientation.Horizontal;
            }
        }



makeFire:
        playerFireResult = opponentPlayerSea.Fire(fireCell);



makeReturn:
        if (playerFireResult == FireResult.Miss || playerFireResult == FireResult.Double || playerFireResult == FireResult.Killed || playerFireResult == FireResult.Wound)
        {
            if (_currentPlayer.Type == PlayerType.Human)
            {
                if (playerFireResult == FireResult.Miss || playerFireResult == FireResult.Double)
                {
                    CurrentPlayer = CurrentPlayer == Player1 ? Player2 : Player1;
                }
            }
            else
            {
                if (playerFireResult == FireResult.Killed)
                {
                    _lastWoundShip = null;
                }
                if (playerFireResult == FireResult.Double || playerFireResult == FireResult.Miss)
                {
                    CurrentPlayer = CurrentPlayer == Player1 ? Player2 : Player1;
                }
                if (playerFireResult == FireResult.Wound)
                {
                    _lastWoundedCell.Add(fireCell);
                }
            }


            int killedCount = 0;
            foreach (Ship ship in _playerOneSea.Ships)
            {
                if (ship.State == ShipState.Dead)
                {
                    killedCount++;
                }
            }
            if (killedCount == 10)
            {
                _isFinal = true; _winner = Player2; _loser = Player1; _lastWoundShip = null;
            }
            else
            {
                killedCount = 0;
                foreach (Ship ship in _playerTwoSea.Ships)
                {
                    if (ship.State == ShipState.Dead)
                    {
                        killedCount++;
                    }
                }
                if (killedCount == 10)
                {
                    _isFinal = true; _winner = Player1; _loser = Player2; _lastWoundShip = null;
                }
                else
                {
                    try { _loser.Type = PlayerType.None; }
                    catch (Exception e) { }
                }
            }
        }

        return(playerFireResult);
    }