001: #include <cstdlib>
002: #include <cmath>
003: #include <ctime>
005: using namespace std;
006:
007: #include "ccc_win.h"
008: #include "ccc_time.h"
009:
010: const double PI = 3.141592653589793;
012: /**
013: A clock that can draw its face.
014: */
015: class Clock {
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);
025: /**
026: Sets the current time.
027: @param t the time to set
028: */
029: void set_time(Time t);
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;
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 {
060: public:
061: /**
062: Constructs a player with no name, level 1, and score 0.
063: */
064: Player();
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);
073: /**
074: Increments the score. Moves to next level if current
075: level complete
076: */
077: void increment_score();
079: /**
080: Gets the current level.
081: @return the level
082: */
083: int get_level() const;
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 {
101: public:
102: /**
103: Constructs the game with a default player.
104: */
105: Game();
107: /**
108: Plays the game while the player wants to continue.
109: */
110: void play();
112: /**
113: Reads player name and level.
114: */
115: void read_player_information();
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();
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: { int seed = static_cast<int>(time(0));
143: srand(seed);
144: }
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: { return a + rand() % (b - a + 1); }
156:
157: Clock::Clock(Point c, double r)
158: { center = c;
160: radius = r;
161: }
162:
163: void Clock::set_time(Time t)
164: { current_time = t; }
167:
168: void Clock::draw_tick(double angle, double length) const
169: { 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: { 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: { 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: { 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: { level = 1;
210: score = 0;
211: }
212:
213: Player::Player(string player_name, int initial_level)
214: { name = player_name;
216: level = initial_level;
217: score = 0;
218: }
219:
220: int Player::get_level() const
221: { return level; }
224:
225: string Player::get_name() const
226: { return name; }
229:
230: void Player::increment_score()
231: { score++;
233: if (score % 5 == 0 && level < 4) level++;
235: }
236:
237: Game::Game() {}
240:
241: void Game::play()
242: { rand_seed();
244: read_player_information();
245: string response;
246: do
247: { play_round();
249: response = cwin.get_string("Do you want to play again? (y/n)");
251: }
252: while (response == "y");
253: }
254:
255: void Game::read_player_information()
256: { string name = cwin.get_string("What is your name?");
258: int initial_level;
259: do
260: { initial_level = cwin.get_int("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: { 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: { int hours;
283: do
284: { hours = cwin.get_int("Please enter hours: (1-12)");
286: }
287: while (hours < 1 || hours > 12);
288: int minutes;
289: do
290: { 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: { 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) guess = get_guess();
310:
311: string text;
312: if (t.seconds_from(guess) == 0)
313: { 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: { Game clock_game;
327: clock_game.play();
328: return 0;
330: }