public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player) { List <Pos2> maneuvers = new List <Pos2>(); List <Pos2> captures = new List <Pos2>(); int[,] dydx = { { 2, -1 }, { 2, 1 }, { -2, -1 }, { -2, 1 }, { 1, -2 }, { 1, 2 }, { -1, -2 }, { -1, 2 } }; int y, x; for (int i = 0; i < (dydx.Length / dydx.Rank); i++) { y = pos.y + dydx[i, 0]; x = pos.x + dydx[i, 1]; // if this is a valid spot to put the knight if (y >= 0 && y < 8 && // within bounds x >= 0 && x < 8 && // ^^^ Math.Sign(board.value[y, x]) != player) // not own piece { if (Math.Sign(board.value[y, x]) == -player) { captures.Add(new Pos2(y, x)); } else { maneuvers.Add(new Pos2(y, x)); } } } return(maneuvers, captures); }
public bool PlayerIsTrapped(int player) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { int p = value[i, j]; // if piece does not belong to player, move on if (Math.Sign(p) != player) { continue; } List <Pos2>[] sqrs = new List <Pos2> [2]; // destination squares Pos2 src = new Pos2(i, j); // current piece's starting position // get all pseudo-legal moves for current piece (sqrs[0], sqrs[1]) = Pieces.dict[(uint)Math.Abs(p)].ListMoves(this, src, player); foreach (List <Pos2> l in sqrs) // for each move type { // try to find a non suicidal move if (l.Exists(d => !MoveIsSuicide(new Move(src, d), player))) { return(false); } } } } // if you've checked every move and none work, return(true); }
public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player) { List <Pos2> maneuvers = new List <Pos2>(); List <Pos2> captures = new List <Pos2>(); // first determine maneuvers available to the pawn int y = pos.y + player; int x = pos.x; if (y < 8 && y >= 0 && Math.Sign(board.value[y, x]) == 0) // or is empty { // it can move forward 1 maneuvers.Add(new Pos2(y, x)); // if pawn is at home & nothing is 2 squares ahead y += player; if (board.touch[pos.y, x] == 0 && Math.Sign(board.value[y, x]) == 0) // or is empty { maneuvers.Add(new Pos2(y, x)); } } // now determine captures available to the pawn y = pos.y + player; for (int i = 0; i < 2; i++) { x = pos.x + 1 - 2 * i; // check if it's possible to capture in this direction if (x >= 0 && x < 8 && y >= 0 && y < 8) { // capture other player's piece directly if (Math.Sign(board.value[y, x]) == -player) { captures.Add(new Pos2(y, x)); } // capture via en passant (considered maneuver) if (pos.y == (int)(3.5f + player) && board.value[pos.y, x] == -player && board.touch[pos.y, x] == 1 && board.touch[pos.y + player * 2, x] == 1) { maneuvers.Add(new Pos2(y, x)); } } } return(maneuvers, captures); }
public bool MoveIsSuicide(Move move, int player) { // allow null move parameter to mean no move move ??= new Move(new Pos2(0, 0), new Pos2(0, 0)); Board test = new Board(this); // copy board state test.MakeMove(move, player); // make move on new board // find kind in both variations Pos2[] pos = new Pos2[2]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (value[i, j] == Pieces.KING * player) { pos[0] = new Pos2(i, j); } if (test.value[i, j] == Pieces.KING * player) { pos[1] = new Pos2(i, j); } if (pos[0] != null && pos[1] != null) { break; } } } do // (must happen at least once) { pos[0].y += Math.Sign(pos[1].y - pos[0].y); // interpolate king positions on 2nd board pos[0].x += Math.Sign(pos[1].x - pos[0].x); // (if king is stationary do nothing) // if king is hit at any point during his journey if (test.PosIsHitBy(pos[0], null, player)) { return(true); } }while (pos[0].y != pos[1].y || pos[0].x != pos[1].x); return(false); }
public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player) { List <Pos2> maneuvers = new List <Pos2>(); List <Pos2> captures = new List <Pos2>(); int dy, dx; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { dy = 1 - 2 * i; // every combination of 1 & -1 dx = 1 - 2 * j; var(tmpm, tmpc) = IPiece.CastMoves(board, pos, dy, dx, player); maneuvers.AddRange(tmpm); captures.AddRange(tmpc); } } return(maneuvers, captures); }
public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player) { List <Pos2> maneuvers = new List <Pos2>(); List <Pos2> captures = new List <Pos2>(); int dy, dx; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { dy = i * (1 - 2 * j); dx = (i == 0 ? 1 : 0) * (1 - 2 * j); var(tmpm, tmpc) = IPiece.CastMoves(board, pos, dy, dx, player); maneuvers.AddRange(tmpm); captures.AddRange(tmpc); } } return(maneuvers, captures); }
public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player) { List <Pos2> maneuvers = new List <Pos2>(); List <Pos2> captures = new List <Pos2>(); for (int dx = -1; dx < 2; dx++) { for (int dy = -1; dy < 2; dy++) { if (dx == 0 && dy == 0) { continue; } var(tmpm, tmpc) = IPiece.CastMoves(board, pos, dy, dx, player); maneuvers.AddRange(tmpm); captures.AddRange(tmpc); } } return(maneuvers, captures); }
/*-BOARD STATE QUERY FUNCTIONS---------------------------------------*/ public bool PosIsHitBy(Pos2 pos, uint[] ignoredPieces, int player) { if (pos == null) { throw new ArgumentNullException(); } if (ignoredPieces == null) { ignoredPieces = new uint[] { } } ; // iterate through each piece type foreach (KeyValuePair <uint, IPiece> kvp in Pieces.dict) { // check if piece is included if (ignoredPieces.Contains(kvp.Key)) { continue; } // get all captures possible of piece from pos List <Pos2> captures = kvp.Value.ListMoves(this, pos, player).c; // check all potential captures here foreach (Pos2 dst in captures) { // if this is the right piece to attack pos if (Math.Abs(value[dst.y, dst.x]) == kvp.Key) { return(true); } } } return(false); }
public (List <Pos2> m, List <Pos2> c) ListMoves(Board board, Pos2 pos, int player) { List <Pos2> maneuvers = new List <Pos2>(); List <Pos2> captures = new List <Pos2>(); // first find all normal moves for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { int y = pos.y + dy; int x = pos.x + dx; if (y >= 0 && y < 8 && // within bounds x >= 0 && x < 8 && // ^^^ Math.Sign(board.value[y, x]) != player) // or is not friendly piece { if (Math.Sign(board.value[y, x]) == -player) { captures.Add(new Pos2(y, x)); } else { maneuvers.Add(new Pos2(y, x)); } } } } // now find castling moves // TODO: implement chess960 castling rules (more general) if (board.touch[pos.y, pos.x] == 0 && // untouched king !board.PosIsHitBy(pos, new uint[] { Pieces.KING }, player)) // not in check { for (int i = 0; i < 2; i++) { int dx = 1 - 2 * i; // -1 or 1 if (board.touch[pos.y, (int)(4 + 3.5f * dx)] == 0) // untouched rook { bool flag = false; // make sure squares are open for (int j = 3 + dx; j > 0 && j < 7; j += dx) { if (board.value[pos.y, j] != 0) { flag = true; break; } } if (flag) { continue; } maneuvers.Add(new Pos2(pos.y, 3 + 2 * dx)); } } } return(maneuvers, captures); }