scg/ch10/Pig

From FANG

Jump to: navigation, search

001 package scg.ch10;
002 
003 import java.util.ArrayList;
004 import java.util.Scanner;
005 
006 /**
007  * Multiple players (at a single computer) can play Pig. Pig is a dice
008  * game. Players take turns rolling one die. They keep track of the sum
009  * of the rolls until they add it to their total (and pass the die) or
010  * the roll a 1 (a Pig) in which case they lose the points and the die.
011  * First player to 100 wins.
012  */
013 public class Pig {
014   /** score to which _all_ players play */
015   public static final int GAME_SCORE = 100;
016 
017   /** scanner wrapped around standard input */
018   static Scanner keyboard = new Scanner(System.in);
019 
020   /** all of the players with names and scores */
021   private final ArrayList<Player> standings;
022 
023   /**
024    * Construct a new instance of the {@link Pig} game. The game has a
025    * list of {@link Player}s which is filled in in the {@link
026    * #getPlayersNames()} method.
027    */
028   private Pig() {
029     standings = new ArrayList<Player>();
030   }
031 
032   /**
033    * Print the prompt on the standard output until the user answers
034    * either 'y', 'n', 'yes', or 'no'.
035    *
036    @param   prompt  the prompt to show the user
037    *
038    @return  true if user answered 'y' or 'yes'; false otherwise
039    */
040   public static boolean answersYes(String prompt{
041     String userAnswer = "";
042     // sentinel: userAnswer is a valid answer
043     while (!userAnswer.equalsIgnoreCase("y"&&
044         !userAnswer.equalsIgnoreCase("n"&&
045         !userAnswer.equalsIgnoreCase("yes"&&
046         !userAnswer.equalsIgnoreCase("no")) {
047       userAnswer = getLine(prompt);
048     }
049     // userAnswer: "y", "yes", "n", or "no"; first letter differentiates
050     return userAnswer.substring(01).equalsIgnoreCase("y");
051   }
052 
053   /**
054    * Print the prompt on standard output, read the next line from the
055    * standard input and return that value.
056    *
057    @param   prompt  the prompt/question to show the user
058    *
059    @return  the {@link String} typed in by the user; it could be empty
060    */
061   public static String getLine(String prompt{
062     System.out.print(prompt);
063     System.out.print(" ");
064     return keyboard.nextLine();
065   }
066 
067   /**
068    * The main program. At this level: make sure there is a file name on
069    * the command-line, construct a new {@link Pig} object, load and play
070    * the game.
071    *
072    @param  args command-line arguments; ignored by this program
073    */
074   public static void main(String[] args{
075     Pig game = new Pig();
076     game.getPlayersNames();
077     if (game.isPlayable()) {
078       game.play();
079     } else {
080       System.err.println("Not enough players to make game playable.");
081     }
082   }
083 
084   /**
085    * Announce the winner of the game. Method shows the sorted standings
086    * table and then announces the winner at the end.
087    *
088    @param  winner  reference to the {@link Player} who won the game
089    */
090   private void announceWinner(Player winner{
091     sp_Sort(standings);
092     System.out.println("Final Standings:");
093     showStandings();
094     System.out.println(winner.getName() + " wins with " +
095       winner.getScore() + " points.");
096   }
097 
098   /**
099    * Update the state of the game. Returns true if the game should
100    continuefalse otherwise.
101    *
102    @param   curr  the index in standings of the current player
103    *
104    @return  true if game should continuefalse otherwise
105    */
106   private boolean continueGame(Player curr{
107     boolean currHasWon = curr.getScore() >= GAME_SCORE;
108     return !currHasWon;
109   }
110 
111   /**
112    * Get the n'th player in the list of players.
113    *
114    @param   n  index of the player to fetch
115    *
116    @return  reference to the player in position n of the standings
117    *          list
118    */
119   private Player getPlayer(int n{
120     return standings.get(n);
121   }
122 
123   /**
124    * Get the index of the {@link Player} p in the {@link #standings}
125    * list.
126    *
127    @param   p  the {@link Player} to find
128    *
129    @return  the index of p in the standings (if it exists); -1
130    *          otherwise
131    */
132   private int indexOf(Player p{
133     int ndx = -1;
134     for (int = 0; i != standings.size()++i{
135       if (standings.get(i== p{
136         ndx = i;
137       }
138     }
139     return ndx;
140   }
141 
142   /**
143    * Get player's names from the user. A sentinel-controlled loop
144    * (sentinel: when user enters "done" as a player's name) uses {@link
145    * #getLine(String)} to prompt user for player's names. A {@link
146    * Player} object is then constructed for the new player.<br />
147    {@link #standings} is updated by this method.
148    */
149   private void getPlayersNames() {
150     String playerName = "";
151     while (!playerName.equalsIgnoreCase("done")) {
152       playerName = getLine("Next player's Name ('done' to exit):");
153       if (!playerName.equalsIgnoreCase("done")) {
154         standings.add(new Player(playerName));
155       }
156     }
157   }
158 
159   /**
160    * Get input from the user to complete their turn
161    *
162    @param  curr  reference to the current {@link Player}
163    */
164   private void handlePlayerTurn(Player curr{
165     curr.takeTurn();
166   }
167 
168   /**
169    * Is this game playable? Are there enough players?
170    *
171    @return  true if there are enough players; false otherwise
172    */
173   private boolean isPlayable() {
174     boolean hasPlayerList = standings != null;
175     boolean hasEnoughPlayers = hasPlayerList && (standings.size() 1);
176     return hasPlayerList && hasEnoughPlayers;
177   }
178 
179   /**
180    * Increment the turn variable; return the next turn number.
181    *
182    @param   currentTurn  the current turn
183    *
184    @return  the index of the next player whose turn it should be
185    */
186   private int nextTurn(int currentTurn{
187     return (currentTurn + 1% standings.size();
188   }
189 
190   /**
191    * Play the game.<br />
192    * While the game is being played, one player takes their turn (a
193    * video game loop is in there). If player wins (can only happen at
194    * the end of their turn), announce it and end play If the player does
195    * not win, advance the turn index by 1 modulo the number of players
196    * (players numbered from 0 inside {@link #standings}). When we roll
197    * over to showing the first player print a standing's table in player
198    * number order.
199    */
200   private void play() {
201     int turn = 0;
202     Player curr = null;
203     boolean playing = true;
204     while (playing{
205       curr = getPlayer(turn);
206       showState(curr);
207       handlePlayerTurn(curr);
208       playing = continueGame(curr);
209       turn = nextTurn(turn);
210     }
211     announceWinner(curr);
212   }
213 
214   /**
215    * Print the standings (player's names and scores) in the order they
216    * are stored in {@link #standings}.
217    */
218   private void showStandings() {
219     for (int = 0; i != standings.size()++i{
220       System.out.println("  " + standings.get(i));
221     }
222   }
223 
224   /**
225    * Print the current state of the game. Show the standings (if
226    * necessary) and show the current player's status.
227    *
228    @param  curr  reference to the {@link Player} whose turn it is
229    */
230   private void showState(Player curr{
231     boolean isFirstPlayersTurn = (indexOf(curr== 0);
232     if (isFirstPlayersTurn{
233       System.out.println();// improve readability of output
234       System.out.println("Standings:");
235       showStandings();
236     }
237     System.out.println();// improve readability of output
238     System.out.println(curr);
239   }
240 
241   /**
242    * Find the index of the largest score inside of standings at or after
243    * the given starting index
244    *
245    @param   aList       reference to the list in which the index of
246    *                      the largest element is to be found
247    @param   startIndex  start searching at this index in the list
248    *
249    @return  a number >= to startIndex, an index into aList; if
250    *          startIndex is out of range, will return startIndex;
251    *          otherwise will always return a valid index
252    */
253   private int sp_LargestIndex(ArrayList<Player> standings,
254     int startIndex{
255     int largestNdx = startIndex;
256     for (int contenderNdx = startIndex + 1;
257         contenderNdx != standings.size()
258         ++contenderNdx{
259       if (standings.get(contenderNdx).getScore() >
260           standings.get(largestNdx).getScore()) {
261         largestNdx = contenderNdx;
262       }
263     }
264     return largestNdx;
265   }
266 
267   /**
268    * Sort the standings in descending order by score. firstUnsortedIndex
269    * indexes the first entry in the standings which is not yet sorted.
270    * The body of the outer loop moves the right element into the first
271    * unsorted position (making that position sorted), so
272    * firstUnsortedIndex can be incremented (by the for loop).<br />
273    */
274   private void sp_Sort(ArrayList<Player> standings{
275     for (int firstUnsortedIndex = 0;
276         firstUnsortedIndex != standings.size()
277         ++firstUnsortedIndex{
278       int largestUnsortedIndex = 
279         sp_LargestIndex(standings, firstUnsortedIndex);
280       sp_Swap(standings, firstUnsortedIndex, largestUnsortedIndex);
281     }
282   }
283 
284   /**
285    * Swap elements standings[a] and standings[b] (using array notation).
286    * Works for all valid index value for a and b (even if they are
287    * equal). Does not do anything crafty when they are equal.
288    *
289    @param  standings  list in which elements should be changed
290    @param  a          an index into aList
291    @param  b          an index into aList
292    */
293   private void sp_Swap(ArrayList<Player> standings, int a, int b{
294     Player temp = standings.get(a);
295     standings.set(a, standings.get(b));
296     standings.set(b, temp);
297   }
298 }
299 
300 //Uploaded on Mon Mar 29 21:39:50 EDT 2010


Download/View scg/ch10/Pig.java





Views
Personal tools
Add to 
del.icio.usAdd to 
diggAdd to 
FacebookAdd to 
favoritesAdd to 
GoogleAdd to 
MySpaceAdd to 
PrintAdd to 
SlashdotAdd to 
StumbleUponAdd to 
Twitter

Games
Games