KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > sampleproject > connectfour > PlayingStand


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2005, ThoughtWorks, Inc.
4  * 651 W Washington Ave. Suite 600
5  * Chicago, IL 60661 USA
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * + Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * + Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  *
20  * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
21  * names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior
23  * written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  ********************************************************************************/

37 package net.sourceforge.cruisecontrol.sampleproject.connectfour;
38
39 /**
40  * Represents the playing field (or stand) in the game of Connect Four. This
41  * class encapsulates all the game logic, including turn-based plays, winning,
42  * stalemating and illegal moves.
43  */

44 public class PlayingStand {
45     private static final int MAX_ROWS = 6;
46     private static final int MAX_COLUMNS = 7;
47
48     private final Chip[][] stand = new Chip[MAX_COLUMNS][MAX_ROWS];
49     private boolean gameOver;
50     private Chip winner = null;
51     private Chip lastPlayed;
52     private WinningPlacement winningPlacement;
53
54     public void dropRed(int columnNumber) throws GameOverException {
55         dropChip(Chip.RED, columnNumber);
56     }
57
58     public void dropBlack(int columnNumber) throws GameOverException {
59         dropChip(Chip.BLACK, columnNumber);
60     }
61
62     private void dropChip(Chip player, int columnNumber) {
63         if (gameOver) {
64             throw new GameOverException();
65         }
66
67         if (lastPlayed == player) {
68             throw new OutOfTurnException();
69         }
70
71         if (columnNumber < 0 || columnNumber >= MAX_COLUMNS) {
72             throw new InvalidColumnException();
73         }
74
75         if (stand[columnNumber][MAX_ROWS - 1] != null) {
76             throw new FullColumnException();
77         }
78
79         Chip[] column = stand[columnNumber];
80         for (int i = 0; i < column.length; i++) {
81             Chip nextChip = column[i];
82             if (nextChip == null) {
83                 column[i] = player;
84                 break;
85             }
86         }
87
88         lastPlayed = player;
89         gameOver = areFourConnected() || isFull();
90     }
91
92     public boolean isFull() {
93
94         for (int nextColumnNum = 0; nextColumnNum < stand.length; nextColumnNum++) {
95             if (stand[nextColumnNum][MAX_ROWS - 1] == null) {
96                 return false;
97             }
98         }
99
100         return true;
101     }
102
103     public boolean areFourConnected() {
104         for (int i = 0; i < stand.length; i++) {
105             Chip[] column = stand[i];
106             for (int j = 0; j < column.length; j++) {
107                 Chip nextCell = column[j];
108                 if (nextCell != null && (hasVerticalMatch(i, j) ||
109                         hasUpwardDiagonalMatch(i, j) ||
110                         hasDownwardDiagonalMatch(i, j) ||
111                         hasHorizontalMatch(i, j))) {
112                     winner = nextCell;
113                     return true;
114                 }
115             }
116         }
117
118         return false;
119     }
120
121     private boolean hasHorizontalMatch(int column, int row) {
122         Chip chip = stand[column][row];
123         winningPlacement = new WinningPlacement(column, row, Direction.HORIZONTAL);
124
125         try {
126             return stand[column + 1][row] == chip && stand[column + 2][row] == chip && stand[column + 3][row] == chip;
127         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
128             return false;
129         }
130     }
131
132     private boolean hasUpwardDiagonalMatch(int column, int row) {
133         Chip chip = stand[column][row];
134         winningPlacement = new WinningPlacement(column, row, Direction.UPWARD_DIAGONAL);
135         try {
136             return stand[column + 1][row + 1] == chip && stand[column + 2][row + 2] == chip &&
137                     stand[column + 3][row + 3] == chip;
138         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
139             return false;
140         }
141     }
142
143     private boolean hasDownwardDiagonalMatch(int column, int row) {
144         Chip chip = stand[column][row];
145         winningPlacement = new WinningPlacement(column, row, Direction.DOWNWARD_DIAGONAL);
146         try {
147             return stand[column + 1][row - 1] == chip && stand[column + 2][row - 2] == chip &&
148                     stand[column + 3][row - 3] == chip;
149         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
150             return false;
151         }
152     }
153
154     private boolean hasVerticalMatch(int column, int row) {
155         Chip chip = stand[column][row];
156         winningPlacement = new WinningPlacement(column, row, Direction.VERTICAL);
157         try {
158             return stand[column][row + 1] == chip && stand[column][row + 2] == chip && stand[column][row + 3] == chip;
159         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
160             return false;
161         }
162     }
163
164     public Chip getWinner() {
165         return winner;
166     }
167
168     public boolean isGameOver() {
169         return gameOver;
170     }
171
172     public WinningPlacement getWinningPlacement() {
173         if (!gameOver) {
174             throw new GameNotOverException();
175         }
176         if (isFull() && !areFourConnected()) {
177             throw new StalemateException();
178         }
179
180         return winningPlacement;
181     }
182
183     public class WinningPlacement {
184         private final Direction direction;
185         private final Cell startingCell;
186
187         public WinningPlacement(int column, int row, Direction direction) {
188             startingCell = new Cell(column, row);
189             this.direction = direction;
190         }
191
192         public Cell getStartingCell() {
193             return startingCell;
194         }
195
196         public Direction getDirection() {
197             return direction;
198         }
199     }
200
201
202 }
203
Popular Tags