CB100

Notas, resueltos y tps de la materia Algoritmos y Estructuras de Datos
Index Commits Files Refs README
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 }