001: #include <cstdlib>
002: #include <cmath>
003: #include <ctime>
004: 
005: using namespace std;
006: 
007: #include "ccc_win.h"
008: #include "ccc_time.h"
009: 
010: const double PI = 3.141592653589793;
011: 
012: /**
013:    A clock that can draw its face.
014: */
015: class Clock
016: {
017: public:
018:    /**
019:       Constructs a clock with a given center and radius.
020:       @param c the center of the clock
021:       @param r the radius of the clock
022:    */              
023:    Clock(Point c, double r);
024: 
025:    /**
026:       Sets the current time.
027:       @param t the time to set
028:    */
029:    void set_time(Time t);
030: 
031:    /**
032:       Draws the clock face, with tick marks and hands.
033:    */
034:    void draw() const;
035: private:
036:    /**
037:       Draw a tick mark (hour or minute mark).
038:       @param angle the angle in minutes (0...59, 0 = top)
039:       @param length the length of the tick mark
040:    */
041:    void draw_tick(double angle, double length) const;
042: 
043:    /**
044:       Draw a hand, starting from the center.
045:       @param angle the angle in minutes (0...59, 0 = top)
046:       @param length the length of the hand
047:    */
048:    void draw_hand(double angle, double length) const;
049: 
050:    Time current_time;
051:    Point center;
052:    double radius;
053: };
054: 
055: /**
056:    The player of the clock game.
057: */
058: class Player
059: {
060: public:
061:    /**
062:       Constructs a player with no name, level 1, and score 0.
063:    */
064:    Player();
065: 
066:    /**
067:       Constructs a player with given name and level.
068:       @param player_name the player name
069:       @param initial_level the player's level (1...4)
070:    */            
071:    Player(string player_name, int initial_level);
072: 
073:    /**
074:       Increments the score. Moves to next level if current 
075:       level complete
076:    */
077:    void increment_score();
078: 
079:    /**
080:       Gets the current level.
081:       @return the level
082:    */
083:    int get_level() const;
084: 
085:    /**
086:       Gets the player's name.
087:       @return the name
088:    */
089:    string get_name() const;
090: private:
091:    string name;
092:    int score;
093:    int level;
094: };
095: 
096: /**
097:    The clock game.
098: */
099: class Game
100: {
101: public:
102:    /**
103:       Constructs the game with a default player.
104:    */
105:    Game();
106: 
107:    /**
108:       Plays the game while the player wants to continue.
109:    */
110:    void play();
111: 
112:    /**
113:       Reads player name and level.
114:    */
115:    void read_player_information();
116: 
117:    /**
118:       Plays a round, with up to two guesses.
119:    */
120:    void play_round();
121: private:
122:    /**
123:       Makes a random time, depending on the level
124:       @return the random time
125:    */
126:    Time random_time();
127: 
128:    /**   
129:       Gets a time input from the user
130:       @return  the time guessed by the user
131:    */
132:    Time get_guess();
133: 
134:    Player player;
135: };
136: 
137: /**
138:    Sets the seed of the random number generator.
139: */
140: void rand_seed()
141: {  
142:    int seed = static_cast<int>(time(0));
143:    srand(seed);
144: }
145: 
146: /**
147:    Returns a random integer in a range.
148:    @param a the bottom of the range
149:    @param b the top of the range
150:    @return a random number x, a <= x and x <= b
151: */
152: int rand_int(int a, int b)
153: {  
154:    return a + rand() % (b - a + 1);
155: }
156: 
157: Clock::Clock(Point c, double r)
158: {  
159:    center = c;
160:    radius = r;
161: }
162: 
163: void Clock::set_time(Time t)
164: {  
165:    current_time = t;
166: }
167: 
168: void Clock::draw_tick(double angle, double length) const
169: {  
170:    double alpha = PI / 2 - 6 * angle * PI / 180;
171:    Point from(
172:       center.get_x() + cos(alpha) * radius * (1 - length),
173:       center.get_y() + sin(alpha) * radius * (1 - length));
174:    Point to(center.get_x() + cos(alpha) * radius,
175:       center.get_y() + sin(alpha) * radius);
176:    cwin << Line(from, to);
177: }
178: 
179: void Clock::draw_hand(double angle, double length) const
180: {  
181:    double alpha = PI / 2 - 6 * angle * PI / 180;
182:    Point from = center;
183:    Point to(center.get_x() + cos(alpha) * radius * length,
184:       center.get_y() + sin(alpha) * radius * length);
185:    cwin << Line(from, to);
186: }
187: 
188: void Clock::draw() const
189: {  
190:    cwin << Circle(center, radius);
191:    const double HOUR_TICK_LENGTH = 0.2;
192:    const double MINUTE_TICK_LENGTH = 0.1;
193:    const double HOUR_HAND_LENGTH = 0.6;
194:    const double MINUTE_HAND_LENGTH = 0.75;
195:    for (int i = 0; i < 12; i++)
196:    {  
197:       draw_tick(i * 5, HOUR_TICK_LENGTH);
198:       int j;
199:       for (j = 1; j <= 4; j++)
200:          draw_tick(i * 5 + j, MINUTE_TICK_LENGTH);
201:    }
202:    draw_hand(current_time.get_minutes(), MINUTE_HAND_LENGTH);
203:    draw_hand((current_time.get_hours() +
204:       current_time.get_minutes() / 60.0) * 5, HOUR_HAND_LENGTH);
205: }
206: 
207: Player::Player()
208: {  
209:    level = 1;
210:    score = 0;
211: }
212: 
213: Player::Player(string player_name, int initial_level)
214: {  
215:    name = player_name;
216:    level = initial_level;
217:    score = 0;
218: }
219: 
220: int Player::get_level() const
221: {  
222:    return level;
223: }
224: 
225: string Player::get_name() const
226: {  
227:    return name;
228: }
229: 
230: void Player::increment_score()
231: {  
232:    score++;
233:    if (score % 5 == 0 && level < 4)
234:       level++;
235: }
236: 
237: Game::Game()
238: {  
239: }
240: 
241: void Game::play()
242: {  
243:    rand_seed();
244:    read_player_information();
245:    string response;
246:    do
247:    {  
248:       play_round();
249:       response = cwin.get_string(
250:          "Do you want to play again? (y/n)");
251:    } 
252:    while (response == "y");
253: }
254: 
255: void Game::read_player_information()
256: {  
257:    string name = cwin.get_string("What is your name?");
258:    int initial_level;
259:    do
260:    {  
261:       initial_level = cwin.get_int(
262:          "At what level do you want to start? (1-4)");
263:    } 
264:    while (initial_level < 1 || initial_level > 4);
265:    player = Player(name, initial_level);
266: }
267: 
268: Time Game::random_time()
269: {  
270:    int level = player.get_level();
271:    int minutes;
272:    if (level == 1) minutes = 0;
273:    else if (level == 2) minutes = 15 * rand_int(0, 3);
274:    else if (level == 3) minutes = 5 * rand_int(0, 11);
275:    else minutes = rand_int(0, 59);
276:    int hours = rand_int(1, 12);
277:    return Time(hours, minutes, 0);
278: }
279: 
280: Time Game::get_guess()
281: {  
282:    int hours;
283:    do
284:    {  
285:       hours = cwin.get_int("Please enter hours: (1-12)");
286:    } 
287:    while (hours < 1 || hours > 12);
288:    int minutes;
289:    do
290:    {  
291:       minutes = cwin.get_int("Please enter minutes: (0-59)");
292:    } 
293:    while (minutes < 0 || minutes > 59);
294: 
295:    return Time(hours, minutes, 0);
296: }
297: 
298: void Game::play_round()
299: {  
300:    cwin.clear();
301:    Time t = random_time();
302:    const double CLOCK_RADIUS = 5;
303:    Clock clock(Point(0, 0), CLOCK_RADIUS);
304:    clock.set_time(t);
305:    clock.draw();
306: 
307:    Time guess = get_guess();
308:    if (t.seconds_from(guess) != 0)
309:       guess = get_guess();
310: 
311:    string text;
312:    if (t.seconds_from(guess) == 0)
313:    {  
314:       text = "Congratulations, " + player.get_name()
315:          + "! That is correct.";
316:       player.increment_score();
317:    }
318:    else
319:       text = "Sorry, " + player.get_name()
320:          + "! That is not correct.";
321:    cwin << Message(Point(-CLOCK_RADIUS, CLOCK_RADIUS + 1), text);
322: }
323: 
324: int ccc_win_main()
325: {  
326:    Game clock_game;
327:    clock_game.play();
328: 
329:    return 0;
330: }