public override void AddRules() { base.AddRules(); // *** BORDER RULE *** // AddRule(new Rules.Brouhaha.BrouhahaBorderRule()); // *** PAWN DOUBLE MOVE *** // MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 2; Pawn.AddMoveCapability(doubleMove); // *** EN-PASSANT *** // AddEnPassantRule(Pawn, new Direction(1, 0)); // *** CASTLING *** // AddCastlingRule(); CastlingMove(0, "e1", "g1", "h1", "f1", 'K'); CastlingMove(0, "e1", "c1", "a1", "d1", 'Q'); CastlingMove(1, "e8", "g8", "h8", "f8", 'k'); CastlingMove(1, "e8", "c8", "a8", "d8", 'q'); // *** PAWN PROMOTION *** // if (PromotionRule.Value == "Custom") { List <PieceType> availablePromotionTypes = ParseTypeListFromString(PromotionTypes); AddBasicPromotionRule(Pawn, availablePromotionTypes, loc => loc.Rank == 8); } }
public override void Initialize(Game game) { base.Initialize(game); hashKeyIndex = game.HashKeys.TakeKeys(game.Board.NumSquares); epCaptureSquares = new int[Game.MAX_PLY]; epMoverSquares = new int[Game.MAX_PLY]; for (int x = 0; x < Game.MAX_PLY; x++) { epCaptureSquares[x] = epMoverSquares[x] = 0; } gameHistoryCaptureSquares = new int[Game.MAX_GAME_LENGTH]; gameHistoryCaptureSquares[0] = 0; gameHistoryMoverSquares = new int[Game.MAX_GAME_LENGTH]; gameHistoryMoverSquares[0] = 0; // find the move directions captureDirections = new int[2]; MoveCapability[] moveCapabilities; int nMoveCapabilities = PawnType.GetMoveCapabilities(out moveCapabilities); for (int nMoveCap = 0; nMoveCap < nMoveCapabilities; nMoveCap++) { MoveCapability move = moveCapabilities[nMoveCap]; if (move.CanCapture) { captureDirections[0] = Game.PlayerDirection(0, move.NDirection); captureDirections[1] = Game.PlayerDirection(1, move.NDirection); } } // Hook up MoveBeingPlayed event handler game.MoveBeingPlayed += MoveBeingPlayedHandler; }
public override void AddRules() { base.AddRules(); // *** PAWN DOUBLE MOVE *** // if (PawnDoubleMove && BerolinaPawn.Enabled) { MoveCapability doubleMoveNE = new MoveCapability(); doubleMoveNE.MinSteps = 2; doubleMoveNE.MaxSteps = 2; doubleMoveNE.MustCapture = false; doubleMoveNE.CanCapture = false; doubleMoveNE.Direction = new Direction(1, 1); doubleMoveNE.Condition = location => location.Rank == 1; BerolinaPawn.AddMoveCapability(doubleMoveNE); MoveCapability doubleMoveNW = new MoveCapability(); doubleMoveNW.MinSteps = 2; doubleMoveNW.MaxSteps = 2; doubleMoveNW.MustCapture = false; doubleMoveNW.CanCapture = false; doubleMoveNW.Direction = new Direction(1, -1); doubleMoveNW.Condition = location => location.Rank == 1; BerolinaPawn.AddMoveCapability(doubleMoveNW); } // *** EN-PASSANT *** // if (EnPassant && BerolinaPawn.Enabled) { AddRule(new Rules.Berolina.BerolinaEnPassantRule(BerolinaPawn)); } }
// *** CONSTRUCTION *** // public ExtraMovesForUnmovedPieceRule(PieceType pieceType, string fenSegmentName) { PieceType = pieceType; FENSegmentName = fenSegmentName; extraMoves = new MoveCapability[MAX_EXTRA_MOVES]; privLookup = new Dictionary <char, int>(); privToSquareLookup = new Dictionary <int, int>(); }
public override void AddPieceTypes() { base.AddPieceTypes(); AddPieceType(Rook = new Rook("Rook", "R", 500, 550)); AddPieceType(Bishop = new Bishop("Bishop", "B", 325, 350)); AddPieceType(Knight = new Knight("Knight", "N", 325, 325)); AddPieceType(Scout = new Scout("Scout", "S", 300, 300)); AddPieceType(Cleric = new Cleric("Cleric", "C", 475, 500)); AddPieceType(Queen = new Queen("Queen", "Q", 900, 1000)); // *** CLERIC FIRST MOVE *** // MoveCapability clericMove = new MoveCapability(); clericMove.MaxSteps = 1; clericMove.Direction = new Direction(1, 3); clericMove.Condition = location => location.Rank == 0 && (location.File == 0 || location.File == 9); Cleric.AddMoveCapability(clericMove); clericMove = new MoveCapability(); clericMove.MaxSteps = 1; clericMove.Direction = new Direction(1, -3); clericMove.Condition = location => location.Rank == 0 && (location.File == 0 || location.File == 9); Cleric.AddMoveCapability(clericMove); clericMove = new MoveCapability(); clericMove.MaxSteps = 1; clericMove.Direction = new Direction(3, 1); clericMove.Condition = location => location.Rank == 0 && (location.File == 0 || location.File == 9); Cleric.AddMoveCapability(clericMove); clericMove = new MoveCapability(); clericMove.MaxSteps = 1; clericMove.Direction = new Direction(3, -1); clericMove.Condition = location => location.Rank == 0 && (location.File == 0 || location.File == 9); Cleric.AddMoveCapability(clericMove); // *** SCOUT FIRST MOVE *** // MoveCapability scoutMove = new MoveCapability(); scoutMove.MaxSteps = 1; scoutMove.Direction = new Direction(1, 2); scoutMove.Condition = location => location.Rank == 0 && (location.File == 4 || location.File == 5); Scout.AddMoveCapability(scoutMove); scoutMove = new MoveCapability(); scoutMove.MaxSteps = 1; scoutMove.Direction = new Direction(1, -2); scoutMove.Condition = location => location.Rank == 0 && (location.File == 4 || location.File == 5); Scout.AddMoveCapability(scoutMove); scoutMove = new MoveCapability(); scoutMove.MaxSteps = 1; scoutMove.Direction = new Direction(2, 1); scoutMove.Condition = location => location.Rank == 0 && (location.File == 4 || location.File == 5); Scout.AddMoveCapability(scoutMove); scoutMove = new MoveCapability(); scoutMove.MaxSteps = 1; scoutMove.Direction = new Direction(2, -1); scoutMove.Condition = location => location.Rank == 0 && (location.File == 4 || location.File == 5); Scout.AddMoveCapability(scoutMove); }
public override void AddRules() { base.AddRules(); var elephantRule = new Rules.ExtraMovesForUnmovedPieceRule(Elephant, "elephants"); elephantRule.AddMove(MoveCapability.Step(new Direction(2, 0))); elephantRule.AddMove(MoveCapability.Step(new Direction(2, 2))); elephantRule.AddMove(MoveCapability.Step(new Direction(2, -2))); AddRule(elephantRule); }
public override void AddRules() { base.AddRules(); // *** PAWN MULTIPLE MOVE *** // if (PawnMultipleMove.Value == "@2(2)" || PawnMultipleMove.Value == "@2(2,3)" || PawnMultipleMove.Value == "@2(2,3,4)") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = Convert.ToInt32(PawnMultipleMove.Value.Substring(PawnMultipleMove.Value.Length - 2, 1)); doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 1; Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "@3(2)" || PawnMultipleMove.Value == "@3(2,3)") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = Convert.ToInt32(PawnMultipleMove.Value.Substring(PawnMultipleMove.Value.Length - 2, 1)); doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 2; Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "@4(2)") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 3; Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "Fast Pawn") { // Find the pawn's forward move capability and increase // the range to two spaces MoveCapability[] moves; int nMoves = Pawn.GetMoveCapabilities(out moves); foreach (MoveCapability move in moves) { if (move.NDirection == PredefinedDirections.N && move.MaxSteps == 1) { move.MaxSteps = 2; break; } } } }
// *** INITIALIZATION *** // #region AddRules public override void AddRules() { base.AddRules(); // pawn has a foward capturing move on 7th rank MoveCapability move = new MoveCapability(); move.MaxSteps = 1; move.MustCapture = true; move.CanCapture = true; move.Direction = new Direction(1, 0); move.Condition = location => location.Rank == 6; Pawn.AddMoveCapability(move); }
public static bool CustomMoveGenerationHandler(PieceType pieceType, Piece piece, MoveList moveList, bool capturesOnly) { MoveCapability[] moves; int nMoves = pieceType.GetMoveCapabilities(out moves); for (int nMove = 0; nMove < nMoves; nMove++) { MoveCapability move = moves[nMove]; int step = 1; int nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, piece.Square); while (nextSquare >= 0 && step <= move.MaxSteps) { Piece pieceOnSquare = piece.Board[nextSquare]; if (pieceOnSquare != null) { if (step >= move.MinSteps && move.CanCapture && pieceOnSquare.Player != piece.Player) { moveList.AddCapture(piece.Square, nextSquare); } else if (step >= move.MinSteps && pieceOnSquare.Player == piece.Player && piece.PieceType != pieceOnSquare.PieceType) { // self-capture move allowing relocation of friendly piece int currentSquare = piece.Square; while (currentSquare != nextSquare) { moveList.BeginMoveAdd(MoveType.MoveRelay, piece.Square, nextSquare, currentSquare); moveList.AddPickup(piece.Square); moveList.AddPickup(nextSquare); moveList.AddDrop(piece, nextSquare); moveList.AddDrop(pieceOnSquare, currentSquare); moveList.EndMoveAdd(piece.PieceType.GetMidgamePST(nextSquare) - piece.PieceType.GetMidgamePST(piece.Square) + pieceOnSquare.PieceType.GetMidgamePST(currentSquare) - pieceOnSquare.PieceType.GetMidgamePST(nextSquare)); currentSquare = piece.Board.NextSquare(piece.Player, move.NDirection, currentSquare); } } nextSquare = -1; } else { if (step >= move.MinSteps && !move.MustCapture && !capturesOnly) { moveList.AddMove(piece.Square, nextSquare); } nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, nextSquare); step++; } } } return(false); }
public override void AddRules() { base.AddRules(); // *** PAWN DOUBLE MOVE *** // if (PawnDoubleMove) { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 1; Pawn.AddMoveCapability(doubleMove); } }
public override void AddRules() { base.AddRules(); // Promotion Rules AddRule(new Rules.BasicPromotionRule(Guard, new List <PieceType> { EquesRex }, loc => loc.Rank == 11, loc => loc.Rank != 11)); AddRule(new Rules.BasicPromotionRule(Cat, new List <PieceType> { StarCat }, loc => loc.Rank == 11, loc => loc.Rank != 11)); AddRule(new Rules.BasicPromotionRule(Knight, new List <PieceType> { SpeedyKnight }, loc => loc.Rank == 11)); // Cat and Star Cat Powers AddRule(new Rules.OptionalCaptureByOvertakeRule(new List <PieceType> { Cat, StarCat })); // Pawn Enhancement MoveCapability pawnLeftMove = new MoveCapability(); pawnLeftMove.MinSteps = 1; pawnLeftMove.MaxSteps = 1; pawnLeftMove.MustCapture = false; pawnLeftMove.CanCapture = false; pawnLeftMove.Direction = new Direction(0, -1); pawnLeftMove.Condition = location => location.Rank >= 6; Pawn.AddMoveCapability(pawnLeftMove); MoveCapability pawnRightMove = new MoveCapability(); pawnRightMove.MinSteps = 1; pawnRightMove.MaxSteps = 1; pawnRightMove.MustCapture = false; pawnRightMove.CanCapture = false; pawnRightMove.Direction = new Direction(0, 1); pawnRightMove.Condition = location => location.Rank >= 6; Pawn.AddMoveCapability(pawnRightMove); // Reconfigure the 50-move rule Rules.Move50Rule rule = (Rules.Move50Rule)FindRule(typeof(Rules.Move50Rule)); rule.HalfMoveCounterThreshold = 160; rule.SetRequiredDirection(new Direction(1, 0)); }
public static new void AddMoves(PieceType type) { Ferz.AddMoves(type); // add the multi-path move MoveCapability move = MoveCapability.Step(new Direction(2, 0)); MovePathInfo movePath = new MovePathInfo(); movePath.AddPath(new List <Direction>() { new Direction(1, 1), new Direction(1, -1) }); movePath.AddPath(new List <Direction>() { new Direction(1, -1), new Direction(1, 1) }); move.PathInfo = movePath; type.AddMoveCapability(move); }
// *** OVERRIDES *** // #region Initialize public override void Initialize(Game game) { base.Initialize(game); hashKeyIndex = game.HashKeys.TakeKeys(game.Board.NumSquaresExtended); epSquares = new int[Game.MAX_PLY]; for (int x = 0; x < Game.MAX_PLY; x++) { epSquares[x] = 0; } gameHistory = new int[Game.MAX_GAME_LENGTH]; gameHistory[0] = 0; List <int> attackdirs = new List <int>(); MoveCapability[] moveCapabilities; int nMoveCapabilities = PawnType.GetMoveCapabilities(out moveCapabilities); for (int nMoveCap = 0; nMoveCap < nMoveCapabilities; nMoveCap++) { MoveCapability move = moveCapabilities[nMoveCap]; if (move.CanCapture) { attackdirs.Add(move.NDirection); } } nAttackDirections = attackdirs.Count; attackDirections = new int[game.NumPlayers, nAttackDirections]; for (int ndir = 0; ndir < nAttackDirections; ndir++) { for (int player = 0; player < game.NumPlayers; player++) { attackDirections[player, ndir] = game.PlayerDirection(player, attackdirs[ndir]); } } // Hook up MoveBeingPlayed event handler game.MoveBeingPlayed += MoveBeingPlayedHandler; }
private void generateChaserPlan() { moveCapabilityMatrix = new MoveCapability[width, height]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { MoveCapability cap = new MoveCapability(); GameObject currentGo = this.gameObjectMatrix[i, j]; if (currentGo == null || currentGo.tag == "Gold" || currentGo.tag == "HiddenLadder" || currentGo.tag == "Ladder" || currentGo.tag == "Stick") { if (j < height - 1) { GameObject upperGo = gameObjectMatrix[i, j + 1]; if (currentGo != null && currentGo.tag == "Ladder" && (upperGo == null || !upperGo.tag.Contains("Floor"))) { cap.goUp = true; } } if (j > 0) { GameObject lowerGo = gameObjectMatrix[i, j - 1]; if (lowerGo == null || !lowerGo.tag.Contains("Floor")) { cap.goDown = true; } } if (i > 0 && j > 0) { GameObject leftGo = gameObjectMatrix[i - 1, j]; GameObject lowerGo = gameObjectMatrix[i, j - 1]; if (lowerGo != null && ((lowerGo.tag == "Ladder" && (currentGo == null || currentGo.tag != "Ladder")) || lowerGo.tag.Contains("Floor")) && (leftGo == null || !leftGo.tag.Contains("Floor"))) { cap.goLeft = true; } if (currentGo != null && currentGo.tag == "Stick") { cap.goLeft = true; } } if (i < width - 1) { GameObject rightGo = gameObjectMatrix[i + 1, j]; GameObject lowerGo = gameObjectMatrix[i, j - 1]; if (lowerGo != null && (lowerGo.tag == "Ladder" || lowerGo.tag.Contains("Floor")) && (rightGo == null || !rightGo.tag.Contains("Floor"))) { cap.goRight = true; } if (currentGo != null && currentGo.tag == "Stick") { cap.goRight = true; } } } moveCapabilityMatrix[i, j] = cap; } } //visualize /* * for (int i = 0; i < width; i++) { * for (int j = 0; j < height; j++) { * MoveCapability m = moveCapabilityMatrix[i, j]; * if (m.goUp) { * (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) * .transform.Rotate(0, 0, 90f); * } * if (m.goDown) { * (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) * .transform.Rotate(0, 0, -90f); * } * if (m.goRight) { * (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) * .transform.Rotate(0, 0, 0); * } * * if (m.goLeft) { * (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) * .transform.Rotate(0, 0, 180); * } * } * }*/ for (int playerx = 0; playerx < width; playerx++) { for (int playery = 0; playery < height; playery++) { Queue <int> toVisitQueue = new Queue <int>(); HashSet <int> visited = new HashSet <int>(); toVisitQueue.Enqueue(xyKey(playerx, playery)); while (toVisitQueue.Count > 0) { int tmp = toVisitQueue.Dequeue(); int currentx = tmp >> 8; int currenty = tmp & 255; visited.Add(xyKey(currentx, currenty)); if (currentx > 0 && !visited.Contains(xyKey(currentx - 1, currenty))) { MoveCapability mc = moveCapabilityMatrix[currentx - 1, currenty]; int key = chaseDirectionKey(playerx, playery, currentx - 1, currenty); if (mc != null && mc.goRight && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_RIGHT); toVisitQueue.Enqueue(xyKey(currentx - 1, currenty)); } } if (currentx < width - 1 && !visited.Contains(xyKey(currentx + 1, currenty))) { MoveCapability mc = moveCapabilityMatrix[currentx + 1, currenty]; int key = chaseDirectionKey(playerx, playery, currentx + 1, currenty); if (mc != null && mc.goLeft && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_LEFT); toVisitQueue.Enqueue(xyKey(currentx + 1, currenty)); } } if (currenty < height - 1 && !visited.Contains(xyKey(currentx, currenty + 1))) { MoveCapability mc = moveCapabilityMatrix[currentx, currenty + 1]; int key = chaseDirectionKey(playerx, playery, currentx, currenty + 1); if (mc != null && mc.goDown && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_DOWN); toVisitQueue.Enqueue(xyKey(currentx, currenty + 1)); } } if (currenty > 0 && !visited.Contains(xyKey(currentx, currenty - 1))) { MoveCapability mc = moveCapabilityMatrix[currentx, currenty - 1]; int key = chaseDirectionKey(playerx, playery, currentx, currenty - 1); if (mc != null && mc.goUp && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_UP); toVisitQueue.Enqueue(xyKey(currentx, currenty - 1)); } } } } } // visualize // int playerX = 2; // int playerY = 8; // for (int i = 0; i < width; i++) { // for (int j = 0; j < height; j++) { // int key = chaseDirectionKey(playerX, playerY, i, j); // if (!chaseDirection.ContainsKey(key)) { // continue; // } // MoveDirection m = (MoveDirection)chaseDirection[key]; // if (m == MoveDirection.GO_UP) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, 90f); // } // if (m == MoveDirection.GO_DOWN) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, -90f); // } // if (m == MoveDirection.GO_RIGHT) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, 0); // } // // if (m == MoveDirection.GO_LEFT) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, 180); // } // } // } }
public static bool CustomMoveGenerationHandler(PieceType pieceType, Piece piece, MoveList moveList, bool capturesOnly) { MoveCapability[] moves; int nMoves = pieceType.GetMoveCapabilities(out moves); for (int nMove = 0; nMove < nMoves; nMove++) { MoveCapability move = moves[nMove]; int step = 1; int nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, piece.Square); while (nextSquare >= 0 && step <= move.MaxSteps) { Piece pieceOnSquare = piece.Board[nextSquare]; if (pieceOnSquare != null) { if (step >= move.MinSteps && move.CanCapture && pieceOnSquare.Player != piece.Player) { moveList.AddCapture(piece.Square, nextSquare); for (int x = 0; x < 8; x++) { int targetSquare = piece.Board.NextSquare(x, nextSquare); if (targetSquare >= 0 && piece.Board[targetSquare] != null && piece.Board[targetSquare].Player != piece.Player) { moveList.BeginMoveAdd(MoveType.ExtraCapture, piece.Square, nextSquare, targetSquare); moveList.AddPickup(piece.Square); moveList.AddPickup(nextSquare); moveList.AddPickup(targetSquare); moveList.AddDrop(piece, nextSquare); moveList.EndMoveAdd(4000 + piece.Board[nextSquare].PieceType.MidgameValue + piece.Board[targetSquare].PieceType.MidgameValue); } } } nextSquare = -1; } else { if (step >= move.MinSteps && !move.MustCapture) { if (!capturesOnly) { moveList.AddMove(piece.Square, nextSquare); } for (int x = 0; x < 8; x++) { int targetSquare = piece.Board.NextSquare(x, nextSquare); if (targetSquare >= 0 && piece.Board[targetSquare] != null && piece.Board[targetSquare].Player != piece.Player) { moveList.BeginMoveAdd(MoveType.ExtraCapture, piece.Square, nextSquare, targetSquare); moveList.AddPickup(piece.Square); moveList.AddPickup(targetSquare); moveList.AddDrop(piece, nextSquare); moveList.EndMoveAdd(3000 + piece.Board[targetSquare].PieceType.MidgameValue); } } } nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, nextSquare); step++; } } } return(false); }
public void AddMove(MoveCapability move) { extraMoves[nExtraMoves++] = move; }
public override void AddRules() { base.AddRules(); // *** PAWN MULTIPLE MOVE *** // if (PawnMultipleMove.Value == "Double") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 1; Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "Triple" || PawnMultipleMove.Value == "Wildebeest") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 3; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 1; Pawn.AddMoveCapability(doubleMove); if (PawnMultipleMove.Value == "Wildebeest") { doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 2; Pawn.AddMoveCapability(doubleMove); } } else if (PawnMultipleMove.Value == "Great") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 1 || location.Rank == 2; Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "Grand") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); doubleMove.Condition = location => location.Rank == 2; Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "Unicorn") { MoveCapability doubleMove = new MoveCapability(); doubleMove.MinSteps = 2; doubleMove.MaxSteps = 2; doubleMove.MustCapture = false; doubleMove.CanCapture = false; doubleMove.Direction = new Direction(1, 0); int nFiles = Board.NumFiles; int file1 = nFiles / 2; int file2 = (nFiles - 1) / 2; doubleMove.Condition = location => location.Rank == 1 || (location.Rank == 2 && (location.File == file1 || location.File == file2)); Pawn.AddMoveCapability(doubleMove); } else if (PawnMultipleMove.Value == "Fast Pawn") { // Find the pawn's forward move capability and increase // the range to two spaces MoveCapability[] moves; int nMoves = Pawn.GetMoveCapabilities(out moves); foreach (MoveCapability move in moves) { if (move.NDirection == PredefinedDirections.N && move.MaxSteps == 1) { move.MaxSteps = 2; break; } } } }
private void generateChaserPlan() { moveCapabilityMatrix = new MoveCapability[width, height]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { MoveCapability cap = new MoveCapability(); GameObject currentGo = this.gameObjectMatrix[i, j]; if (currentGo == null || currentGo.tag == "Gold" || currentGo.tag == "HiddenLadder" || currentGo.tag == "Ladder" || currentGo.tag == "Stick") { if (j < height - 1) { GameObject upperGo = gameObjectMatrix[i, j + 1]; if (currentGo != null && currentGo.tag == "Ladder" && (upperGo == null || !upperGo.tag.Contains("Floor"))) { cap.goUp = true; } } if ( j > 0) { GameObject lowerGo = gameObjectMatrix[i, j - 1]; if (lowerGo == null || !lowerGo.tag.Contains("Floor")) { cap.goDown = true; } } if (i > 0 && j > 0 ) { GameObject leftGo = gameObjectMatrix[i - 1, j]; GameObject lowerGo = gameObjectMatrix[i, j - 1]; if (lowerGo != null && ((lowerGo.tag == "Ladder" && (currentGo == null || currentGo.tag != "Ladder")) || lowerGo.tag.Contains("Floor")) && (leftGo == null || !leftGo.tag.Contains("Floor"))) { cap.goLeft = true; } if (currentGo != null && currentGo.tag == "Stick") { cap.goLeft = true; } } if (i < width - 1) { GameObject rightGo = gameObjectMatrix[i + 1, j]; GameObject lowerGo = gameObjectMatrix[i, j - 1]; if (lowerGo != null && (lowerGo.tag == "Ladder" || lowerGo.tag.Contains("Floor")) && (rightGo == null || !rightGo.tag.Contains("Floor"))) { cap.goRight = true; } if (currentGo != null && currentGo.tag == "Stick") { cap.goRight = true; } } } moveCapabilityMatrix[i, j] = cap; } } //visualize /* for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { MoveCapability m = moveCapabilityMatrix[i, j]; if (m.goUp) { (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) .transform.Rotate(0, 0, 90f); } if (m.goDown) { (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) .transform.Rotate(0, 0, -90f); } if (m.goRight) { (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) .transform.Rotate(0, 0, 0); } if (m.goLeft) { (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) .transform.Rotate(0, 0, 180); } } }*/ for (int playerx = 0; playerx < width; playerx++) { for (int playery = 0; playery < height; playery++) { Queue<int> toVisitQueue = new Queue<int>(); HashSet<int> visited = new HashSet<int>(); toVisitQueue.Enqueue(xyKey(playerx, playery)); while(toVisitQueue.Count > 0) { int tmp = toVisitQueue.Dequeue(); int currentx = tmp >> 8; int currenty = tmp & 255; visited.Add(xyKey(currentx, currenty)); if (currentx > 0 && !visited.Contains(xyKey(currentx - 1, currenty))) { MoveCapability mc = moveCapabilityMatrix[currentx - 1, currenty]; int key = chaseDirectionKey(playerx, playery, currentx - 1, currenty); if (mc != null && mc.goRight && !chaseDirection.ContainsKey(key)) { chaseDirection.Add (key, MoveDirection.GO_RIGHT); toVisitQueue.Enqueue(xyKey(currentx - 1, currenty)); } } if (currentx < width - 1 && !visited.Contains(xyKey(currentx + 1, currenty))) { MoveCapability mc = moveCapabilityMatrix[currentx + 1, currenty]; int key = chaseDirectionKey(playerx, playery, currentx + 1, currenty); if (mc != null && mc.goLeft && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_LEFT); toVisitQueue.Enqueue(xyKey(currentx + 1, currenty)); } } if (currenty < height - 1 && !visited.Contains(xyKey(currentx, currenty + 1))) { MoveCapability mc = moveCapabilityMatrix[currentx, currenty + 1]; int key = chaseDirectionKey(playerx, playery, currentx, currenty + 1); if (mc != null && mc.goDown && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_DOWN); toVisitQueue.Enqueue(xyKey(currentx, currenty + 1)); } } if (currenty > 0 && !visited.Contains(xyKey(currentx, currenty - 1))) { MoveCapability mc = moveCapabilityMatrix[currentx, currenty - 1]; int key = chaseDirectionKey(playerx, playery, currentx, currenty - 1); if (mc != null && mc.goUp && !chaseDirection.ContainsKey(key)) { chaseDirection.Add(key, MoveDirection.GO_UP); toVisitQueue.Enqueue(xyKey(currentx, currenty - 1)); } } } } } // visualize // int playerX = 2; // int playerY = 8; // for (int i = 0; i < width; i++) { // for (int j = 0; j < height; j++) { // int key = chaseDirectionKey(playerX, playerY, i, j); // if (!chaseDirection.ContainsKey(key)) { // continue; // } // MoveDirection m = (MoveDirection)chaseDirection[key]; // if (m == MoveDirection.GO_UP) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, 90f); // } // if (m == MoveDirection.GO_DOWN) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, -90f); // } // if (m == MoveDirection.GO_RIGHT) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, 0); // } // // if (m == MoveDirection.GO_LEFT) { // (Instantiate(arrowPrefab, new Vector3(i, j), Quaternion.identity) as GameObject) // .transform.Rotate(0, 0, 180); // } // } // } }
private void MovementDiagramControl_Paint(object sender, PaintEventArgs e) { // Create our graphics objects Pen blackOutlinePen = new Pen(Color.Black, 2); Pen redOutlinePen = new Pen(Color.Red, 2); Pen thickRedPen = new Pen(Color.Red, 5); Pen thickGreenPen = new Pen(Color.FromArgb(0, 255, 0), 5); SolidBrush lightSquareBrush = new SolidBrush(Theme == null ? Color.FromArgb(0xFF, 0xFF, 0xCC) : Theme.ColorScheme.SquareColors[0]); SolidBrush darkSquareBrush = new SolidBrush(Theme == null ? Color.FromArgb(0x5D, 0x7E, 0x7E) : Theme.ColorScheme.SquareColors[1]); SolidBrush thirdSquareBrush = (Theme != null && Theme.ColorScheme.SquareColors.Count > 2) ? new SolidBrush(Theme.ColorScheme.SquareColors[2]) : darkSquareBrush; SolidBrush redBrush = new SolidBrush(Color.FromArgb(255, 0, 0)); SolidBrush greenBrush = new SolidBrush(Color.FromArgb(0, 255, 0)); SolidBrush blackBrush = new SolidBrush(Color.Black); // Draw the board for (int file = 0; file < 9; file++) { for (int rank = 0; rank < 9; rank++) { SolidBrush squareBrush = lightSquareBrush; if (Theme == null || Theme.NSquareColors == 2) { squareBrush = (file + rank) % 2 == 1 ? lightSquareBrush : darkSquareBrush; } else if (Theme != null && Theme.NSquareColors == 3) { squareBrush = (file + rank) % 2 == 1 ? lightSquareBrush : (rank % 2 == 0 ? darkSquareBrush : thirdSquareBrush); } e.Graphics.FillRectangle(squareBrush, 50 + 36 * file, 50 + 36 * rank, 36, 36); } } for (int file = 0; file < 9; file++) { for (int rank = 0; rank < 9; rank++) { e.Graphics.DrawRectangle(blackOutlinePen, 50 + 36 * file, 50 + 36 * rank, 36, 36); } } if (Theme == null) { // we are just previewing this control in the Forms Designer // so we have nothing further to present return; } // Draw miniature piece BoardPresentation.PieceSetPresentation.Render(e.Graphics, new Rectangle(50 + 36 * 4, 50 + 36 * 4, 36, 36), Piece, true); // Draw movement capabilities, first pass ... MoveCapability[] moves; int nMoves = PieceType.GetMoveCapabilities(out moves); for (int z = 0; z < nMoves; z++) { MoveCapability move = moves[z]; Direction direction = Piece.Game.GetDirection(Piece.Game.PlayerDirection(Piece.Player, move.NDirection)); int steps = 1; int rank = 4; int file = 4; int newRank; int newFile; newRank = rank - direction.RankOffset; newFile = file + direction.FileOffset; int oldFile = 4; int oldRank = 4; while (newRank >= 0 && newRank < 9 && newFile >= 0 && newFile < 9 && steps <= move.MaxSteps) { // draw indicator for this step if (move.MaxSteps == 1) { // handle displaying "paths" for moves that have paths if (move.PathInfo != null) { MovePathInfo pathinfo = move.PathInfo; foreach (List <Direction> dirlist in pathinfo.PathDirections) { int pathRank = 4; int pathFile = 4; foreach (Direction dir in dirlist) { int newPathRank = pathRank - dir.RankOffset; int newPathFile = pathFile + dir.FileOffset; // draw line int startX = 68 + 36 * pathFile; int startY = 68 + 36 * pathRank; int endX = 68 + 36 * newPathFile; int endY = 68 + 36 * newPathRank; if (pathRank == 4 && pathFile == 4) { FindIntersectionOfLineAndRectangle(startX, startY, endX, endY, 50 + 36 * 4, 50 + 36 * 4, 50 + 36 * 5, 50 + 36 * 5, ref startX, ref startY); } e.Graphics.DrawLine(move.CanCapture ? thickRedPen : thickGreenPen, startX, startY, endX, endY); pathRank = newPathRank; pathFile = newPathFile; } } } // a single step move is displayed // differently from a sliding move Brush fillBr; Pen outlinePen; if (move.CanCapture && !move.MustCapture) { outlinePen = blackOutlinePen; fillBr = redBrush; } else if (!move.CanCapture) { outlinePen = blackOutlinePen; fillBr = greenBrush; } else { outlinePen = redOutlinePen; fillBr = blackBrush; } e.Graphics.FillEllipse(fillBr, 54 + 36 * newFile, 54 + 36 * newRank, 28, 28); e.Graphics.DrawEllipse(outlinePen, 54 + 36 * newFile, 54 + 36 * newRank, 28, 28); if (move.MustCapture) { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; e.Graphics.DrawString("X", System.Drawing.SystemFonts.CaptionFont, redBrush, new RectangleF(51 + 36 * newFile, 51 + 36 * newRank, 36, 36), format); } } else if (steps >= move.MinSteps) { Brush fillBr; Pen outlinePen; if (move.CanCapture && !move.MustCapture) { outlinePen = blackOutlinePen; fillBr = redBrush; } else if (!move.CanCapture) { outlinePen = blackOutlinePen; fillBr = greenBrush; } else { outlinePen = redOutlinePen; fillBr = blackBrush; } e.Graphics.FillEllipse(fillBr, 54 + 36 * newFile, 54 + 36 * newRank, 28, 28); e.Graphics.DrawEllipse(outlinePen, 54 + 36 * newFile, 54 + 36 * newRank, 28, 28); if (move.MustCapture) { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; e.Graphics.DrawString("X", System.Drawing.SystemFonts.CaptionFont, redBrush, new RectangleF(51 + 36 * newFile, 51 + 36 * newRank, 36, 36), format); } } // take another step... oldFile = newFile; oldRank = newRank; newRank -= direction.RankOffset; newFile += direction.FileOffset; steps++; } steps--; if (steps > 1) { int nextSquareCenterX; int nextSquareCenterY; int lineEndX = 0; int lineEndY = 0; int maxSteps = move.MaxSteps; if (steps >= move.MaxSteps) { nextSquareCenterX = lineEndX = 68 + (36 * oldFile); nextSquareCenterY = lineEndY = 68 + (36 * oldRank); } else { newRank -= direction.RankOffset; newFile += direction.FileOffset; nextSquareCenterX = 68 + (36 * newFile); nextSquareCenterY = 68 + (36 * newRank); if (move.Direction.FileOffset == move.Direction.RankOffset || move.Direction.FileOffset == -move.Direction.RankOffset) { FindIntersectionOfLineAndRectangle(212, 212, nextSquareCenterX, nextSquareCenterY, 60 - 36, 60 - 36, 75 + (36 * 9), 75 + (36 * 9), ref lineEndX, ref lineEndY); } else if (move.Direction.FileOffset == 0 || move.Direction.RankOffset == 0) { FindIntersectionOfLineAndRectangle(212, 212, nextSquareCenterX, nextSquareCenterY, 43 - 36, 43 - 36, 92 + (36 * 9), 92 + (36 * 9), ref lineEndX, ref lineEndY); } else { FindIntersectionOfLineAndRectangle(212, 212, nextSquareCenterX, nextSquareCenterY, 51 - 36, 51 - 36, 84 + (36 * 9), 84 + (36 * 9), ref lineEndX, ref lineEndY); } } int lineStartX = 0; int lineStartY = 0; FindIntersectionOfLineAndRectangle(212, 212, nextSquareCenterX, nextSquareCenterY, 51 + (36 * 4), 51 + (36 * 4), 84 + (36 * 4), 84 + (36 * 4), ref lineStartX, ref lineStartY); Pen linePen; Brush fillBrush; if (move.CanCapture && !move.MustCapture) { linePen = thickRedPen; fillBrush = redBrush; } else if (!move.CanCapture) { linePen = thickGreenPen; fillBrush = greenBrush; } else { linePen = thickRedPen; fillBrush = redBrush; } e.Graphics.DrawLine(linePen, lineStartX, lineStartY, lineEndX, lineEndY); if (steps < move.MaxSteps) { double angle = 0.0; angle = Math.Atan2((double)(lineEndY - lineStartY), (double)(lineStartX - lineEndX)); Point[] pt = new Point[3]; pt[0].X = lineEndX; pt[0].Y = lineEndY; pt[1].X = (int)((lineEndX + (Math.Cos(angle) * 30)) + (Math.Cos(angle + (Math.PI / 2)) * 10)); pt[1].Y = (int)((lineEndY - (Math.Sin(angle) * 30)) - (Math.Sin(angle + (Math.PI / 2)) * 10)); pt[2].X = (int)((lineEndX + (Math.Cos(angle) * 30)) + (Math.Cos(angle - (Math.PI / 2)) * 10)); pt[2].Y = (int)((lineEndY - (Math.Sin(angle) * 30)) - (Math.Sin(angle - (Math.PI / 2)) * 10)); e.Graphics.FillPolygon(fillBrush, pt); e.Graphics.DrawPolygon(linePen, pt); } } } // second pass ... for (int z = 0; z < nMoves; z++) { MoveCapability move = moves[z]; Direction direction = Piece.Game.GetDirection(Piece.Game.PlayerDirection(Piece.Player, move.NDirection)); int steps = 1; int rank = 4; int file = 4; int newRank = rank - direction.RankOffset; int newFile = file + direction.FileOffset; while (newRank >= 0 && newRank < 9 && newFile >= 0 && newFile < 9 && steps <= move.MaxSteps) { if (move.MaxSteps > 1) { // draw black inner dot e.Graphics.FillEllipse(blackBrush, 63 + 36 * newFile, 63 + 36 * newRank, 11, 11); } if (move.PathInfo != null) { MovePathInfo pathinfo = move.PathInfo; foreach (List <Direction> dirlist in pathinfo.PathDirections) { int pathRank = 4; int pathFile = 4; foreach (Direction dir in dirlist) { pathRank = pathRank - dir.RankOffset; pathFile = pathFile + dir.FileOffset; // draw black inner dot e.Graphics.FillEllipse(blackBrush, 63 + 36 * pathFile, 63 + 36 * pathRank, 11, 11); } } } // take another step... newRank -= direction.RankOffset; newFile += direction.FileOffset; steps++; } } }