Source code: hangman1/Visit.java
1 /* This work is hereby released into the Public Domain.
2 * To view a copy of the public domain dedication, visit
3 * http://creativecommons.org/licenses/publicdomain/
4 * or send a letter to Creative Commons, 559 Nathan Abbott Way,
5 * Stanford, California 94305, USA.
6 */
7 package hangman1;
8
9 /**
10 *
11 * The Visit class runs most of the game logic and acts as controller, mediating
12 * between the pure interface code and the pure logic code.
13 *
14 * @author Howard Lewis Ship (original Tapestry version)
15 * @author Hand Bergsten (modified for JSF example)
16 */
17
18 public class Visit
19 {
20 // In a real application, the word source would be shared between all sessions.
21 // Here, we just allow each Visit to have its own instance.
22
23 private WordSource _wordSource = new WordSource();
24
25 // On the other hand, the Game is specifically for this
26 // Visit and only this Visit.
27
28 private Game _game = new Game();
29
30 // Converted to a JSF action method
31 public String startGame()
32 {
33 _game.start(_wordSource.nextWord());
34
35 // Now that the Game is initialized, we can go to the Guess
36 // page to allow the player to start making guesses.
37
38 // Note! in the JSF version, the page selection is handled
39 // by a navigation rule in faces-config.xml based on the
40 // outcome value.
41
42 return "newGame";
43 }
44
45 /**
46 * Processes the player's guess, possibly updating the response
47 * page to be "Win" or "Lose".
48 *
49 **/
50 // Converted to a JSF action method, invoked from GuessBean
51 public String makeGuess(char ch)
52 {
53
54 // If this return true, then stay on this page at let
55 // player keep guessing.
56
57 if (_game.makeGuess(ch))
58 return "notDone";
59
60 return _game.isWin() ? "win" : "lose";
61 }
62
63 /**
64 * Returns the {@link Game} instance for this Visit; this is used
65 * primarily by the {@link Guess} page to display things like
66 * the number of remaining guesses and the list of guessed
67 * and unguessed letters.
68 *
69 **/
70
71 public Game getGame()
72 {
73 return _game;
74 }
75
76 /**
77 * Added as a bridge to Game.getLetters(), turning the char[] into
78 * a String[], because the JSF UIData component doesn't handle
79 * primitive type arrays (and String is easier to compare with in
80 * an EL expression). This is a JSF flaw that will hopefully be
81 * fixed in a future version.
82 */
83 public String[] getLetters()
84 {
85 char[] letters = _game.getLetters();
86 String[] wrappedLetters = new String[letters.length];
87 for (int i = 0; i < letters.length; i++) {
88 wrappedLetters[i] = String.valueOf(letters[i]);
89 }
90 return wrappedLetters;
91 }
92
93 /**
94 * Added for JSF version. Returns an array of GuessBean instances
95 * with one element per guess.
96 */
97 public GuessBean[] getGuesses()
98 {
99 boolean[] guessed = _game.getGuessedLetters();
100 GuessBean[] guesses = new GuessBean[guessed.length];
101 for (int i = 0; i < guessed.length; i++) {
102 if (guessed[i]) {
103 guesses[i] = new GuessBean('#', this);
104 }
105 else {
106 guesses[i] = new GuessBean((char) ('a' + i), this);
107 }
108 }
109 return guesses;
110 }
111
112 /**
113 * Added for the JSF version. A bean that holds a letter and an
114 * action method for guessing the letter.
115 */
116 public static class GuessBean {
117 private char c;
118 private Visit v;
119
120 public GuessBean(char c, Visit v) {
121 this.c = c;
122 this.v = v;
123 }
124
125 public String getLetter() {
126 return String.valueOf(c);
127 }
128
129 public String makeGuess() {
130 return v.makeGuess(c);
131 }
132 }
133 }