/// <inheritdoc />
        public override async Task GetShot(Guid _, string __, IReadOnlyBoard ___, Shoot shoot)
        {
            // Return a random shot between A1 and J10
            var rand = new Random();

            await shoot($"{(char)('A' + rand.Next(10))}{rand.Next(1, 11)}");
        }
Beispiel #2
0
        /// <inheritdoc />
        public override async Task GetShot(Guid _, string __, IReadOnlyBoard ___, Shoot shoot)
        {
            // Return a random shot between A1 and J10
            var rand = new Random();

            await shoot(new BoardIndex(rand.Next(10), rand.Next(10)));
        }
Beispiel #3
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (playerId != targetId && !String.IsNullOrWhiteSpace(playerTeam) && !String.IsNullOrWhiteSpace(targetTeam) && playerTeam == targetTeam && special == Specials.NukeField)
     {
         Achieve();
     }
 }
Beispiel #4
0
 /// <summary>
 /// Convert a battleship board into a compact string
 /// </summary>
 /// <param name="board">Board to convert</param>
 /// <returns>
 /// String in which each letter represents one board sqare.
 /// </returns>
 public static string ToShortString(this IReadOnlyBoard board) =>
 string.Create(100, board, (buf, content) =>
 {
     for (var i = 0; i < 100; i++)
     {
         buf[i] = BoardContentJsonConverter.SquareContentToChar(content[new BoardIndex(i)]);
     }
 });
Beispiel #5
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (playerId != targetId && _specialsUsed.ContainsKey(special))
     {
         _specialsUsed[special].UsedOnOpponent = true;
         CheckAchieved();
     }
 }
Beispiel #6
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     // TODO: check team ???
     if (targetId != playerId && special == Specials.NukeField)
     {
         _nukeUsed = true;
     }
 }
Beispiel #7
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (special == Specials.BlockBomb)
     {
         int targetBomb = targetBoard.ReadOnlyCells.Count(x => CellHelper.GetSpecial(x) == Specials.BlockBomb);
         if (targetBomb >= 3)
         {
             Achieve();
         }
     }
 }
Beispiel #8
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (special == Special)
     {
         _count++;
         if (_count == CountToAchieve)
         {
             Achieve();
         }
     }
 }
Beispiel #9
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (_specialsUsed.ContainsKey(special))
     {
         _specialsUsed[special] = true;
         if (_specialsUsed.All(pair => pair.Value))
         {
             Achieve();
         }
     }
 }
Beispiel #10
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (playerId == targetId && special == Specials.NukeField)
     {
         int spawnX = playerBoard.PieceSpawnX;
         int topY   = playerBoard.Height - 2;
         if (playerBoard[spawnX, topY] != CellHelper.EmptyCell)
         {
             Achieve();
         }
     }
 }
