/// <summary> /// Calucalte new game boards which are optional moves /// </summary> /// <param name="board"></param> /// <param name="player"></param> /// <returns></returns> public IDictionary<Board, IList<Coordinate>> CalculateNewBoardsFromCoordinates(Board board, Player player) { IDictionary<Board, IList<Coordinate>> newBoardsPositions = new Dictionary<Board, IList<Coordinate>>(); for (int i = 1; i <= board.Size; i++) { if (board.IsOwner(player, board[i])) { IList<Coordinate> coordinateList = GetMovesInDirection(board, board[i], player); foreach (Coordinate coordinate in coordinateList.Reverse()) { //if a soldier of mine exists in this coord then this coord is not optional; if (board.IsOwner(player, coordinate)) { coordinateList.Remove(coordinate); } //if an oppenent soldier exsist in this coord try capturing him! else if (board.IsOpponentPiece(player, coordinate)) { IList<Coordinate> destList = CoordsToCaptureAndDest(board, board[i], coordinate, player).Values.ToList(); if (destList.Count != 0) { // destList is all the coordinates presenting the board after the capture. foreach (Coordinate coord in destList.Reverse()) { Board nBoard = board.Copy(); nBoard.UpdateBoard(nBoard[nBoard.Search(board[i])], coord); IsBecameAKing(nBoard, coord); IList<Coordinate> temp = new List<Coordinate>(); temp.Add(nBoard[nBoard.Search(board[i])]); temp.Add(nBoard[nBoard.Search(coord)]); newBoardsPositions.Add(nBoard, temp); } } } else if (!board.IsAloacted(coordinate)) { //create new board that represnt board after the move Board nBoard = board.Copy(); nBoard.UpdateBoard(nBoard[nBoard.Search(board[i])], coordinate); IsBecameAKing(nBoard, coordinate); IList<Coordinate> temp = new List<Coordinate>(); temp.Add(nBoard[nBoard.Search(board[i])]); temp.Add(nBoard[nBoard.Search(coordinate)]); newBoardsPositions.Add(nBoard, temp); } } } } return newBoardsPositions; }
/// <summary> /// Find dictionary of all captures on board per player /// </summary> /// <param name="board"></param> /// <param name="player"></param> /// <returns>dictionary of 2 lists : first list of coordinates (captured coordinates) , second coordinates (src-destination cords)-</returns> public IDictionary<IList<Coordinate>, IList<Coordinate>> FindCaptures(Board board, Player player) { IDictionary<IList<Coordinate>, IList<Coordinate>> res = new Dictionary<IList<Coordinate>, IList<Coordinate>>(); for (int i = 1; i <= 32; i++) { if (board.IsOwner(player, board[i])) { var coordsInDir = GetMovesInDirection(board, board[i], player); if (coordsInDir.Count == 0) break; foreach (Coordinate coordindir in coordsInDir) { if (board.IsOpponentPiece(player, coordindir)) { var coordsToJumpTo = CoordsToCaptureAndDest(board, board[i], coordindir, player); if (coordsToJumpTo.Count != 0) { foreach (var item in coordsToJumpTo) { res.Add(item.Key, new List<Coordinate> {board[i], item.Value}); } } } } } } return res; }
/// <summary> /// Find captures from a given source coord and opponent coord /// /// </summary> /// <param name="board"></param> /// <param name="srcCoordinate"></param> /// <param name="oponentCoordinate"></param> /// <param name="player"></param> /// <returns> a dictionary of dest coord and lists of captures</returns> public IDictionary<IList<Coordinate>, Coordinate> CoordsToCaptureAndDest(Board board, Coordinate srcCoordinate, Coordinate oponentCoordinate, Player player) { IDictionary<IList<Coordinate>, Coordinate> map = new Dictionary<IList<Coordinate>, Coordinate>(); int srcX = srcCoordinate.X; int srcY = srcCoordinate.Y; int oponentX = oponentCoordinate.X; int oponentY = oponentCoordinate.Y; Coordinate dest; Piece opponentPiece = new Piece(); int destX, destY; //find the direction of the optional capture and set destination accordingly if (srcX < oponentX) destX = oponentX + 1; else destX = oponentX - 1; if (srcY < oponentY) destY = oponentY + 1; else destY = oponentY - 1; if (InBounds(board, destX, destY)) { dest = new Coordinate(board[destX, destY]); } else { return map; } if (dest.Status != Piece.None) return map; dest.Status = srcCoordinate.Status; IsBecameAKing(board, dest); if (board.IsKing(dest)) { opponentPiece = board[oponentCoordinate.X, oponentCoordinate.Y].Status; board[oponentCoordinate.X, oponentCoordinate.Y].Status = Piece.None; } //find coordinates if we can continue capture from dest IList<Coordinate> moreOptionalDirCaptures = GetMovesInDirection(board, dest, player); map.Add(new List<Coordinate> {oponentCoordinate}, dest); if (moreOptionalDirCaptures.Count == 0) { return map; } foreach (var cid in moreOptionalDirCaptures) { if (board.IsOpponentPiece(player, cid)) { IDictionary<IList<Coordinate>, Coordinate> temp = CoordsToCaptureAndDest(board, dest, cid, player); if (temp.Keys.Count() > map.Keys.Count()) { map = temp; if (map.Values.Contains(dest)) { var item = map.FirstOrDefault((x => x.Value.X == dest.X && x.Value.Y == dest.Y)); map.Remove(item.Key); } } else if (temp.Keys.Count() == map.Keys.Count()) { map = map.Concat(temp).ToDictionary(pair => pair.Key, pair => pair.Value); if (map.Values.Contains(dest)) { var item = map.FirstOrDefault((x => x.Value.X == dest.X && x.Value.Y == dest.Y)); map.Remove(item.Key); } } } } if (!map.Values.Contains(dest)) { foreach (var item in map) { item.Key.Add(oponentCoordinate); } } if (board[oponentCoordinate.X, oponentCoordinate.Y].Status == Piece.None) { board[oponentCoordinate.X, oponentCoordinate.Y].Status = opponentPiece; } return map; }
/// <summary> /// Checkes whether the coordinate can capture /// </summary> /// <param name="board"></param> /// <param name="coordinate"></param> /// <param name="player"></param> /// <returns></returns> private int CanCapture(Board board, Coordinate coordinate, Player player) { Rules rule = new Rules(); IList<Coordinate> coordinatesinDirection = rule.GetMovesInDirection(board, coordinate, player); int max = 0; foreach (var cid in coordinatesinDirection) { if (board.IsOpponentPiece(player, cid)) { IDictionary<IList<Coordinate>, Coordinate> captures = rule.CoordsToCaptureAndDest(board, coordinate, cid, player); if (captures.Count > 0) { if (captures.ElementAt(0).Key.Count > max) { max = captures.ElementAt(0).Key.Count; } } } } return max; }