EMMA Coverage Report (generated Fri Mar 15 09:08:15 CET 2013)
[all classes][jpacman.model]

COVERAGE SUMMARY FOR SOURCE FILE [Move.java]

nameclass, %method, %block, %line, %
Move.java100% (1/1)92%  (12/13)71%  (245/343)79%  (43.2/55)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Move100% (1/1)92%  (12/13)71%  (245/343)79%  (43.2/55)
die (): void 0%   (0/1)0%   (0/13)0%   (0/3)
apply (): void 100% (1/1)64%  (45/70)74%  (8.9/12)
playerDies (): boolean 100% (1/1)67%  (8/12)78%  (1.6/2)
precomputeEffects (): void 100% (1/1)70%  (50/71)85%  (11.9/14)
Move (MovingGuest, Cell): void 100% (1/1)74%  (48/65)91%  (11.8/13)
<static initializer> 100% (1/1)75%  (6/8)75%  (0.8/1)
moveDone (): boolean 100% (1/1)76%  (25/33)72%  (2.2/3)
movePossible (): boolean 100% (1/1)81%  (21/26)75%  (1.5/2)
withinBorder (): boolean 100% (1/1)86%  (6/7)85%  (0.8/1)
tryMoveToGuestPrecondition (Guest): boolean 100% (1/1)92%  (11/12)91%  (0.9/1)
moveInvariant (): boolean 100% (1/1)95%  (19/20)95%  (1/1)
getMovingGuest (): MovingGuest 100% (1/1)100% (3/3)100% (1/1)
initialized (): boolean 100% (1/1)100% (3/3)100% (1/1)

