home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IDIOMS.ZIP / FVIDEO2.C < prev    next >
C/C++ Source or Header  |  1991-12-04  |  5KB  |  215 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. #include <generic.h>
  7. #include <iostream.h>
  8. #include <string.h>
  9. #include "curses.h"
  10.  
  11. struct Scope { Scope *parent; virtual char *ScopeName() = 0; };
  12. #define LocalScope(function)    \
  13. struct name2(function,LocalScope):public Scope {    \
  14.     char *ScopeName() { return "function"; }    \
  15.     name2(function,LocalScope)(Scope *p) { parent = p; } public
  16. #define EndLocalScope } local(this)
  17. #define EndOuterScope } local(0)
  18. #define Parent(type,c) ((name2(type,LocalScope)*)_Parent("type",c))
  19.  
  20. inline Scope *_Parent(const char * type, Scope *c)
  21. {
  22.     register Scope *s = c;
  23.     while(s && strcmp(s->ScopeName(), type)) s = s->parent;
  24.     if (!s) cerr << "couldn't find scope " << type << endl;
  25.     return s;
  26. }
  27.  
  28. void main()
  29. {
  30.     LocalScope(BallGame):
  31.         void DrawSides() {
  32.             for(int i = 0; i < 66; i++) mvaddch(0, i, 'S');
  33.             for(i = 0; i < 13; i++) {
  34.                 mvaddch(i, 0, 'S');
  35.                 mvaddch(i, 65, 'S');
  36.             }
  37.             leftWall = 0;
  38.             rightWall = 65;
  39.         }
  40.  
  41.         struct Ball {
  42.             int yposition, xposition;
  43.             int yspeed, xspeed;
  44.             Ball() {
  45.                 yposition = 6;
  46.                 xposition = 33;
  47.                 yspeed = 1;
  48.                 xspeed = 1;
  49.             }
  50.         } ball;
  51.  
  52.         struct Bat {
  53.             int yposition, position, length, xspeed;
  54.             Bat() { position = 40;
  55.                 yposition = 11;
  56.                 length = 4;
  57.                 xspeed = 0;
  58.             }
  59.         } bat;
  60.  
  61.         void DrawBat() {
  62.             for (int i = bat.position; i < bat.position + bat.length; i++) {
  63.                 mvaddch(bat.yposition, i, 'b');
  64.             }
  65.         }
  66.  
  67.         void EraseBat() {
  68.             for (int i = bat.position; i < bat.position + bat.length; i++) {
  69.                 mvaddch(bat.yposition, i, ' ');
  70.             }
  71.         }
  72.  
  73.         short leftWall, rightWall;
  74.  
  75.         int score;
  76.     
  77.         void DrawWall() {
  78.             for(int i = 0; i < 66; i++) {
  79.                 mvaddch(3, i, 'W');
  80.                 mvaddch(4, i, 'W');
  81.                 mvaddch(5, i, 'W');
  82.             }
  83.         }
  84.  
  85.         char ballIsInPlay() {
  86.             return ball.xposition < rightWall &&
  87.               ball.xposition > leftWall &&
  88.               ball.yposition <= bat.yposition;
  89.         }
  90.  
  91.         void PlayGame() {
  92.             LocalScope(PlayGame):
  93.                 char key;    // from keyboard
  94.  
  95.                 short ballsLeft;
  96.                 void PlayABall() {
  97.                     LocalScope(PlayABall):
  98.                         void CheckBallPosition() {
  99.                             PlayGameLocalScope *p = Parent(PlayGame, this);
  100.                             BallGameLocalScope *p2 = Parent(BallGame, p);
  101.                             int &y = p2->ball.yposition;
  102.                             int &x = p2->ball.xposition;
  103.                             if (x <= p2->leftWall+1 ||
  104.                                 x >= p2->rightWall-1) {
  105.                                 p2->ball.xspeed = -p2->ball.xspeed;
  106.                             }
  107.                             if (y <= 0) {
  108.                                 p2->ball.yspeed = -p2->ball.yspeed;
  109.                             }
  110.                             char c = mvinch(y + p2->ball.yspeed,
  111.                                 x + p2->ball.xspeed);
  112.                             switch (c) {
  113.                             case 'W':
  114.                                 mvaddch(y + p2->ball.yspeed,
  115.                                     x + p2->ball.xspeed,
  116.                                     ' ');
  117.                                 p2->score++;
  118.                             case 'b':
  119.                                 p2->ball.yspeed = -p2->ball.yspeed;
  120.                                 p2->ball.xspeed = p2->bat.xspeed;
  121.                                 break;
  122.                             }
  123.                         }
  124.  
  125.                         void MoveBall() {
  126.                             PlayGameLocalScope *p = Parent(PlayGame, this);
  127.                             BallGameLocalScope *p2 = Parent(BallGame, p);
  128.                             mvaddch(p2->ball.yposition,
  129.                                 p2->ball.xposition, ' ');
  130.                             p2->ball.xposition += p2->ball.xspeed;
  131.                             p2->ball.yposition += p2->ball.yspeed;
  132.                             mvaddch(p2->ball.yposition,
  133.                                 p2->ball.xposition, 'O');
  134.                         }
  135.  
  136.                         void MoveBat(char key) {
  137.                             LocalScope(MoveBat):
  138.                                 void MoveLeft(Bat& bat) {
  139.                                     PlayABallLocalScope *p = Parent(PlayABall, this);
  140.                                     PlayGameLocalScope *p2 = Parent(PlayGame, p);
  141.                                     Parent(BallGame, p2)->EraseBat();
  142.                                     if (bat.position > Parent(BallGame, p2)->leftWall) {
  143.                                         bat.position--;
  144.                                     }
  145.                                     Parent(BallGame, p2)->DrawBat();
  146.                                 }
  147.  
  148.                                 void MoveRight(Bat& bat) {
  149.                                     PlayABallLocalScope *p = Parent(PlayABall, this);
  150.                                     PlayGameLocalScope *p2 = Parent(PlayGame, p);
  151.                                     Parent(BallGame, p2)->EraseBat();
  152.                                     if (bat.position < Parent(BallGame, p2)->rightWall - bat.length) {
  153.                                         bat.position++;
  154.                                     }
  155.                                     Parent(BallGame, p2)->DrawBat();
  156.                                 }
  157.                             EndLocalScope;
  158.  
  159.                             PlayGameLocalScope *p = Parent(PlayGame, this);
  160.                             switch (key) {
  161.                             case 'l':
  162.                                 local.MoveLeft(Parent(BallGame, p)->bat);
  163.                                 Parent(BallGame, p)->bat.xspeed = -1;
  164.                                 break;
  165.                             case 'r':
  166.                                 local.MoveRight(Parent(BallGame, p)->bat);
  167.                                 Parent(BallGame, p)->bat.xspeed = 1;
  168.                                 break;
  169.                             default:
  170.                                 break;
  171.                             }
  172.                         }
  173.                     EndLocalScope;
  174.  
  175.                     while (Parent(BallGame, this)->ballIsInPlay()) {
  176.                         local.CheckBallPosition();    
  177.                         local.MoveBall();
  178.                         refresh();
  179.                         key = getch();
  180.                         local.MoveBat(key);
  181.                     }
  182.                 }
  183.             EndLocalScope;
  184.  
  185.             local.ballsLeft = 4;
  186.             while (local.ballsLeft > 0) {
  187.                 refresh();
  188.                 local.key = getch();
  189.                 local.PlayABall();
  190.                 --local.ballsLeft;
  191.             }
  192.         }
  193.  
  194.     EndOuterScope;
  195.  
  196.     int bestScore = 0;
  197.  
  198.     initscr();
  199.     cbreak();
  200.     noecho();
  201.  
  202.     local.DrawSides();
  203.     local.DrawBat();
  204.  
  205.     for (;;) {
  206.         local.score = 0;
  207.         local.DrawWall();
  208.         local.PlayGame();
  209.         if (local.score > bestScore) {
  210.             bestScore = local.score;
  211.         }
  212.         cout << "best score is " << bestScore << "\n";
  213.     }
  214. }
  215.