public static MoveCapability CannonMove(Direction direction, int maxSteps = 9999) { MoveCapability move = new MoveCapability(direction, maxSteps, 1, false, false); move.SpecialAttacks = SpecialAttacks.CannonCapture; return(move); }
public static MoveCapability RifleCapture(Direction direction, int maxSpaces) { MoveCapability move = new MoveCapability(direction, maxSpaces, 1, true, true); move.SpecialAttacks = SpecialAttacks.CannonCapture; return(move); }
public MoveCapability AddMoveCapability(MoveCapability moveCapability) { moveCapabilities[nMoveCapabilities] = moveCapability; if (moveCapability.PathInfo != null) { HasMovesWithPaths = true; } if (moveCapability.Condition != null) { HasMovesWithConditionalLocation = true; } return(moveCapabilities[nMoveCapabilities++]); }
private void findSquare(int square, int slice, int step, MoveCapability move) { if (step >= move.MinSteps && move.CanCapture) { findSquare(square, slice); } else if (move.MaxSteps <= step && (move.ConditionalBySquare == null || move.ConditionalBySquare[0][square])) { int nextSquare = Game.Board.NextSquare(move.NDirection, square); if (nextSquare >= 0 && SliceLookup[nextSquare] == -1) { findSquare(nextSquare, slice, step + 1, move); } } }
// *** CONSTRUCTION *** // #region Constructor protected PieceType(string internalName, string name, string notation, int midgameValue, int endgameValue, string preferredImageName = null) { InternalName = internalName; Name = name; Notation = new string[2]; NotationClean = new string[2]; if (notation != null) { SetNotation(notation); } ImagePreferenceList = new List <string>(); ImagePreferenceList.Add(internalName); if (internalName != name) { ImagePreferenceList.Add(name); } PreferredImage = preferredImageName; SimpleMoveGeneration = true; HasMovesWithPaths = false; HasMovesWithConditionalLocation = false; IsPawn = false; Enabled = true; IsSliced = true; moveCapabilities = new MoveCapability[MAX_MOVE_CAPABILITIES]; nMoveCapabilities = 0; AttackRangePerDirection = new int[Game.MAX_DIRECTIONS]; CannonAttackRangePerDirection = new int[Game.MAX_DIRECTIONS]; MidgameValue = midgameValue; EndgameValue = endgameValue; CustomMoveGenerator = null; PSTMidgameInSmallCenter = 3; PSTMidgameInLargeCenter = 3; PSTMidgameSmallCenterAttacks = 1; PSTMidgameLargeCenterAttacks = 1; PSTMidgameForwardness = 0; PSTMidgameGlobalOffset = -15; PSTEndgameInSmallCenter = 3; PSTEndgameInLargeCenter = 3; PSTEndgameSmallCenterAttacks = 1; PSTEndgameLargeCenterAttacks = 1; PSTEndgameForwardness = 0; PSTEndgameGlobalOffset = -15; }
// *** OPERATIONS *** // #region GetEmptyBoardMobility public void GetEmptyBoardMobility(Game game, int player, int square, bool[] boardSquares) { for (int x = 0; x < nMoveCapabilities; x++) { MoveCapability move = moveCapabilities[x]; if (!move.MustCapture && (move.ConditionalBySquare == null || move.ConditionalBySquare[player][square])) { int steps = 1; int nextSquare = game.Board.NextSquare(game.PlayerDirection(player, move.NDirection), square); while (nextSquare >= 0 && steps <= move.MaxSteps) { if (steps >= move.MinSteps) { boardSquares[nextSquare] = true; } steps++; nextSquare = game.Board.NextSquare(game.PlayerDirection(player, move.NDirection), nextSquare); } } } }
public void GenerateMovesForCapability(bool simpleMoveGeneration, ref MoveCapability move, MoveList list, bool capturesOnly) { if (simpleMoveGeneration) { #region Handle simple move generation int step = 1; int nextSquare = Game.Board.NextSquare(Player, move.NDirection, Square); while (nextSquare >= 0 && step <= move.MaxSteps) { Piece pieceOnSquare = Board[nextSquare]; if (pieceOnSquare != null) { if (step >= move.MinSteps && move.CanCapture && pieceOnSquare.Player != Player) { list.AddCapture(Square, nextSquare); } nextSquare = -1; } else { if (step >= move.MinSteps && !move.MustCapture && !capturesOnly) { list.AddMove(Square, nextSquare); } nextSquare = Game.Board.NextSquare(Player, move.NDirection, nextSquare); step++; } } #endregion } else { #region Handle pieces with the more complex moves int step = 1; bool passedScreen = false; int nextSquare = Game.Board.NextSquare(Player, move.NDirection, Square); while (nextSquare >= 0 && step <= move.MaxSteps) { Piece pieceOnSquare = Board[nextSquare]; #region Handle pieces with move paths if (move.PathInfo != null) { if (pieceOnSquare == null && capturesOnly) { // don't bother trying to generate this non-capture return; } if (pieceOnSquare != null && pieceOnSquare.Player == Player) { // can't capture own piece return; } // ensure this move is supported if (step > 1 || move.SpecialAttacks != 0 || move.PathInfo.AllowMultiCapture == true) { throw new Exception("Piece type " + PieceType.Name + " has an unsupported movement capability"); } // iterate through the paths to see if one is available foreach (List <int> path in move.PathInfo.PathNDirections) { int pathSquare = Square; // iterate through each step in this path to see if it is clear bool pathIsClear = true; foreach (int nDirection in path) { pathSquare = Game.Board.NextSquare(Player, nDirection, pathSquare); if (pathSquare < 0 || (Board[pathSquare] != null && Board[pathSquare] != pieceOnSquare)) { // this path is obstructed pathIsClear = false; break; } } if (pathIsClear) { if (pieceOnSquare != null && move.CanCapture) { list.AddCapture(Square, nextSquare); } else if (pieceOnSquare == null) { list.AddMove(Square, nextSquare); } // we can return now; no need to try other paths return; } } // if we are here, all paths are blocked return; } #endregion if (pieceOnSquare != null) { if (step >= move.MinSteps && pieceOnSquare.Player != Player && (move.CanCapture || ((move.SpecialAttacks & SpecialAttacks.CannonCapture) != 0 && passedScreen))) { if (move.SpecialAttacks != SpecialAttacks.RifleCapture) { list.AddCapture(Square, nextSquare); } else { list.AddRifleCapture(Square, nextSquare); } } if ((move.SpecialAttacks & SpecialAttacks.CannonCapture) != 0 && !passedScreen) { passedScreen = true; nextSquare = Game.Board.NextSquare(Player, move.NDirection, nextSquare); } else { nextSquare = -1; } } else { if (step >= move.MinSteps && !move.MustCapture && !capturesOnly && !passedScreen) { list.AddMove(Square, nextSquare); } nextSquare = Game.Board.NextSquare(Player, move.NDirection, nextSquare); step++; } } #endregion } }
public double CalculateMobilityStatistics(Game game, double density) { Board board = game.Board; double[] mobilityPerSquare = new double[board.NumSquares]; double[] directionsPerSquare = new double[board.NumSquares]; double[] safeChecksPerSquare = new double[board.NumSquares]; for (int square = 0; square < board.NumSquares; square++) { int rank = board.GetRank(square); int file = board.GetFile(square); double mobility = 0.0; double directions = 0.0; double safeChecks = 0.0; for (int x = 0; x < nMoveCapabilities; x++) { MoveCapability move = moveCapabilities[x]; if (move.CanCapture && (move.ConditionalBySquare == null || move.ConditionalBySquare[0][square])) { double directionalMobility = 0.0; double currentWeight = 1.0; int steps = 1; int nextSquare = game.Board.NextSquare(move.NDirection, square); if (nextSquare >= 0) { directions++; } while (nextSquare >= 0 && steps <= move.MaxSteps) { if (steps >= move.MinSteps) { directionalMobility += currentWeight; currentWeight = currentWeight * density; // is this a safe check? int currentRank = board.GetRank(nextSquare); int currentFile = board.GetFile(nextSquare); if (currentFile > file + 1 || currentFile < file - 1 || currentRank > rank + 1 || currentRank < rank - 1) { safeChecks++; } } steps++; nextSquare = game.Board.NextSquare(move.NDirection, nextSquare); } mobility += directionalMobility; } } mobilityPerSquare[square] = mobility; directionsPerSquare[square] = directions; safeChecksPerSquare[square] = safeChecks; } // calculate averages double totalMobility = 0.0; double totalDirections = 0.0; double totalSafeChecks = 0.0; for (int square = 0; square < board.NumSquares; square++) { totalMobility += mobilityPerSquare[square]; totalDirections += directionsPerSquare[square]; totalSafeChecks += safeChecksPerSquare[square]; } AverageMobility = totalMobility / board.NumSquares; AverageDirectionsAttacked = totalDirections / board.NumSquares; AverageSafeChecks = totalSafeChecks / board.NumSquares; return(AverageMobility); }
public MoveCapability RifleCapture(Direction direction, int maxSpaces) { SimpleMoveGeneration = false; moveCapabilities[nMoveCapabilities] = MoveCapability.RifleCapture(direction, maxSpaces); return(moveCapabilities[nMoveCapabilities++]); }
public MoveCapability CannonMove(Direction direction) { SimpleMoveGeneration = false; moveCapabilities[nMoveCapabilities] = MoveCapability.CannonMove(direction); return(moveCapabilities[nMoveCapabilities++]); }
public MoveCapability SlideCaptureOnly(Direction direction) { moveCapabilities[nMoveCapabilities] = MoveCapability.SlideCaptureOnly(direction); return(moveCapabilities[nMoveCapabilities++]); }
public MoveCapability Slide(Direction direction, int maxSteps) { moveCapabilities[nMoveCapabilities] = MoveCapability.Slide(direction, maxSteps); return(moveCapabilities[nMoveCapabilities++]); }
public MoveCapability Step(Direction direction) { moveCapabilities[nMoveCapabilities] = MoveCapability.Step(direction); return(moveCapabilities[nMoveCapabilities++]); }