public GameState TryMakeMove(GameState oldState, Coords from, Coords to) { GameState newState = oldState.Clone(); Context ctx = new Context(newState.GlobalContext); // Special vars x, y are from coordinates ctx.SetXYZ(from, newState.CurrentPlayer); ctx.SetVariable("from", Transform(from, newState.CurrentPlayer)); ctx.SetVariable("to", Transform(to, newState.CurrentPlayer)); ctx.SetVariable("NewGameState", newState); if (!MoveIsValidGlobal(newState, from, to, ctx)) return null; Piece piece = board.PieceAt(newState, from, null); Piece oppPiece = board.PieceAt(newState, to, null); bool isInlist = EnumerateMovesFromCoord(newState, from).Any( md => Coords.Match(md.From, from) && Coords.Match(md.To, to)); if (!isInlist) return null; foreach (var rule in moveRules) { // No offboard rules here if (rule.OffboardRule) continue; var fromT = Transform(from, newState.CurrentPlayer); var toT = Transform(to, newState.CurrentPlayer); if (!MoveIsValidForRule(newState, rule, null, fromT, toT, ctx)) continue; // Move is valid rule.RunAction(newState, ctx); // Perform the move piece = board.PieceAt(newState, from, null); if (!board.TryRemove(newState, from, null)) { // Original piece was removed, should not happen! throw new InvalidGameException("Cannot move from " + from.ToString() + ", piece " + oppPiece.ToString() + " was removed!"); } if (!board.TryPut(newState, to, piece, null)) { // Piece was not captured throw new InvalidGameException("Cannot move to " + to.ToString() + ", piece " + oppPiece.ToString() + " is in the way!"); } ctx.SetXYZ(to, newState.CurrentPlayer); // Move was performed oldStates.Add(oldState); newState.CurrentPlayer.PostMove(newState, ctx); PostMoveActions(newState); return newState; } // No suitable rule found. return null; }
public GameState TryMakeMoveFromOffboard(GameState oldState, Piece piece, Coords to) { GameState newState = oldState.Clone(); Context ctx = new Context(newState.GlobalContext); ctx.SetVariable("to", Transform(to, newState.CurrentPlayer)); ctx.SetVariable("NewGameState", newState); // piece cannot be null if (piece == null) return null; // Cannot move opponent's piece if (piece.Owner != newState.CurrentPlayer) return null; bool isInlist = EnumerateMovesFromOffboard(newState, piece).Any( md => md.From == null && Coords.Match(md.To, to) && md.PieceType == piece.Type); if (!isInlist) return null; if (!MoveIsValidGlobal(newState, null, to, ctx)) return null; Piece oppPiece = board.PieceAt(newState, to, null); foreach (var rule in moveRules) { // Only offboard rules here if (!rule.OffboardRule) continue; if (!MoveIsValidForRule(newState, rule, piece, null, to, ctx)) continue; // Move is valid rule.RunAction(newState, ctx); // Perform the move if (!newState.CurrentPlayer.RemoveOffBoard(newState, piece)) { // Original piece was removed, should not happen! throw new InvalidGameException("Cannot move from offboard, piece " + oppPiece.ToString() + " was removed!"); } if (!board.TryPut(newState, to, piece, null)) { // Piece was not captured throw new InvalidGameException("Cannot move to " + to.ToString() + ", piece " + oppPiece.ToString() + " is in the way!"); } ctx.SetXYZ(to, newState.CurrentPlayer); // Move was performed oldStates.Add(oldState); newState.CurrentPlayer.PostMove(newState, ctx); PostMoveActions(newState); return newState; } // No suitable rule found. return null; }
protected override void OnRender(System.Windows.Media.DrawingContext dc) { if (game == null) return; if (ImageCache == null) return; bool needsCheckerBoard = true; if (ImageCache.Contains("bg")) { dc.DrawImage(ImageCache["bg"], new Rect(0, 0, Width, Height)); needsCheckerBoard = false; } Coords size = ict.GameToBoard(game.Size); for (int i = 0; i < size[0]; i++) { for (int j = 0; j < size[1]; j++) { int myj = size[1] - j - 1; Coords c = new Coords(i+1, j+1); if (highlightCoord.Contains(c)) { dc.DrawRectangle(Brushes.LightBlue, null, new Rect(i * 30, myj * 30, 30, 30)); } else if (needsCheckerBoard) { Brush b = ((i + j) % 2) == 0 ? Brushes.Brown : Brushes.BurlyWood; dc.DrawRectangle(b, null, new Rect(i * 30, myj * 30, 30, 30)); } } } foreach (var kvp in game.GetPieces(GetGameState())) { Coords c = ict.GameToBoard(kvp.Key); Piece p = kvp.Value; string player = p.Owner.ID.ToString(); string type = p.Type; int x = (c[0]-1) * 30; int y = (size[1]-c[1]) * 30; if (highlightPiece.Contains(p)) { dc.DrawRectangle(Brushes.LightBlue, null, new Rect(x, y, 30, 30)); } dc.DrawImage(ImageCache[type + player], new System.Windows.Rect(x, y, 30, 30)); } for (int i = 0; i < size[0]; i++) { for (int j = 0; j < size[1]; j++) { int myj = size[1] - j - 1; Coords c = new Coords(i + 1, j + 1); if (PrintGameCoords && ict.IsValidBoardCoord(c)) { string str = c.ToString() + "\n" + ict.BoardToGame(c); dc.DrawText(new FormattedText( str, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Consolas"), 8, Brushes.Black), new Point(i * 30, myj * 30)); } } } }