001    package rules;
002    import java.util.*;
003    
004    import core.*;
005    
006    /**
007     * Common superclass of bishop, rook, and queen (which all have
008     * similar movement).
009     * 
010     * Immutable.
011     *
012     * @specfield canmovediagonally: boolean
013     * @specfield canmovestraight: boolean
014     */
015    public abstract class StraightPiece extends Piece{
016        
017        /* Whether abs(dx)+abs(dy) is good */
018        protected boolean[] goodSum;
019    
020        //AF:
021        // canmovestraight = goodSum[1]
022        // canmovediagonally = goodSum[2]
023    
024        // RI:
025        //  goodsum.length == 3
026        //  goodsum[0] = false
027    
028        public StraightPiece(Color color, int lastMove, boolean oneGood,
029                             boolean twoGood){
030            super(color, lastMove);
031            goodSum = new boolean[3];
032            goodSum[0] = false;
033            goodSum[1] = oneGood;
034            goodSum[2] = twoGood;
035            checkRep();
036        }
037        
038        public boolean getGoodSum(int i){
039            assert(i >= 0 && i < 3);
040            return goodSum[i];
041        }
042        private void checkRep(){
043            assert(goodSum.length == 3);
044            assert(!goodSum[0]);
045        }
046        
047        protected abstract StraightPiece constructor(Color color, int lastMove);
048    
049        /**
050             * @see Piece
051             */
052        public Collection<Move> moveCandidates(GameState g, Position here){
053            Board board = g.getBoard();
054            Collection<Move> answer = new ArrayList<Move>();
055            int x = here.getX();
056            int y = here.getY();
057            int nx, ny;
058            for(int dx = -1; dx <= 1; dx++){
059                for(int dy = -1; dy <= 1; dy++){
060                    if (!goodSum[Math.abs(dx) + Math.abs(dy)])
061                        continue;
062                    for(nx = x + dx, ny = y + dy;
063                        Position.isValid(nx, ny);
064                        nx += dx, ny += dy){
065                        Color colorThere = board.get(nx, ny).getColor();
066                        if (colorThere == getColor()) {
067                            break;
068                        }
069                        answer.add(new Move(here, Position.get(nx, ny)));
070                        if (colorThere != Color.NONE)
071                            break;
072                    }
073                }
074            }
075            return answer;
076        }
077    
078    
079        /**
080             * @see Piece
081             */
082        public static boolean threatens(GameState g, Color color, Position pos){
083            Board board = g.getBoard();
084            int x = pos.getX(), y = pos.getY();
085            //StraightPiece
086            for(int dx = -1; dx <= 1; dx++){
087                for(int dy = -1; dy <= 1; dy++){
088                    int abs = Math.abs(dx) + Math.abs(dy);
089                    if (abs != 0){
090                        for(int i = 1; ; i++){
091                            if (!Position.isValid(x+dx*i, y+dy*i))
092                                break;
093                            Piece p  = board.get(x+dx*i, y+dy*i);
094                            if (p instanceof StraightPiece){
095                                if (p.getColor() == color &&
096                                    ((StraightPiece) p).getGoodSum(abs))
097                                    return true;
098                                break;
099                            } else if (p instanceof NoneSquare) {
100                                
101                            } else{
102                                break;
103                            }
104                        }
105                    }
106                }
107            }
108            return false;
109        }
110    }