1package jpacman.model;
2 
3/**
4 * A potential move from one cell to another. The responsibilities of this class
5 * include indicating the effect of the move (player dies, player wins, ...),
6 * whether the move is possible, and actually carrying out the move.
7 * <p>
8 * This class actually implements the Command design pattern from Gamma et al:
9 * The apply() method takes the role of the execution, and ensures that the move
10 * is actually done. The way the effects are handled is the responsibility of
11 * the clients of this class.
12 * <p>
13 *
14 * @author Arie van Deursen, created August 2003.
15 * @version $Id: Move.java,v 1.8 2008/02/04 10:11:19 arie Exp $
16 */
17public abstract class Move {
18 
19    /**
20     * The guest who initiated the move.
21     */
22    private MovingGuest mover = null;
23 
24 
25    /**
26     * The target cell the mover would like to go to.
27     */
28    private Cell to = null;
29 
30    /**
31     * Is the target cell indeed empty and reachable?
32     */
33    private boolean targetCellAvailable = false;
34 
35    /**
36     * Is the player going to die as a result of this move?
37     */
38    private boolean playerDies = false;
39 
40    /**
41     * Are we ready precomputing all possible effects of this move?
42     */
43    private boolean initialized = false;
44 
45    /**
46     * Create a move from a MovingGuest to a particular Cell.
47     * Precondition: the moving guest occupies a cell.
48     * The target cell can be null, in which case
49     * the move simply won't be possible.
50     *
51     * @param fromGuest
52     *            The guest to be moved
53     * @param toCell
54     *            The target location
55     */
56    public Move(MovingGuest fromGuest, Cell toCell) {
57        assert fromGuest != null;
58        assert fromGuest.getLocation() != null;
59        assert toCell == null
60        || fromGuest.getLocation().getBoard() == toCell.getBoard();
61        this.mover = fromGuest;
62        this.to = toCell;
63        assert moveInvariant() : "Move invariant invalid";
64    }
65 
66    /**
67     * Check that the guest to be moved indeed occupies a cell.
68     * Furthermore, moves that cause the player to die are not possible.
69     *
70     * @return True iff the mover occupies a cell.
71     */
72    public boolean moveInvariant() {
73        return mover != null
74            && mover.getLocation() != null
75            && (initialized ? !(movePossible() && playerDies) : true);
76    }
77 
78    /**
79     * Compute all possible effects of this move, such as the potential death of
80     * the player and whether the move is possible at all. Precondition: not
81     * called before. Postcondition: initialization completed.
82     */
83    protected void precomputeEffects() {
84        assert moveInvariant();
85        assert !initialized() : "Can't re-initialized the move.";
86        boolean cellAvailable = false;
87        if (withinBorder()) {
88            assert to != null;
89            Guest targetGuest = to.getInhabitant();
90            if (targetGuest == null) {
91                cellAvailable = true;
92            } else {
93                cellAvailable = tryMoveToGuest(targetGuest);
94            }
95        }
96        this.targetCellAvailable = cellAvailable;
97        initialized = true;
98        assert initialized();
99        assert moveInvariant();
100    }
101 
102    /**
103     * Try to move to an occupied cell.
104     * Precondition: targetGuest != null and still initializing
105     * (see tryMoveToGuestPrecondition).
106     * <p>
107     * This method implements a double dispatch: the actual behavior depends on
108     * both the subclass of the source and the target guest.
109     *
110     * @param targetGuest
111     *            Guest the mover will meet
112     * @return true iff the move is possible.
113     */
114    protected abstract boolean tryMoveToGuest(Guest targetGuest);
115 
116    /**
117     * Boolean function representing the precondition of tryMoveToGuest(Guest
118     * targetGuest).
119     *
120     * @param targetGuest The guest this mover is going tomeet.
121     * @return true iff the precondition of tryMoveToGuest() holds.
122     */
123    protected boolean tryMoveToGuestPrecondition(Guest targetGuest) {
124        return withinBorder() && targetGuest != null && !initialized();
125    }
126 
127    /**
128     * @return true iff the target cell falls within the borders of the Board.
129     */
130    private boolean withinBorder() {
131        return to != null;
132    }
133 
134    /**
135     * Check if the method has been initialized via the precomputeEffects
136     * method.
137     *
138     * @return true iff precomputeEffects has been called.
139     */
140    public boolean initialized() {
141        return initialized;
142    }
143 
144    /**
145     * Return true iff the player will die because of this move. Precondition:
146     * class has been initialized.
147     *
148     * @return true iff player won't survive this move.
149     */
150    public boolean playerDies() {
151        assert initialized();
152        return playerDies;
153    }
154 
155    /**
156     * Return true iff the move is possible. Precondition: class has been
157     * initialized.
158     *
159     * @return true iff the guest can make this move.
160     */
161    public boolean movePossible() {
162        assert initialized() : "run precompute first!";
163        return withinBorder()
164           && targetCellAvailable
165           && !playerDies()
166           && !moveDone();
167    }
168 
169    /**
170     * Actually carry out the move. precondition: the move is possible.
171     * postcondition: the old cell is empty, the target cell is occupied by the
172     * mover.
173     */
174    protected void apply() {
175        assert initialized();
176        assert movePossible() : "Cannot execute an impossible move.";
177 
178        Cell fromCell = mover.getLocation();
179        Guest targetGuest = to.getInhabitant();
180        if (targetGuest != null) {
181            // actually only necessary for food if
182            // the player moves...
183            targetGuest.deoccupy();
184        }
185        mover.deoccupy();
186        mover.occupy(to);
187 
188        assert fromCell.getInhabitant() == null : "old cell should be freed";
189        assert moveDone();
190        assert initialized();
191    }
192 
193    /**
194     * Invoke this method while precomputing the effects of this move if it is
195     * detected that the player will die because of this move. Precondition:
196     * initialization <b>not</b> yet completed.
197     */
198    protected void die() {
199        assert !initialized();
200        playerDies = true;
201    }
202 
203    /**
204     * Obtain the guest initiating the move.
205     *
206     * @return The mover.
207     */
208    protected MovingGuest getMovingGuest() {
209        return mover;
210    }
211 
212    /**
213     * @return true if the move has already been applied.
214     */
215    boolean moveDone() {
216        assert mover != null;
217        assert mover.getLocation() != null;
218        return to != null && mover.getLocation().equals(to);
219    }
220 
221 
222 
223}

[all classes][jpacman.model]
EMMA 2.0.5312 (C) Vladimir Roubtsov