2015-06-02 200 views
0

我正在寫一個國際象棋遊戲,但我一直在遇到一個錯誤。當我要求有效的動作時,我的程序會返回一些不應該有效的點。國際象棋遊戲無效移動

這是我當前的代碼

public enum PieceType { 
    PAWN('p', (piece, pieceOnEndTile, board, move) -> { 
     PieceTeam team = piece.getTeam(); 
     int dx = move.getdx(); 
     int dy = move.getdy(); 
     final boolean willKill = pieceOnEndTile != null && pieceOnEndTile.getTeam() != team; 
     int direction = -1; // to distinguish between the dy of black and white 
     if (team == PieceTeam.BLACK) { 
      direction = 1; // for black pawns, dy is positive, for white it's 
          // negative 
     } 
     dy = dy * direction; 
     boolean isKilling = willKill && dy == 1 && abs(dx) == 1; 
     boolean isMoving1 = dy == 1 && dx == 0 && pieceOnEndTile == null; 
     boolean isMoving2 = dy == 2 && dx == 0 && pieceOnEndTile == null && !piece.hasBeenMoved(); 

     return isKilling || isMoving1 || isMoving2; 

    }), BISHOP('b', (piece, pieceOnEndTile, board, move) -> { 
     PieceTeam team = piece.getTeam(); 
     int dx = move.getdx(); 
     int dy = move.getdy(); 
     return abs(dy) == abs(dx) && tileIsEmptyOrEnemy(pieceOnEndTile, team) && !pieceInWay(board, move, team); 
    }), KNIGHT('k', (piece, pieceOnEndTile, board, move) -> { 
     PieceTeam team = piece.getTeam(); 
     int dx = move.getdx(); 
     int dy = move.getdy(); 
     boolean isCorrectMove = (abs(dy) == abs(2 * dx) || (abs(dx) == abs(2 * dy))) && abs(dy) <= 2 && abs(dx) <= 2; 

     return isCorrectMove && tileIsEmptyOrEnemy(pieceOnEndTile, team); 
    }), ROOK('r', (piece, pieceOnEndTile, board, move) -> { 
     PieceTeam team = piece.getTeam(); 
     int dx = move.getdx(); 
     int dy = move.getdy(); 
     return (abs(dy) >= 1 && abs(dx) == 0 || abs(dx) >= 1 && abs(dy) == 0) && tileIsEmptyOrEnemy(pieceOnEndTile, team) && !pieceInWay(board, move, team); 
    }), QUEEN('Q', (piece, pieceOnEndTile, board, move) -> { 
     PieceTeam team = piece.getTeam(); 
     int dx = move.getdx(); 
     int dy = move.getdy(); 
     return (abs(dy) == abs(dx) || abs(dy) >= 1 && abs(dx) == 0 || abs(dx) >= 1 && abs(dy) == 0) && tileIsEmptyOrEnemy(pieceOnEndTile, team) && !pieceInWay(board, move, team); 
    }), KING('K', (piece, pieceOnEndTile, board, move) -> { 
     PieceTeam team = piece.getTeam(); 
     int dx = move.getdx(); 
     int dy = move.getdy(); 
     return abs(dy) <= 1 && abs(dx) <= 1 && tileIsEmptyOrEnemy(pieceOnEndTile, team); 
    }); 

    public final IsLegalMove isLegalMove; 
    public final char representation; 

    private PieceType(final char representation, final IsLegalMove isLegalMove) { 
     this.isLegalMove = isLegalMove; 
     this.representation = representation; 
    } 

    private static boolean tileIsEmptyOrEnemy(GamePiece piece, PieceTeam currentTeam) { 
     return piece == null || piece.getTeam() != currentTeam; 
    } 

    private static boolean pieceInWay(GamePiece[][] board, Move move, PieceTeam team) { 
     int changerx = (int) Math.signum(move.getdx()); 
     int changery = (int) Math.signum(move.getdy()); 
     for (int x = move.start.x + changerx, y = move.start.y + changery; x < move.end.x; x += changerx, y += changery) { 
      if (board[y][x] != null) { 
       return true; 
      } 
     } 
     return false; 
    } 

