예제 #1
0
        /// <summary>
        /// Gets the potentional coordinates for an attackMove from a checker.
        /// </summary>
        /// <param name="coordinate"></param>
        /// <returns></returns>
        public static IEnumerable <TileCoordinate> GetPotentionalAttackMoveCoordinatesForChecker(TileCoordinate coordinate)
        {
            List <TileCoordinate> possibleCoordinates = new List <TileCoordinate> {
                new TileCoordinate(coordinate.X - 1, coordinate.Y - 1),
                new TileCoordinate(coordinate.X + 1, coordinate.Y - 1),
                new TileCoordinate(coordinate.X - 1, coordinate.Y + 1),
                new TileCoordinate(coordinate.X + 1, coordinate.Y + 1),
            };

            return(possibleCoordinates.Where(c => c.IsValid()));
        }
예제 #2
0
 /// <summary>
 /// Return wherether the given coordinate is a valid one
 /// </summary>
 /// <param name="coordinate"></param>
 /// <returns>true if between the borders</returns>
 public static bool IsValid(TileCoordinate coordinate) => !(coordinate.X <MIN_X || coordinate.X> MAX_X || coordinate.Y <MIN_Y || coordinate.Y> MAX_Y);
예제 #3
0
        /// <summary>
        /// Get all potentional moves for a normal checker. these arn't checked for being valid.
        /// </summary>
        /// <param name="playerNumber"></param>
        /// <param name="coordinate"></param>
        /// <returns></returns>
        public static IEnumerable <TileCoordinate> GetPotentionalMovesForChecker(PlayerNumber playerNumber, TileCoordinate coordinate)
        {
            int y = coordinate.Y + ((playerNumber == PlayerNumber.One) ? 1 : -1);
            IEnumerable <TileCoordinate> possibleCoordinates = new int[] { coordinate.X - 1, coordinate.X + 1 }.Select(c => new TileCoordinate(c, y));

            return(possibleCoordinates.Where(c => c.IsValid()));
        }
예제 #4
0
        /// <summary>
        /// This method generates all possible moves for a given location. It will call itself recursively until the endlocation has no further moves left.
        /// </summary>
        /// <param name="checker"></param>
        /// <param name="startLocation"></param>
        /// <param name="originalStartLocation">This parameter is needed because otherwise the game thinks this tile is occupied, when in reality it isnt. defaults to checker.Coordinate</param>
        /// <param name="doneTiles"></param>
        /// <returns></returns>
        public IEnumerable <AttackMove> GetMovesForLocation(IGame game, IChecker checker, TileCoordinate startLocation, IPlayer currentPlayer, IPlayer enemyPlayer,
                                                            TileCoordinate?originalStartLocation, List <TileCoordinate> doneMoves = null)
        {
            List <AttackMove> moves = new List <AttackMove>();
            //get targets for attackmoves
            var potentionalMoves = checker.GetPotentionalMoveCoordinates(game, this, enemyPlayer: enemyPlayer, startingCoordinate: startLocation,
                                                                         movementType: MovementType.Attack);
            var attmoves = potentionalMoves[MovementType.Attack].Where(m => GetPlayerOwnedTiles(enemyPlayer.PlayerNumber).Select(t => t.Coordinate).Contains(m)).Except(doneMoves);

            foreach (var attmove in attmoves)
            {
                var direction          = TileCoordinate.GetStepDirection(startLocation, attmove);
                var targetCoordinate   = attmove;
                var locationsAfterJunp = GetPossibleMovesInDirectionAfterAttack(checker, targetCoordinate, direction);
                locationsAfterJunp = locationsAfterJunp.Where(l => l.IsValid());

                //for each possible location after the jump, this contains all moves afterattackmove
                foreach (var locationAfterJunp in locationsAfterJunp)
                {
                    var  tile = this.FirstOrDefault(t => t.Coordinate == locationAfterJunp);
                    bool locationAfterJunpFree = (tile.Coordinate == originalStartLocation ||                  //original location is always free, since the attacking checker started there
                                                  tile.Checker == null);
                    if (!locationAfterJunpFree)                    //if theres a checker on the final tile, go onto next potentional move
                    {
                        continue;
                    }

                    var targetChecker = this.FirstOrDefault(t => t.Coordinate == targetCoordinate).Checker;
                    doneMoves.Add(targetCoordinate);                    //add to donetiles, so the game knows it cant jump on it again this turn

                    IEnumerable <AttackMove> movesAfterJump = GetMovesForLocation(game, checker: checker, startLocation: locationAfterJunp,
                                                                                  currentPlayer: currentPlayer, enemyPlayer: enemyPlayer,
                                                                                  originalStartLocation: originalStartLocation, doneMoves: doneMoves);
                    movesAfterJump = movesAfterJump.GetOnlyHighestPriorityMoves();

                    AttackMove move = new AttackMove(checker, targetChecker, startLocation, locationAfterJunp, targetCoordinate, movesAfterJump.ToList());
                    moves.Add(move);
                }
            }
            return(moves);
        }
예제 #5
0
 public IEnumerable <AttackMove> GetMovesForLocation(IGame game, IChecker checker, TileCoordinate startLocation, IPlayer currentPlayer, IPlayer enemyPlayer, List <TileCoordinate> doneMoves)
 => GetMovesForLocation(game, checker, startLocation, currentPlayer, enemyPlayer, this.First(t => t.Checker == checker).Coordinate, doneMoves);
예제 #6
0
        /// <summary>
        /// calculates all possible locations to end after doing an attackmove. this is always 1 tile after for a normal checker, but for a king it checks for a blocking checker in the row and returns all coordinates 'til that point.
        /// </summary>
        /// <param name="checker">The checker which makes the move</param>
        /// <param name="enemyCheckerCoordinate">Coordinate of the enemy checker</param>
        /// <param name="direction">Direction the attackmove was heading</param>
        /// <returns>list of possible ending locations</returns>
        private IEnumerable <TileCoordinate> GetPossibleMovesInDirectionAfterAttack(IChecker checker, TileCoordinate enemyCheckerCoordinate, DiagonalDirection direction)
        {
            var moves = new List <TileCoordinate>();

            if (checker.Type == CheckerType.King)
            {
                TileCoordinate lastCheckedTile = new TileCoordinate(enemyCheckerCoordinate.X, enemyCheckerCoordinate.Y);
                TileCoordinate nextCoordinate  = TileCoordinate.CalculateLocationAfterSteps(lastCheckedTile, direction);
                while (nextCoordinate.IsValid())                //continues as long as the code hasnt reached a corner of the board, of until a attackmove is detected
                {
                    var nextTile = this.First(t => t.Coordinate == nextCoordinate);
                    if (nextTile.Checker != null)     //theres a checker here, so check for a possibility of a attackmove.
                    {
                        break;                        //stop checking moves in this direction, since we found a checker. no need to check the further moves now.
                    }
                    else
                    {
                        moves.Add(nextCoordinate);
                    }
                    //update the nextcoordinate, which is needed for the next direction
                    nextCoordinate = TileCoordinate.CalculateLocationAfterSteps(nextCoordinate, direction);
                }
            }
            else
            {
                moves.Add(TileCoordinate.CalculateLocationAfterSteps(enemyCheckerCoordinate, direction));
            }
            return(moves);
        }