Beispiel #11
0
        /// <inheritdoc />
        public override async Task GetShot(Guid gameId, string __, IReadOnlyBoard board, Shoot shoot)
        {
            if (!indexes.TryGetValue(gameId, out BoardIndex ix))
            {
                ix = indexes[gameId] = new BoardIndex();
            }

            // Shoot at first current square
            await shoot(ix);

            indexes[gameId]++;
        }
 /// <summary>
 /// Convert a battleship board into a compact string
 /// </summary>
 /// <param name="board">Board to convert</param>
 /// <returns>
 /// String in which each letter represents one board sqare.
 /// </returns>
 public static string ToShortString(this IReadOnlyBoard board) =>
 string.Create(100, board, (buf, content) =>
 {
     for (var i = 0; i < 100; i++)
     {
         buf[i] = content[new BoardIndex(i)] switch
         {
             SquareContent.Water => 'W',
             SquareContent.Ship => 'S',
             SquareContent.HitShip => 'H',
             SquareContent.SunkenShip => 'X',
             SquareContent.Unknown => ' ',
             _ => throw new InvalidOperationException("Invalid square content, should never happen!")
Beispiel #13
0
        /// <inheritdoc />
        public override async Task GetShot(Guid _, string __, IReadOnlyBoard board, Shoot shoot)
        {
            var ix = new BoardIndex();

            // Find next unknown square
            while (board[ix] != SquareContent.Unknown)
            {
                ix = ix.Next();
            }

            // Shoot at first unknonwn square
            await shoot(ix);
        }
        public void Print(IReadOnlyBoard board)
        {
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Console.Write(board.GetSignAt(i, j));
                }

                Console.WriteLine();
            }

            Console.WriteLine();
        }
Beispiel #15
0
        public static List <ChessPiece> AllPieces(this IReadOnlyBoard readOnlyBoard)
        {
            List <ChessPiece> listy = new List <ChessPiece>();

            foreach (ChessPiece chessPiece in readOnlyBoard)
            {
                if (chessPiece != ChessPiece.None)
                {
                    listy.Add(chessPiece);
                }
            }

            return(listy);
        }
Beispiel #16
0
        /// <inheritdoc />
        public override async Task GetShot(Guid _, string __, IReadOnlyBoard board, Shoot shoot)
        {
            var rand = new Random();

            while (true)
            {
                var ix = new BoardIndex(rand.Next(10), rand.Next(10));
                if (board[ix] == SquareContent.Unknown)
                {
                    await shoot(ix);

                    break;
                }
            }
        }
Beispiel #17
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     if (special == Specials.BlockGravity)
     {
         _gravity = true;
     }
     if (special == Specials.LeftGravity)
     {
         _leftGravity = true;
     }
     if (_gravity && _leftGravity)
     {
         Achieve();
     }
 }
Beispiel #18
0
        private int CalculateScore(IReadOnlyBoard readOnlyBoard, Player player)
        {
            var score = 0;
            Dictionary <ChessPiece, int> dictionaryToUseForScore = player == Player.White ? ScoresForWhite : ScoresForBlack;

            foreach (ChessPiece piece in readOnlyBoard)
            {
                if (piece.BelongsToWhite())
                {
                    score += dictionaryToUseForScore[piece];
                }
                else if (piece.BelongsToBlack())
                {
                    score += dictionaryToUseForScore[piece];
                }
            }

            return(score);
        }
Beispiel #19
0
        /// <inheritdoc />
        public override async Task GetShot(Guid gameId, string __, IReadOnlyBoard board, Shoot shoot)
        {
            BoardIndex ix;

            if (LastShot == null)
            {
                // Player did not shoot before
                ix = new BoardIndex();
            }
            else
            {
                // Player did shoot before. Take location of last shot and increment it by one.
                ix = (BoardIndex)LastShot;
                ix++;
            }

            // Shoot at current square
            await shoot(ix);
        }
Beispiel #20
0
 public override void OnRoundFinished(int lineCompleted, int level, int moveCount, int score, IReadOnlyBoard board, IReadOnlyCollection <Pieces> collapsedPieces)
 {
     _lineCount += lineCompleted;
     if (_lineCount >= CountToAchieve)
     {
         Achieve();
     }
 }
Beispiel #21
0
 public override void OnRoundFinished(int lineCompleted, int level, int moveCount, int score, IReadOnlyBoard board, IReadOnlyCollection <Pieces> collapsedPieces)
 {
     if (board.ReadOnlyCells.All(x => x == CellHelper.EmptyCell))
     {
         Achieve();
     }
 }
 public bool IsGameOver(IReadOnlyBoard board)
 => board.NonEmptyFields
 .GroupBy(field => field.X)
 .Any(group =>
      @group.Count() == 3 &&
      @group.Select(field => field.Sign).Distinct().Count() == 1);
Beispiel #23
0
 public override void OnRoundFinished(int lineCompleted, int level, int moveCount, int score, IReadOnlyBoard board, IReadOnlyCollection <Pieces> collapsedPieces)
 {
     if (lineCompleted == LineCount)
     {
         _count++;
         if (_count == CountToAchieve)
         {
             Achieve();
         }
     }
     else if (lineCompleted > 0)
     {
         _count = 0;
     }
 }
Beispiel #24
0
 public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
     _specialCount++;
     IsFailed = true;
 }
Beispiel #25
0
 public virtual void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
 }
