001    package ai;
002    
003    import core.Move;
004    
005    /**
006     *  A Variation represents the sequence of optimal plays from a game
007     *  state.
008     *  
009     *  It is an immutable linked list, where each cell contains a move,
010     *  the value associated with that cell, and the length of the list.
011     *
012     *  @specfield value : int     // The value that the current player gets
013     *                             // by playing optimally.
014     *  @specfield depth : int //The number of plays this Variation is known to.
015     *  @specfield move : Move //The current move to make
016     *  @specfield variation : Variation //The next player's Variation after the move
017     *
018     *  Abstract invariant
019     *   depth  = length(variation)
020     *   value is consistent.
021     */
022    
023    public class Variation{
024        int value;
025        Variation v;
026        Move m;
027        int depth;
028    
029        // AF is trivial.
030        // RI:
031        // either depth == 0 and v == null and m == null 
032        // or     depth = 1 + v.depth, m != null, value = -v.value
033    
034        public Variation(int value){
035            super();
036            this.value = value;
037            v = null;
038            m = null;
039            depth = 0;
040        }
041    
042        private Variation(int value, Move move, int depth, Variation v){
043            this.v = v;
044            this.m = move;
045            this.value = value;
046            this.depth = depth;
047        }
048    
049    
050        /**
051         * @returns The value for this player with this variation.
052         */
053        public int getValue(){
054            return value;
055        }
056    
057        /**
058         * @returns The move at this point of the variation.
059         */
060        public Move getMove(){
061            return m;
062        }
063    
064        /**
065         * @returns The depth from this point of the variation.
066         */
067        public int getDepth(){
068            return depth;
069        }
070    
071        /**
072         * @returns A new variation with a given Move as the first move
073         * and this as the rest.
074         */
075        public Variation cons(Move move){
076            return new Variation(-value, move, depth + 1, this);
077        }
078    
079        /**
080         * @returns The rest of the Variation.
081         */
082        public Variation cdr(){
083            return v;
084        }
085    }