/// <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)}"); }
/// <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))); }
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(); } }
/// <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)]); } });
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(); } }
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; } }
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(); } } }
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(); } } }
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(); } } }
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(); } } }
/// <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!")
/// <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(); }
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); }
/// <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; } } }
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(); } }
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); }
/// <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); }
public override void OnRoundFinished(int lineCompleted, int level, int moveCount, int score, IReadOnlyBoard board, IReadOnlyCollection <Pieces> collapsedPieces) { _lineCount += lineCompleted; if (_lineCount >= CountToAchieve) { Achieve(); } }
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);
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; } }
public override void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special) { _specialCount++; IsFailed = true; }
public virtual void OnUseSpecial(int playerId, string playerTeam, IReadOnlyBoard playerBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special) { }
/// <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);
/// <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); }
public virtual void OnSpecialUsed(int playerId, int sourceId, string sourceTeam, IReadOnlyBoard sourceBoard, int targetId, string targetTeam, IReadOnlyBoard targetBoard, Specials special) { }
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;