Beispiel #26
0
 /// <summary>
 /// Gets the next shot from the player.
 /// </summary>
 /// <param name="gameId">Unique identifier of the current game</param>
 /// <param name="opponent">identifier of the opponent</param>
 /// <param name="board">Current board content</param>
 /// <param name="shoot">Callback with which the method has to do the shooting</param>
 /// <remarks>
 /// <para>
 /// The method has to call <paramref name="shoot"/> exactly once before returning.
 /// </para>
 /// <para>
 /// The method has to finish within 250ms.
 /// </para>
 /// <para>
 /// The method is not expected to throw an exception.
 /// </para>
 /// <para>
 /// Players have to be stateless. During a battle, a new player might be instantiated
 /// at any time, maybe even for every shot. If the player needs state, it has to store
 /// its state externally (e.g. file on disk).
 /// </para>
 /// <para>
 /// The <paramref name="gameId"/> will stay the same during a single game between two players.
 /// </para>
 /// </remarks>
 public abstract Task GetShot(Guid gameId, string opponentId, IReadOnlyBoard board, Shoot shoot);
Beispiel #27
0
        /// <summary>
        /// Find out whether there is a ship on a given location and return its boundaries
        /// </summary>
        /// <param name="board">Board on which to find the ship</param>
        /// <param name="ix">Location to check</param>
        /// <param name="shipRange">Boundaries of the found ship</param>
        /// <returns>
        /// The method returns <see cref="ShipFindingResult.NoShip"/> if there is no ship on the specified cell.
        /// It returns <see cref="ShipFindingResult.PartialShip"/> if there is a ship on the specified cell, but it
        /// cannot be said for sure how long it is (because of <see cref="SquareContent.Unknown"/> cells in front or
        /// behind the ship). If a ship was found and the size of the ship could be determined, the function returns
        /// <see cref="ShipFindingResult.CompleteShip"/>.
        /// </returns>
        public static ShipFindingResult TryFindShip(this IReadOnlyBoard board, BoardIndex ix, out BoardIndexRange shipRange)
        {
            // Note pattern matching

            if (board[ix] is not SquareContent.HitShip and not SquareContent.Ship)
            {
                // No ship at specified index
                shipRange = new BoardIndexRange();
                return(ShipFindingResult.NoShip);
            }

            // Note local method returning tuple

            (BoardIndex ix, bool complete) FindShipEdge(BoardIndex current, Direction direction, bool prev)
            {
                bool canMoveFurther;

                do
                {
                    BoardIndex next;
                    if (prev)
                    {
                        canMoveFurther = current.TryPrevious(direction, out next);
                    }
                    else
                    {
                        canMoveFurther = current.TryNext(direction, out next);
                    }

                    if (canMoveFurther)
                    {
                        current = next;
                    }
                }while (canMoveFurther && board[current] is not SquareContent.Water and not SquareContent.Unknown);

                var complete = board[current] is not SquareContent.Unknown;

                if (board[current] is not SquareContent.Water and not SquareContent.Unknown)
                {
                    return(current, complete);
                }

                if (!prev)
                {
                    return(direction == Direction.Horizontal ? current.PreviousColumn() : current.PreviousRow(), complete);
                }

                return(direction == Direction.Horizontal ? current.NextColumn() : current.NextRow(), complete);
            }

            // Note local method receiving tuple

            bool TryDirection(Direction direction, out (BoardIndexRange range, ShipFindingResult complete) result)
            {
                var(beginningIx, beginningComplete) = FindShipEdge(ix, direction, true);
                var(endIx, endComplete)             = FindShipEdge(ix, direction, false);
                result = (new BoardIndexRange(beginningIx, endIx),
                          beginningComplete&& endComplete ? ShipFindingResult.CompleteShip : ShipFindingResult.PartialShip);
                return(result.range.Length > 1);
            }

            // Go left and find first water
            if (TryDirection(Direction.Horizontal, out var resultHorizontal))
            {
                shipRange = resultHorizontal.range;
                return(resultHorizontal.complete);
            }

            // Note discard operator to indicate that result is not relevant

            _         = TryDirection(Direction.Vertical, out var resultVertical);
            shipRange = resultVertical.range;
            return(resultVertical.complete);
        }
Beispiel #28
0
 public virtual void OnSpecialUsed(int playerId, int sourceId, string sourceTeam, IReadOnlyBoard sourceBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special)
 {
 }
Beispiel #29
0
 public virtual void OnRoundFinished(int lineCompleted, int level, int moveCount, int score, IReadOnlyBoard board, IReadOnlyCollection <Pieces> collapsedPieces)
 {
 }
 public bool IsGameOver(IReadOnlyBoard board)
 => board.NonEmptyFields
 .Where(field => field.X.Equals(2 - field.Y))
 .Select(field => field.Sign)
 .Distinct()
 .Count() == 1;