/// <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); }