home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 444_01 / chsclk13 / chessclk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-24  |  9.3 KB  |  370 lines

  1. /****************************** Chess clock program ************************
  2.       FULL-FEATURED CHESS CLOCK
  3.       Large digital displays of clocks
  4.                Move counter
  5.                White and Black clocks separately settable
  6.                Times from 1 minute to 99 hours
  7.                Low-time warning (optional)
  8.                Flashing "tick" indicator (optional)
  9.       Flag for active player's clock
  10.       Audible player changeover indicator
  11.       Pause control
  12. ****************************************************************************/
  13. // M\Cooper, 3425 Chessnut Ridge Rd., Grantsville, MD 21536-9801
  14.  
  15.  
  16. #include <stdio.h>
  17. #include <time.h>
  18. #include <conio.h>
  19. #include <stdlib.h>
  20. #include <graphics.h>
  21. #include <dos.h>
  22. #include "oscr.hpp"
  23. #include "chessclk.hpp"
  24.  
  25. #define XXPOS 60
  26. #define YYPOS 37
  27. // Base coordinates for time display
  28.  
  29. #define PX   197
  30. #define PY   130
  31. // Coordinates for "pause" message
  32.  
  33. #define XWIDTH 580
  34. #define YHEIGHT 25
  35. #define XXMARGIN 50
  36. #define LXMARGIN 26
  37. // *Whose_clock_is_running* flag coordinates
  38.  
  39. #define DEFAULT_TIME 2
  40. #define DEFAULT_TEST() if( hrs==0 && min == 0 ) hrs = DEFAULT_TIME
  41.  
  42. void main()
  43. {
  44.    randomize();
  45.    opening_screen();
  46.    play();
  47. }
  48.  
  49. void CountdownTimer::clock_on()
  50. {
  51.    time_t prev_sec;
  52.    int ch;
  53.  
  54.    pause_t = 0;
  55.  
  56.       if( p == WHITE_ )
  57.      text_color = LIGHTBLUE;
  58.       else
  59.      text_color = DARKGRAY;
  60.  
  61.       setcolor( text_color );
  62.       settextstyle( TRIPLEX_FONT, HORIZ_DIR, 5 );
  63.       settextjustify( LEFT_TEXT, TOP_TEXT );
  64.  
  65.      ShowFlag();
  66.  
  67.       startn_t = time ( NULL );  //Click on stopwatch.
  68.       gotoxy( XXPOS * p + 1, YYPOS );
  69.       outtextxy( NAME_POS * p, 100, player [p] );
  70.       display_time();  //Otherwise initial time not displayed...
  71.  
  72.       while( !( ch = kbhit() ) )
  73.      {
  74.      prev_sec = seconds;
  75.      if( running_flag) //Is this 2nd or later lap?
  76.         interval_t = time( NULL ) - startn_t;
  77.      else
  78.         interval_t = time( NULL ) - start_t;
  79.  
  80. /**********************XXXXX**********PAUSE-TIME**********************/
  81.  
  82.      running_t = total_seconds - interval_t - pause_t;  // Minus PauseTime(s)
  83. //                                         ^^^^^^^
  84. //            
  85.      convert( running_t );
  86.  
  87.      if( seconds - prev_sec )
  88.         {
  89.         display_time();
  90.  
  91.         if( !seconds )
  92.            if( minutes == warning )
  93.           if( !hours )
  94.              if( time_warning_flag )
  95.             blatt();
  96.  
  97.         if( visual_ticking_flag ) // Show blinking box ticks?
  98.            {
  99.            setfillstyle( random ( PATTERNS ), random ( COLORS ) );
  100.            setcolor ( random ( COLORS ) );
  101.            setlinestyle( SOLID_LINE, 0xFFF, NORM_WIDTH );
  102.            bar( X_C - RADIUS, Y_C - RADIUS,
  103.             X_C + RADIUS, Y_C + RADIUS );
  104.            }
  105.         }
  106.  
  107.      if( timeout() )
  108.         exit_();
  109.      }
  110.  
  111.       total_seconds = hours * 3600 + minutes * 60 + seconds;
  112.       running_flag = ON;  // Remember that clock was already running.
  113.  
  114.       
  115.       ch = getch(); //Retrieve keypress.
  116.       if( ch == ESC )
  117.          exit__(); //Quit.
  118.       if( ch == 'p' || ch == 'P' )
  119.          pause();
  120.  
  121.       return;
  122.  
  123. }
  124.  
  125. void CountdownTimer::display_moves()
  126. {
  127.    char buf[ 5 ];
  128.    static char ebuf[ 5 ];
  129.  
  130.       if( moves > 1 )
  131.      {
  132.      setcolor( WHITE );
  133.      settextstyle( TRIPLEX_FONT, HORIZ_DIR, 1 );
  134.      settextjustify( CENTER_TEXT, TOP_TEXT );
  135.      outtextxy( MOVES_X, MOVES_Y, ebuf );
  136.      }
  137.  
  138.       sprintf( buf, "%003d", moves );
  139.       sprintf( ebuf, buf );
  140.       setcolor( LIGHTRED );
  141.       settextstyle( TRIPLEX_FONT, HORIZ_DIR, 1 );
  142.       settextjustify( CENTER_TEXT, TOP_TEXT );
  143.       outtextxy( MOVES_X, MOVES_Y, buf );
  144.       
  145.       return;
  146. }
  147.  
  148. void graphics_setup( int background_color )
  149. {
  150.    int grdriver = VGA,
  151.        grmode = VGAHI;
  152.  
  153.        registerfarbgidriver( EGAVGA_driver_far );
  154.        registerfarbgifont( gothic_font_far );
  155.        registerfarbgifont( triplex_font_far );
  156.        initgraph( &grdriver, &grmode, "" );
  157.        setbkcolor( background_color );
  158.  
  159. // Note: Borland BGI graphics drivers are completely
  160. //       incompatible with Microsloth Wimpdows.
  161. //       ============
  162.  
  163. }
  164.  
  165. void exit__()
  166. {
  167.       closegraph();
  168.       exit( QUIT );
  169. }
  170.  
  171.     /***************Routine to erase old numbers*************/
  172. void CountdownTimer::erase_numbers()
  173. {
  174.       setcolor ( WHITE ); 
  175.  
  176.       if( seconds == 59 )
  177.      outtextxy( p * BLK_TIME, Y_TIMEPOS, line_clear );
  178.       else
  179.      if( seconds == 9 || seconds == 19 || seconds == 29
  180.          || seconds == 39 || seconds == 49 )
  181.         outtextxy( p * BLK_TIME + POS1_OFFSET, Y_TIMEPOS,
  182.                line_clear + 6 );
  183.       else
  184.          outtextxy( p * BLK_TIME + POS_OFFSET, Y_TIMEPOS,
  185.             line_clear + 7 ); 
  186.  
  187.      return;
  188.  
  189. }
  190.  
  191.  
  192. void play()
  193. {
  194.    int hrs,
  195.        min;
  196.    char inputstr[ MAXLEN ],
  197.     inp;
  198.  
  199.       clrscr();
  200.  
  201.       textcolor ( LIGHTCYAN );
  202.       cprintf( "\n                              WHITE hours: " );
  203.       gets( inputstr );
  204.       hrs = atoi( inputstr );
  205.       cprintf( "                              WHITE minutes: " );
  206.       gets( inputstr );
  207.       min = atoi( inputstr );
  208.       DEFAULT_TEST();
  209.       CountdownTimer t1( hrs, min, WHITE_ );
  210.  
  211.       textcolor( RED );
  212.       cprintf( "\n                              BLACK hours: " );
  213.       gets( inputstr );
  214.       hrs = atoi( inputstr );
  215.       cprintf( "                              BLACK minutes: " );
  216.       gets( inputstr );
  217.       min = atoi( inputstr );
  218.       DEFAULT_TEST();
  219.       CountdownTimer t2( hrs, min, BLACK_ );
  220.  
  221.       textcolor( YELLOW );
  222.       cprintf( "\n\n                         Enable flashing clock ticks? " );
  223.       inp = getche();
  224.       if( inp == 'y' || inp == 'Y' )
  225.      t1.visual_ticking_flag = t2.visual_ticking_flag = ON;
  226.       else
  227.      t1.visual_ticking_flag = t2.visual_ticking_flag = OFF;
  228.  
  229.       cprintf( "\n                                                      Enable time warning? " );
  230.       inp = getche();
  231.       if( inp == 'y' || inp == 'Y' )
  232.      {
  233.      t1.time_warning_flag = t2.time_warning_flag = ON;
  234.      cprintf( "                                                          At how many minutes? " );
  235.      gets( inputstr );
  236.      t1.warning = t2.warning = atoi( inputstr );
  237.      }
  238.       else
  239.      t1.time_warning_flag = t2.time_warning_flag = OFF;
  240.  
  241.       textcolor( GREEN | BLINK );
  242.       _setcursortype( _NOCURSOR );
  243.       printf( "\n\n\n\n\n\n\n\n\n\n\n\n" );
  244.       cprintf( "                             PRESS A KEY TO BEGIN" );
  245.       while ( !getch() );  //Wait for keypress - to begin play.
  246.       beep1();  //BEEP
  247.  
  248.       graphics_setup( WHITE );
  249.  
  250.       t1.initialize_clock();
  251.       t1.moves++;
  252.       t1.display_moves();
  253.       t1.clock_on();
  254.       beep1();
  255.  
  256.       t2.initialize_clock();
  257.       t2.clock_on();
  258.       beep2();
  259.  
  260.       while ( PLAY )
  261.      {
  262.      t1.moves++;  
  263.      t1.display_moves();
  264.      t1.clock_on();
  265.       beep1();
  266.      t2.clock_on(); 
  267.       beep2();
  268.      }
  269.  
  270. } // End play()
  271.  
  272.  
  273. void opening_screen()
  274. {
  275.    char topline[] = "Chess Clock",
  276.     by_line[] = "by",
  277.     name_line[] = "M\\Cooper",
  278.     endline[] = "PRESS A KEY";
  279.  
  280.       graphics_setup( CYAN );
  281.       settextstyle( GOTHIC_FONT, HORIZ_DIR, HEADLINE_SIZE );
  282.       settextjustify( CENTER_TEXT, CENTER_TEXT );
  283.       setcolor( MAGENTA );
  284.       outtextxy( TOPX, TOPY, topline );
  285.  
  286.       settextstyle( TRIPLEX_FONT, HORIZ_DIR, BY_LINE_SIZE );
  287.       setcolor( BLUE );
  288.       outtextxy( BY_LINE_X, BY_LINE_Y, by_line );
  289.  
  290.       setfillstyle( BAR_PATTERN, BAR_COLOR );
  291.       bar3d( BAR_LEFT, BAR_TOP, BAR_RIGHT, BAR_BOTTOM, BAR_DEPTH, BAR_TOPFLAG );
  292.  
  293.       setfillstyle( PIE_PATTERN, PIE_COLOR );
  294.       pieslice( PIE1_X, PIE_Y, PIE_STARTANGLE, PIE_ENDANGLE, PIE_RADIUS );
  295.       pieslice( PIE2_X, PIE_Y, PIE_STARTANGLE, PIE_ENDANGLE, PIE_RADIUS );
  296.       circle( PIE1_X, PIE_Y, CIRC_RAD );
  297.       circle( PIE2_X, PIE_Y, CIRC_RAD );
  298.       line( LINE1_X, LINE_Y1, LINE1_X, LINE_Y2 );
  299.       line( LINE2_X, LINE_Y1, LINE2_X, LINE2_Y2 );
  300.       setfillstyle( PIE_PATTERN, WHITE );
  301.       bar( B1_LEFT, B1_TOP, B1_RIGHT, B_BOTTOM );
  302.       bar( B2_LEFT, B2_TOP, B2_RIGHT, B_BOTTOM );
  303.  
  304.  
  305.       settextstyle( TRIPLEX_FONT, HORIZ_DIR, NAME_LINE_SIZE );
  306.       setcolor( BLUE );
  307.       outtextxy( NAME_LINE_X, NAME_LINE_Y, name_line );
  308.  
  309.       sleep( DELAY );
  310.  
  311.       settextstyle( TRIPLEX_FONT, HORIZ_DIR, ENDLINE_SIZE );
  312.       setcolor( RED );
  313.       outtextxy( ENDLINE_X, ENDLINE_Y, endline );
  314.  
  315.       getch();
  316.       closegraph();
  317.  
  318.       return;
  319. }
  320.  
  321. void CountdownTimer::ShowFlag()
  322. {
  323.      //Show flag over clock in use.
  324.      setfillstyle( INTERLEAVE_FILL, LIGHTRED );
  325.      bar( XXPOS * p + LXMARGIN, YYPOS,
  326.          XXPOS * p + XWIDTH - LXMARGIN, YYPOS + YHEIGHT );
  327.  
  328.      //Erase flag over clock *not* in use.
  329.      setfillstyle( SOLID_FILL, WHITE );
  330.      if( p == WHITE_ ) pp = BLACK_;
  331.      else pp = WHITE_;
  332.      bar( XXPOS * pp + LXMARGIN, YYPOS,
  333.          XXPOS * pp + XWIDTH - LXMARGIN, YYPOS + YHEIGHT );
  334.  
  335.      return;
  336. }
  337.  
  338. void CountdownTimer::pause()
  339. {
  340. //Pause clock when [p] key is pressed.
  341.  
  342.    time_t interim_time = 0;
  343.  
  344.  
  345.       beep2();   beep1();   //Sound for pause.
  346.  
  347.       pause_start_t = time( NULL );
  348.  
  349.       Write_Message( PX, PY, PauseMessage, LIGHTMAGENTA );  //Pause message.
  350.  
  351.       while( !getch() );   //Wait for keypress.
  352.  
  353.       interim_time = time( NULL );
  354.       pause_t = interim_time - pause_start_t;
  355.  
  356.       Write_Message( PX, PY, PauseMessage, WHITE );  //Erase message.
  357.  
  358.       return;
  359.  
  360. }
  361.  
  362. void CountdownTimer::Write_Message( int Px, int Py, char *Pmessage, int Pcolor )
  363. {
  364.       setcolor( Pcolor);
  365.       outtextxy( Px, Py, Pmessage );
  366.  
  367.       return;
  368.  
  369. }
  370.