parciales/2021-1C-2p/main.cpp (8586B)
1 #include <iostream> 2 #include <sstream> 3 #include <cctype> 4 5 #define CHANNELS_MAX 140 6 7 class Channel { 8 private: 9 Channel* next; 10 Channel* prev; 11 unsigned int index; 12 unsigned int volume; 13 unsigned int maxVolume; 14 bool mute; 15 16 public: 17 /** 18 * post: initializes the Channel 19 */ 20 Channel() { 21 next = prev = NULL; 22 index = 0; 23 maxVolume = volume = 50; // initialize channel volume at 50% 24 mute = false; 25 } 26 27 /** 28 * post: clears memory calling next destructor 29 */ 30 virtual ~Channel() { 31 delete this->next; 32 } 33 34 /** 35 * pre: the Channel must be initialized 36 * post: sets the Channel index to `index` 37 */ 38 void setChannelIndex(unsigned int index) { 39 this->index = index; 40 } 41 42 /** 43 * pre: the Channel must be initialized 44 * post: toggles the mute bool variable 45 */ 46 void toggleMute() { 47 this->mute = !this->mute; 48 } 49 50 /** 51 * pre: the Channel must be initialized 52 * post: sets the Channel mute to `true` 53 */ 54 void setMute() { 55 this->mute = true; 56 } 57 58 /** 59 * pre: the Channel must be initialized 60 * post: sets the Channel mute to `false` 61 */ 62 void unsetMute() { 63 this->mute = false; 64 } 65 66 /** 67 * pre: the Channel must be initialized 68 * post: returns the `mute` variable status 69 */ 70 bool getMute() { 71 return this->mute; 72 } 73 74 /** 75 * pre: the Channel must be initialized 76 * post: returns the `index` variable status 77 */ 78 unsigned int getIndex() { 79 return this->index; 80 } 81 82 /** 83 * pre: the Channel must be initialized 84 * post: returns the `volume` variable status 85 */ 86 unsigned int getVolume() { 87 return this->volume; 88 } 89 90 /** 91 * pre: the Channel must be initialized 92 * post: sets the Channel volume to `volume` 93 */ 94 void setVolume(int volume) { 95 if(volume > 100) { 96 this->volume = 100; 97 maxVolume = 100; 98 } 99 else if(volume < 0) { 100 this->volume = 0; 101 } else { 102 this->volume = volume; 103 if(volume > (int)this->maxVolume) { 104 maxVolume = volume; 105 } 106 } 107 } 108 109 /** 110 * pre: the Channel must be initialized 111 * post: returns the Channel `maxVolume` 112 */ 113 unsigned int getMaxVolume() { 114 return this->maxVolume; 115 } 116 117 /** 118 * pre: the Channel must be initialized 119 * post: sets the Channel `next` to `next` 120 */ 121 void setNextChannel(Channel *next) { 122 this->next = next; 123 } 124 125 /** 126 * pre: the Channel must be initialized 127 * post: sets the Channel `prev` to `prev` 128 */ 129 void setPrevChannel(Channel *prev) { 130 this->prev = prev; 131 } 132 133 /** 134 * pre: the Channel must be initialized 135 * post: retuns a pointer to the previous Channel 136 */ 137 Channel *getPrev() { 138 return this->prev; 139 } 140 141 /** 142 * pre: the Channel must be initialized 143 * post: retuns a pointer to the next Channel 144 */ 145 Channel *getNext() { 146 return this->next; 147 } 148 }; 149 150 class Television { 151 private: 152 Channel *channelList; 153 Channel *currentChannel; 154 155 public: 156 /** 157 * post: initializes `Television` and all the Channels in `channelList` 158 */ 159 Television() { 160 channelList = new Channel; 161 currentChannel = channelList; 162 channelList->setChannelIndex(0); 163 164 Channel *prev = NULL; 165 Channel *next = new Channel; 166 next->setPrevChannel(channelList); 167 next->setNextChannel(NULL); 168 next->setChannelIndex(1); 169 170 channelList->setPrevChannel(prev); 171 channelList->setNextChannel(next); 172 173 for(unsigned int i = 2; i < CHANNELS_MAX; ++i) { 174 prev = next; 175 next = new Channel; 176 prev->setNextChannel(next); 177 next->setPrevChannel(prev); 178 next->setNextChannel(NULL); 179 next->setChannelIndex(i); 180 } 181 } 182 183 /** 184 * pre: `Television` must be initialized 185 * post: calls the first `channelList` destructor 186 */ 187 virtual ~Television() { 188 delete this->channelList; 189 } 190 191 /** 192 * pre: `Television` must be initialized 193 * post: returns the `currentChannel` 194 */ 195 Channel *getCurrentChannel() { 196 return this->currentChannel; 197 } 198 199 /** 200 * pre: `Television` must be initialized 201 * post: sets the `currentChannel` to the next channel if is not the last 202 */ 203 void nextChannel() { 204 if(currentChannel->getNext() != NULL) { 205 currentChannel = currentChannel->getNext(); 206 } 207 } 208 209 /** 210 * pre: `Television` must be initialized 211 * post: sets the `currentChannel` to the previous channel if is not the first 212 */ 213 void prevChannel() { 214 if(currentChannel->getPrev() != NULL) { 215 currentChannel = currentChannel->getPrev(); 216 } 217 } 218 219 /** 220 * pre: `Television` must be initialized 221 * post: sets the `currentChannel` to the channel with index `channelIndex` 222 */ 223 void setChannel(int channelIndex) { 224 if(channelIndex > CHANNELS_MAX) { 225 channelIndex = CHANNELS_MAX; 226 } else if(channelIndex < 0) { 227 channelIndex = 0; 228 } 229 230 if(channelIndex < (int)currentChannel->getIndex()) { 231 while(currentChannel->getPrev() != NULL) { 232 if((int)currentChannel->getIndex() == channelIndex) { 233 break; 234 } 235 currentChannel = currentChannel->getPrev(); 236 } 237 } else if(channelIndex >= (int)currentChannel->getIndex()) { 238 while(currentChannel->getNext() != NULL) { 239 if((int)currentChannel->getIndex() == channelIndex) { 240 break; 241 } 242 currentChannel = currentChannel->getNext(); 243 } 244 } 245 } 246 247 248 /** 249 * pre: `Television` must be initialized 250 * post: mutes the `currentChannel` 251 */ 252 void muteChannel() { 253 currentChannel->setMute(); 254 } 255 256 /** 257 * pre: `Television` must be initialized 258 * post: unmutes the `currentChannel` 259 */ 260 void unmuteChannel() { 261 currentChannel->unsetMute(); 262 } 263 264 /** 265 * pre: `Television` must be initialized 266 * post: toggles the mute for the `currentChannel` 267 */ 268 void toggleMuteChannel() { 269 currentChannel->toggleMute(); 270 } 271 272 /** 273 * pre: `Television` must be initialized 274 * post: raises the volume of the `currentChannel` 275 */ 276 void raiseVolume() { 277 currentChannel->setVolume(currentChannel->getVolume() + 10); 278 } 279 280 /** 281 * pre: `Television` must be initialized 282 * post: lowers the volume of the `currentChannel` 283 */ 284 void lowerVolume() { 285 currentChannel->setVolume(currentChannel->getVolume() - 10); 286 } 287 288 /** 289 * pre: `Television` must be initialized 290 * post: sets the volume of the `currentChannel` to `volume` 291 */ 292 void setVolume(unsigned int volume) { 293 currentChannel->setVolume(volume); 294 } 295 296 /** 297 * pre: `Television` must be initialized 298 * post: prints the main atributes of `Television` to `stdout` 299 */ 300 void printStatus() { 301 std::cout << "channel: " << this->currentChannel->getIndex()+1<< std::endl; 302 std::cout << "volume: " << this->currentChannel->getVolume() << "%\n"; 303 std::cout << "mute: " 304 << (this->currentChannel->getMute() ? "true" : "false") << std::endl; 305 } 306 }; 307 308 void printHelp() { 309 std::cout 310 << "television simulator\n" 311 << "list of valid keys:\n" 312 << " `+`: raise volume\n" 313 << " `-`: lower volume\n" 314 << " `m`: toggle mute\n" 315 << " `n`: next channel\n" 316 << " `c`: change to channel by index\n" 317 << " `p`: previous channel\n" 318 << " `q`: close\n\n"; 319 } 320 321 int main () { 322 Television *tv = new Television; 323 bool shouldClose = false; 324 char key; 325 326 tv->printStatus(); 327 std::cout << "press `h` for a list of valid keys\n"; 328 while(!shouldClose) { 329 std::cout << "tv> "; 330 std::cin.get(key); 331 332 if(std::cin.eof()) { 333 shouldClose = true; 334 } 335 336 if(key == '\n') { 337 continue; 338 } 339 340 switch(key) { 341 case '+': 342 std::cin.ignore(1); 343 tv->raiseVolume(); 344 tv->printStatus(); 345 break; 346 case '-': 347 std::cin.ignore(1); 348 tv->lowerVolume(); 349 tv->printStatus(); 350 break; 351 case 'm': 352 std::cin.ignore(1); 353 tv->toggleMuteChannel(); 354 tv->printStatus(); 355 break; 356 case 'n': 357 std::cin.ignore(1); 358 tv->nextChannel(); 359 tv->printStatus(); 360 break; 361 case 'p': 362 std::cin.ignore(1); 363 tv->prevChannel(); 364 tv->printStatus(); 365 break; 366 case 'c': { 367 std::cin.ignore(1); 368 std::string channelIndexStr; 369 int newIndex; 370 std::cout << "go to channel> "; 371 do { 372 std::cin.get(key); 373 if(isdigit(key)) { 374 channelIndexStr += key; 375 } 376 } while(key != '\n'); 377 std::istringstream(channelIndexStr) >> newIndex; 378 try { 379 tv->setChannel(newIndex-1); 380 } catch (const char *error) { 381 std::cout << error << std::endl; 382 } 383 tv->printStatus(); 384 break; 385 } 386 case 'v': { 387 std::cin.ignore(1); 388 std::string newVolumeStr; 389 int newVolume; 390 std::cout << "volume> "; 391 do { 392 std::cin.get(key); 393 if(isdigit(key)) { 394 newVolumeStr += key; 395 } 396 } while(key != '\n'); 397 std::istringstream(newVolumeStr) >> newVolume; 398 try { 399 tv->setVolume(newVolume); 400 } catch (const char *error) { 401 std::cout << error << std::endl; 402 } 403 tv->printStatus(); 404 break; 405 } 406 case 'q': 407 shouldClose = true; 408 break; 409 case 'h': 410 std::cin.ignore(1); 411 printHelp(); 412 tv->printStatus(); 413 break; 414 case 10: 415 default: 416 std::cin.ignore(1); 417 break; 418 } 419 } 420 421 delete tv; 422 return 0; 423 }