    @FunctionalInterface 
    public static interface IsLegalMove { 
     public boolean call(GamePiece piece, GamePiece pieceOnEndTile, GamePiece[][] board, Move move); 
    } 

} 

的問題,我認爲,在pieceInWay方法。我一直在盯着它,但我無法弄清楚。

+0

難道是'y = move.start.y + changery',y沒有聲明爲int。你得到什麼樣的錯誤? –

+0

一旦程序變得複雜,你確實需要一個測試工具來保持一切正常。像'testPawn()','testBishop()'和'testPieceInWay()'這樣的簡單方法將幫助你隔離錯誤並避免複雜的調試。 [某些信息在這裏。](http://martinfowler.com/bliki/UnitTest.html) – markspace

+0

哪些景點?哪些部分?在哪個委員會州? – RealSkeptic

回答

0

我通過寫出8個方向中的每一個的實際案例來解決它,現在它似乎工作。

public static boolean pieceInWay(final GamePiece[][] board, final Move move) { 
     final int changerx = (int) Math.signum(move.getdx()); 
     final int changery = (int) Math.signum(move.getdy()); 
     switch (Direction.getFromDelta(changerx, changery)) { 
     case DOWN: 
      for (int y = move.start.y + 1; y < move.end.y; y++) { 
       if (board[y][move.start.x] != null) { 
        return true; 
       } 
      } 
      break; 
     case DOWN_LEFT: 
      for (int y = move.start.y + 1, x = move.start.x - 1; y < move.end.y; y++, x--) { 
       if (board[y][x] != null) { 
        return true; 
       } 
      } 
      break; 
     case DOWN_RIGHT: 
      for (int y = move.start.y + 1, x = move.start.x + 1; y < move.end.y; y++, x++) { 
       if (board[y][x] != null) { 
        return true; 
       } 
      } 
      break; 
     case LEFT: 
      for (int x = move.start.x - 1; x > move.end.x; x--) { 
       if (board[move.start.y][x] != null) { 
        return true; 
       } 
      } 
      break; 
     case RIGHT: 
      for (int x = move.start.x + 1; x < move.end.x; x++) { 
       if (board[move.start.y][x] != null) { 
        return true; 
       } 
      } 
      break; 
     case UP: 
      for (int y = move.start.y - 1; y > move.end.y; y--) { 
       if (board[y][move.start.x] != null) { 
        return true; 
       } 
      } 
      break; 
     case UP_LEFT: 
      for (int y = move.start.y - 1, x = move.start.x - 1; y > move.end.y; y--, x--) { 
       if (board[y][x] != null) { 
        return true; 
       } 
      } 
      break; 
     case UP_RIGHT: 
      for (int y = move.start.y - 1, x = move.start.x + 1; y > move.end.y; y--, x++) { 
       if (board[y][x] != null) { 
        return true; 
       } 
      } 
      break; 
     } 
     return false; 
    } 

    @FunctionalInterface 
    public static interface IsLegalMove { 
     public boolean call(GamePiece piece, GamePiece pieceOnEndTile, GamePiece[][] board, Move move); 
    } 

    private static enum Direction { 
     UP(0, -1), 
     UP_RIGHT(1, -1), 
     RIGHT(1, 0), 
     DOWN_RIGHT(1, 1), 
     DOWN(0, 1), 
     DOWN_LEFT(-1, 1), 
     LEFT(-1, 0), 
     UP_LEFT(-1, -1); 

     public final int dx; 
     public final int dy; 

     private Direction(final int dx, final int dy) { 
      this.dx = dx; 
      this.dy = dy; 
     } 

     public static Direction getFromDelta(final int dx, final int dy) { 
      for (final Direction d : values()) { 
       if (d.dx == dx && d.dy == dy) { 
        return d; 
       } 
      } 
      return null; 
     } 
    } 
+0

好的。餅乾像往常一樣騎士。你知道騎士的動作嗎? –

+0

@ott是的,但我不需要與騎士一起使用此方法,因爲騎士跳躍而不是幻燈片。 – Kyranstar

+0

考慮到它,該方法需要重構。 b5有什麼?我能抓住它來增加我的分數嗎?我可以移動到C4來創造另一個威脅嗎? –