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: }