public void AnimateCancelMove(DeltaChange dc, Move move) { this.OnMoveAnimationPreview(); this.SetupAnimationCount(move); var figureDiedItems = dc.Filter((ch) => (ch.Action == MoveAction.Deletion) && (ch.FigureColor != this.viewModel.CurrentPlayerColor) && (ch.Square == move.To)); Queem.Core.Figure figureDied = Queem.Core.Figure.Nobody; if (figureDiedItems.Count() > 0) figureDied = figureDiedItems.First().FigureType; while (dc.HasItems()) { var change = dc.PopLast(); switch (change.Action) { case MoveAction.Move: this.InnerAnimateMove(new Move(change.AdditionalSquare, change.Square), figureDied); break; case MoveAction.Creation: break; case MoveAction.Deletion: if (move.To != change.Square) this.viewModel.UpdateFigure(change.Square, change.FigureType, change.FigureColor); break; } } }
public BenchmarkItem(string[] moves) { // for now only white color will be supported // (when i'll have time later, it will be expanded) this.provider = new GameProvider(new MovesArrayAllocator(100, 100)); Color color = Color.White; foreach (var moveStr in moves) { if (moveStr.Length == 0) continue; Move move = new Move(moveStr); if (this.provider.PlayerBoards[(int)color].Figures[(int)move.From] == Queem.Core.Figure.King) if (Math.Abs((int)move.From - (int)move.To) == 2) move.Type = MoveType.KingCastle; this.provider.ProcessMove(move, color); bool needsPromotion = (int)move.Type >= (int)MoveType.Promotion; if (needsPromotion) this.provider.PromotePawn( color, move.To, move.Type.GetPromotionFigure()); color = (Queem.Core.Color)(1 - (int)color); } solver = new ChessSolver(new DebutGraph()); this.lastColor = color; }
/// <summary> /// Adds all moves to Tree /// </summary> /// <param name="whitePos">Position of white figures on board</param> /// <param name="moves">Pairs of moves and replies e.g. ("e2-e4", "e7-e5")</param> public void AddMoves(PlayerPosition whitePos, params string[] moves) { Move temp = new Move(moves[0]); MoveNode tempNode = new MoveNode(temp); //iterator, that will add move to tree MoveIterator pushingIterator = null; MoveNode next = null; if (!rootMoves.ContainsKey(tempNode)) { rootMoves.Add(tempNode, tempNode); next = rootMoves[tempNode].Add(new Move(moves[1])); } else { next = rootMoves[tempNode].Add(new Move(moves[1])); } pushingIterator = GetIterator(tempNode); //next answer pushingIterator.CurrentNode = next; int i = 2; while (i < moves.Length) { pushingIterator.CurrentNode = pushingIterator.CurrentNode.Add(moves[i], whitePos); ++i; } }
public void AddItem(Move move) { lastIndex++; this.moves[lastIndex].From = move.From; this.moves[lastIndex].To = move.To; this.moves[lastIndex].Type = move.Type; }
public static List<Move> GenerateSituation(int depth) { int curr_depth = 0; Color myColor = Color.White; PlayerPosition myPosition = PlayerPosition.Down; GameProvider provider = new GameProvider(new MovesArrayAllocator()); Color color = myColor; Random rand = new Random(DateTime.Now.Millisecond); while (curr_depth < depth) { var player = provider.PlayerBoards[(int)color]; var opponent = provider.PlayerBoards[1 - (int)color]; var lastMove = new Move(Square.A1, Square.A1); if (provider.History.HasItems()) lastMove = provider.History.GetLastMove(); var moves = player.GetMoves( opponent, lastMove, MovesMask.AllMoves); provider.FilterMoves(moves, color); if (moves.Size == 0) { // some checkmate found break; } int index = rand.Next(moves.Size); // just get random move var move = new Move(moves.InnerArray[index]); provider.ProcessMove(move, color); bool needsPromotion = (int)move.Type >= (int)MoveType.Promotion; if (needsPromotion) provider.PromotePawn( color, move.To, move.Type.GetPromotionFigure()); color = (Queem.Core.Color)(1 - (int)color); curr_depth += 1; provider.Allocator.ReleaseLast(); } return provider.History.Moves; }
public SortingTests() { this.provider = new GameProvider(new MovesArrayAllocator(100, 100)); string path = "chess.game"; string[] lines = System.IO.File.ReadAllLines(path); Queem.Core.Color color = Queem.Core.Color.White; foreach (var line in lines) { var move = new Move(line); if (this.provider.PlayerBoards[(int)color].Figures[(int)move.From] == Queem.Core.Figure.King) if (Math.Abs((int)move.From - (int)move.To) == 2) move.Type = MoveType.KingCastle; this.provider.ProcessMove(move, color); color = (Queem.Core.Color)(1 - (int)color); } }
private void CancelLastMove() { if (!this.gameProvider.History.HasItems()) return; var lastMove = new Move(this.gameProvider.History.GetLastMove()); var lastDeltaChanges = this.gameProvider.History.GetLastDeltaChange().GetCopy(); this.chessboardControl.ChangeCurrentPlayer(); this.gameProvider.CancelLastMove(this.chessboardControl.CurrentPlayerColor); this.chessboardControl.AnimateCancelMove(lastDeltaChanges, lastMove); redoButton.IsEnabled = true; redoMoves.Add(new MoveWithDecision() { Move = lastMove, Decision = lastMove.Type.GetPromotionFigure() }); if (!this.gameProvider.History.HasItems()) this.cancelButton.IsEnabled = false; }
public static Move[][][][] CreateCastlingMoves() { var moves = new Move[2][][][]; for (int pos = 0; pos < 2; ++pos) { moves[pos] = new Move[2][][]; moves[pos][0] = new Move[3][]; moves[pos][1] = new Move[3][]; } moves[(int)Color.White][(int)PlayerPosition.Down][0] = new Move[] {new Move(Square.E1, Square.C1)}; moves[(int)Color.White][(int)PlayerPosition.Down][1] = new Move[] {new Move(Square.E1, Square.G1)}; moves[(int)Color.White][(int)PlayerPosition.Down][2] = new Move[] {new Move(Square.E1, Square.C1), new Move(Square.E1, Square.G1)}; moves[(int)Color.Black][(int)PlayerPosition.Down][0] = new Move[] {new Move(Square.D1, Square.B1)}; moves[(int)Color.Black][(int)PlayerPosition.Down][1] = new Move[] {new Move(Square.D1, Square.F1)}; moves[(int)Color.Black][(int)PlayerPosition.Down][2] = new Move[] {new Move(Square.D1, Square.B1), new Move(Square.D1, Square.F1)}; moves[(int)Color.White][(int)PlayerPosition.Up][0] = new Move[] {new Move(Square.D8, Square.B8)}; moves[(int)Color.White][(int)PlayerPosition.Up][1] = new Move[] {new Move(Square.D8, Square.F8)}; moves[(int)Color.White][(int)PlayerPosition.Up][2] = new Move[] {new Move(Square.D8, Square.B8), new Move(Square.D8, Square.F8)}; moves[(int)Color.Black][(int)PlayerPosition.Up][0] = new Move[] {new Move(Square.E8, Square.C8)}; moves[(int)Color.Black][(int)PlayerPosition.Up][1] = new Move[] {new Move(Square.E8, Square.G8)}; moves[(int)Color.Black][(int)PlayerPosition.Up][2] = new Move[] {new Move(Square.E8, Square.C8), new Move(Square.E8, Square.G8)}; return moves; }
public void TestSingleDownLeftAttacks1() { string boardString = "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "01011100" + "00000000" + "00000000"; // abcdefgh int rankIndex = 2; ulong board = BitBoardHelper.FromString(boardString); byte rank = (byte)(board >> (rankIndex * 8) & 0xff); var realMoves = new Move[] { new Move(Square.C4, Square.B3), new Move(Square.E4, Square.D3), new Move(Square.F4, Square.E3), new Move(Square.G4, Square.F3)}; var moves = PawnBitBoardHelper.AttacksLeftMoves[1][rankIndex][rank]; Assert.IsTrue(this.AreMovesEqual(realMoves, moves)); }
public void TestDoubleUpPushes() { string boardString = "00000000" + "00000000" + "00000000" + "00000000" + "01011100" + "00000000" + "00000000" + "00000000"; // abcdefgh int rankIndex = 3; ulong board = BitBoardHelper.FromString(boardString); byte rank = (byte)(board >> (rankIndex * 8) & 0xff); var realMoves = new Move[] { new Move(Square.B2, Square.B4), new Move(Square.D2, Square.D4), new Move(Square.E2, Square.E4), new Move(Square.F2, Square.F4)}; var moves = PawnBitBoardHelper.DoublePushes[0][rankIndex][rank]; Assert.IsTrue(this.AreMovesEqual(realMoves, moves)); }
public void TestSingleUpPushes2() { string boardString = "01000001" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000"; // abcdefgh int rankIndex = 7; ulong board = BitBoardHelper.FromString(boardString); byte rank = (byte)(board >> (rankIndex * 8) & 0xff); var realMoves = new Move[] { new Move(Square.B7, Square.B8), new Move(Square.H7, Square.H8)}; var moves = PawnBitBoardHelper.QuietMoves[0][rankIndex][rank]; Assert.IsTrue(this.AreMovesEqual(realMoves, moves)); }
public Move(Move from) { this.From = from.From; this.To = from.To; this.Type = from.Type; }
private bool TryFinishMove(SquareItem item) { MoveType type; if (!this.IsLegalMoveEnd(item.Square, out type)) return false; this.MoveEnd = item.Square; Move move = new Move(this.moveStart, item.Square, type); this.provider.ProcessMove(move, this.CurrentPlayerColor); return true; }
public void ProcessMove(Move move, Figure figure) { this.bitboards[(int)figure].DoMove(move); this.allFigures |= (1UL << (int)move.To); this.allFigures &= (~(1UL << (int)move.From)); this.figures[(int)move.From] = Figure.Nobody; this.figures[(int)move.To] = figure; }
protected void AddPromotionMoves(Move[] innerArray, int index, Figure destinationFigure) { if (destinationFigure != Figure.Nobody) { innerArray[index].Type = MoveType.KnightPromoCapture; innerArray[index + 1].Type = MoveType.BishopPromoCapture; innerArray[index + 2].Type = MoveType.RookPromoCapture; innerArray[index + 3].Type = MoveType.QueenPromoCapture; } else { innerArray[index].Type = MoveType.KnightPromotion; innerArray[index + 1].Type = MoveType.BishopPromotion; innerArray[index + 2].Type = MoveType.RookPromotion; innerArray[index + 3].Type = MoveType.QueenPromotion; } for (int i = 0; i < 4; ++i) innerArray[i].Value += (int)innerArray[i].Type * MoveTypeWeight; }
private void SetupAnimationCount(Move move) { if (move.Type == MoveType.KingCastle) this.desiredAnimationsCount = 2; else this.desiredAnimationsCount = 1; this.animationsDone = 0; }
public MoveNode(MoveNode from) { if ((object)from == null) { currentMove = null; replies = new Dictionary<MoveNode, MoveNode>(); } else { currentMove = new Move(from.currentMove); replies = new Dictionary<MoveNode, MoveNode>(from.replies); } }
private void InnerAnimateMove(Move move, Queem.Core.Figure figureDied) { var uniformGrid = mainGrid.FindChild<UniformGrid>(); var moveGrid = uniformGrid.Children.OfType<ContentPresenter>() .Where((child) => (child.DataContext as SquareItem).Square == move.From) .First(); int zIndex = Panel.GetZIndex(moveGrid); // set zIndex over 9000 Panel.SetZIndex(moveGrid, 9001); this.viewModel.AnimateMove(move, moveGrid.ActualWidth, (sourceItem) => { if (figureDied != Queem.Core.Figure.Nobody) sourceItem.UpdateChessFigure(figureDied, this.viewModel.CurrentPlayerColor.GetOpposite()); Panel.SetZIndex(moveGrid, zIndex); this.animationsDone += 1; if (this.animationsDone == this.desiredAnimationsCount) this.OnMoveAnimationFinished(); }); }
public void AnimateMove(Move move, double width, Action<SquareItem> animationFinishedAction) { double deltaX = move.GetDeltaX() * width; double deltaY = -move.GetDeltaY() * width; var sourceItem = this.squareItems[move.From.GetRealIndex()]; var targetItem = this.squareItems[move.To.GetRealIndex()]; var figureMoving = sourceItem.FigureType; sourceItem.AnimateShift(deltaX, deltaY, (item) => { this.dispatcher.BeginInvoke(new Action(() => { targetItem.UpdateChessFigure(item.FigureType, sourceItem.FigureColor); sourceItem.UpdateChessFigure(Figure.Nobody, sourceItem.FigureColor); sourceItem.ResetTransform(); animationFinishedAction(item); }), DispatcherPriority.Render); }); }
public List<HighlightedSquare> GetTargetSquares(Square square, Color playerColor) { var oppositeColor = 1 - (int)playerColor; var player = this.playerBoards[(int)playerColor]; var opponent = this.playerBoards[oppositeColor]; Move lastMove; if (this.History.HasItems()) lastMove = this.History.GetLastMove(); else lastMove = new Move(Square.A1, Square.A8); var moves = player.GetMoves(opponent, lastMove, MovesMask.AllMoves); this.FilterMoves(moves, playerColor); var result = moves.InnerArray.Take(moves.Size) .Where((move) => move.From == square) .Select((move) => new HighlightedSquare() { Square = move.To, MoveType = move.Type }) .GroupBy((hs) => hs.Square).Select((item) => item.First()) // for promotion moves .ToList(); this.allocator.ReleaseLast(); return result; }
/// <summary> /// Adds reply to certain move in moves map /// </summary> /// <param name="moveReply">Move-reply to add</param> /// <returns>Move node, that points to added move</returns> public MoveNode Add(Move moveReply) { MoveNode temp = new MoveNode(moveReply); if (!replies.ContainsKey(temp)) replies.Add(temp, temp); return replies[temp]; }
public MoveNode(string from, PlayerPosition whitePos) { currentMove = new Move(from); replies = new Dictionary<MoveNode, MoveNode>(); }
private bool AreMovesEqual(Move[] moves1, Move[] moves2) { if (moves1.Length != moves2.Length) return false; for (int i = 0; i < moves1.Length; ++i) { if ((moves1[i].From != moves2[i].From) || (moves1[i].To != moves2[i].To)) return false; } return true; }
public FixedArray GetMoves(PlayerBoard opponent, Move lastMove, MovesMask movesMask) { FixedArray moves = this.allocator.CreateNewArray(); var innerArray = moves.InnerArray; int index = 0; ulong mask = 0; if (movesMask == MovesMask.AllMoves) mask = ~this.allFigures; else mask = opponent.allFigures; var opponentFigures = opponent.allFigures; var otherFigures = opponentFigures | this.allFigures; // add knight, bishop, rook, queen moves for (int i = 0; i < PlayerBoard.KnightBishopRookQueen.Length; ++i) { var figure = PlayerBoard.KnightBishopRookQueen[i]; var newMovesList = this.moveGenerators[(int)figure].GetMoves(otherFigures, mask); for (int j = 0; j < newMovesList.Count; ++j) { var newMovesArray = newMovesList[j]; for (int k = 0; k < newMovesArray.Length; ++k) { var item = newMovesArray[k]; innerArray[index].From = item.From; innerArray[index].To = item.To; int destinationFigure = (int)opponent.figures[(int)item.To]; innerArray[index].Type = BitBoardHelper.MoveTypes[(int)figure][destinationFigure][(int)item.From][(int)item.To]; innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight + (int)opponent.figures[(int)item.To]; index++; } } } // add king moves var kingMoves = this.GetKingMoves(opponent, mask, movesMask); for (int j = 0; j < kingMoves.Count; ++j) { var newMovesArray = kingMoves[j]; for (int k = 0; k < newMovesArray.Length; ++k) { var item = newMovesArray[k]; innerArray[index].From = item.From; innerArray[index].To = item.To; int destinationFigure = (int)opponent.figures[(int)item.To]; if (Math.Abs((int)item.From - (int)item.To) == 2) innerArray[index].Type = MoveType.KingCastle; else innerArray[index].Type = BitBoardHelper.MoveTypes[(int)Figure.King][destinationFigure][(int)item.From][(int)item.To]; innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight + (int)opponent.figures[(int)item.To]; index++; } } // add to mask value mask = opponent.allFigures; // pawn in passing state bit int lastFrom = (int)lastMove.From; int lastTo = (int)lastMove.To; int middle = (lastFrom + lastTo) >> 1; bool wasLastMovePassing = false; if (Math.Abs(lastFrom - lastTo) == 16) if (opponent.Pawns.IsBitSet(lastMove.To)) { mask |= 1UL << middle; otherFigures |= mask; wasLastMovePassing = true; } if (movesMask == MovesMask.Attacks) { ulong pawns = this.bitboards[(int)Figure.Pawn].GetInnerValue(); otherFigures |= pawns >> 8; otherFigures |= pawns << 8; } // add pawns moves var pawnMoves = this.moveGenerators[(int)Figure.Pawn].GetMoves(otherFigures, mask); int moveTo; for (int j = 0; j < pawnMoves.Count; ++j) { var newMovesArray = pawnMoves[j]; for (int k = 0; k < newMovesArray.Length; ++k) { var item = innerArray[index]; item.From = newMovesArray[k].From; item.To = newMovesArray[k].To; moveTo = (int)item.To; int destinationFigure = (int)opponent.figures[(int)item.To]; item.Value = (int)opponent.figures[(int)item.To]; item.Type = BitBoardHelper.MoveTypes[(int)Figure.Pawn][destinationFigure][(int)item.From][moveTo]; if (wasLastMovePassing) if (item.To == (Square)middle) item.Type = MoveType.EpCapture; if ((moveTo < 8) || (moveTo >= 56)) { // add 4 moves for (int m = 1; m < 4; ++m) { innerArray[index + m].From = item.From; innerArray[index + m].To = item.To; innerArray[index + m].Value = (int)opponent.figures[(int)item.To]; } this.AddPromotionMoves(innerArray, index, (Figure)j); index += 3; } else item.Value += (int)item.Type; index++; } } moves.Size = index; return moves; }
private void readButton_Click(object sender, RoutedEventArgs e) { this.gameProvider = new GameProvider(this.gameProvider.Allocator); this.chessboardControl.SetupGameProvider(this.gameProvider); this.redoMoves = new List<MoveWithDecision>(); string path = Directory.GetCurrentDirectory() + System.IO.Path.DirectorySeparatorChar + "chess.game"; string[] lines = System.IO.File.ReadAllLines(path); Queem.Core.Color color = Queem.Core.Color.White; foreach (var line in lines) { var move = new Move(line); if (this.gameProvider.PlayerBoards[(int)color].Figures[(int)move.From] == Queem.Core.Figure.King) if (Math.Abs((int)move.From - (int)move.To) == 2) move.Type = MoveType.KingCastle; this.gameProvider.ProcessMove(move, color); color = (Queem.Core.Color)(1 - (int)color); } this.chessboardControl.RedrawAll(); }
public MoveNode(Move from) { currentMove = new Move(from); replies = new Dictionary<MoveNode, MoveNode>(); }
/* * Possible problematic situations * * ----------Pawn----------- * 1. move to in-passing state * 2. move from in-passing state * 3. kill other pawn that is in passing state * 4. just move * 5. kill a rook in state with possible castling * * * ----------Rook---------- * 1. kill a pawn in a passing state * 2. move from castling state * 3. be a part of a castling * 4. kill other rook in a castling state * 5. just move * * * ----------King---------- * 1. move from a castling state * 2. kill a pawn in a passing state * 3. kill a rook in a castling state */ public void ProcessMove(Move move, Color color) { var oppositeColor = (Color)(1 - (int)color); var playerBoard1 = this.playerBoards[(int)color]; var playerBoard2 = this.playerBoards[(int)oppositeColor]; var figureMoving = playerBoard1.Figures[(int)move.From]; var destinationFigure = playerBoard2.Figures[(int)move.To]; this.History.AddItem(move); var deltaChange = this.History.GetLastDeltaChange(); var moveChange = deltaChange.GetNext(MoveAction.Move); moveChange.Square = move.From; moveChange.AdditionalSquare = move.To; moveChange.FigureColor = color; moveChange.FigureType = figureMoving; moveChange.Data = playerBoard1.GetBoardProperty(figureMoving); playerBoard1.ProcessMove(move, figureMoving); if (destinationFigure != Figure.Nobody) { var killChange = deltaChange.GetNext(MoveAction.Deletion); killChange.Square = move.To; killChange.Data = playerBoard2.GetBoardProperty(destinationFigure); killChange.FigureType = destinationFigure; killChange.FigureColor = oppositeColor; playerBoard2.RemoveFigure(move.To, destinationFigure); return; } if (move.Type == MoveType.EpCapture) { var lastMove = this.History.GetPreLastMove(); var passingKillChange = deltaChange.GetNext(MoveAction.Deletion); passingKillChange.Square = lastMove.To; passingKillChange.FigureType = Figure.Pawn; passingKillChange.FigureColor = oppositeColor; playerBoard2.RemoveFigure(passingKillChange.Square, Figure.Pawn); return; } if (move.Type == MoveType.KingCastle) { int moveTo = (int)move.To; int moveFrom = (int)move.From; // will be +2 or -2 int difference = moveTo - moveFrom; // same as sign of difference difference = difference / 2; var rookMoveChange = deltaChange.GetNext(MoveAction.Move); // rook target rookMoveChange.AdditionalSquare = (Square)(moveTo - difference); // rook source // diff -> [1 -> 1, -1 -> 0] difference = (difference + 1) / 2; rookMoveChange.Square = (Square)((moveFrom / 8) * 8 + difference*7); rookMoveChange.FigureType = Figure.Rook; rookMoveChange.FigureColor = color; rookMoveChange.Data = playerBoard1.GetBoardProperty(Figure.Rook); playerBoard1.ProcessMove( new Move(rookMoveChange.Square, rookMoveChange.AdditionalSquare), Figure.Rook); return; } }
public void AnimateMove(DeltaChange dc, Move move) { this.OnMoveAnimationPreview(); this.SetupAnimationCount(move); while (dc.HasItems()) { var change = dc.PopLast(); switch(change.Action) { case MoveAction.Move: this.InnerAnimateMove(new Move(change.Square, change.AdditionalSquare), Queem.Core.Figure.Nobody); break; case MoveAction.Deletion: if (change.Square != move.To) // if not equal - passing capture this.viewModel.RemoveFigure(change.Square); break; case MoveAction.Creation: this.viewModel.UpdateFigure(change.Square, change.FigureType, change.FigureColor); break; } } }