source: tests/exceptions/hotpotato_checked.cfa @ d6c59bce

Last change on this file since d6c59bce was 10b5970, checked in by Michael Brooks <mlbrooks@…>, 2 weeks ago

Fix many test-suite- and libcfa-caused unused variable warnings.

In scope are easy fixes among tests whose sole warnings were unused variable. Reduces the wflags lax list by 40%.

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[fd775ae]1#include <fstream.hfa>                                                                  // sin/sout
2#include <stdlib.hfa>                                                                   // convert
3#include <string.h>
4#include <coroutine.hfa>
5
6struct Potato {
[f0c9c9b]7        PRNG & prng;
8        unsigned int deadline;                                                          // when timer goes off
9        unsigned int timer;                                                                     // up counter to deadline
[fd775ae]10}; // Potato
11
12void reset( Potato & potato, unsigned int maxTicks = 10 );
13void ?{}( Potato & potato, PRNG & prng, unsigned int maxTicks = 10 );
14
15void ?{}( Potato & potato, PRNG & prng, unsigned int maxTicks ) with(potato) {
16        &potato.prng = &prng;
17        reset( potato, maxTicks );
[f0c9c9b]18                } // Potato
[fd775ae]19
20coroutine Player {
[f0c9c9b]21        PRNG & prng;
22        int id;                                                                                         // player identity
23        Potato & potato;                                                                        // potato being tossed
24        Player * partner[2];                                                            // left and right player
[fd775ae]25}; // Player
26
27void ?{}( Player & player, PRNG & prng, unsigned int id, Potato & potato ) {
28        &player.prng = &prng;
29        player.id = id;
30        &player.potato = &potato;
[f0c9c9b]31                } // Player
[fd775ae]32
33Player & umpire;
34
35ExceptionDecl( Explode );
36ExceptionDecl( Terminate, Player * victim; );
[26be854]37ExceptionDecl( Election );
[fd775ae]38ExceptionDecl( cmd_error ); // convert(...) throws out_of_range or invalid_argument
39
40void reset( Potato & potato, unsigned int maxTicks ) with(potato) {
[f0c9c9b]41        if ( maxTicks < 2 ) abort( "Hot Potato initialized with less than 2 ticks" ); // optional
[fd775ae]42        deadline = prng( prng, 1, maxTicks );
43        timer = 0;
44        sout | "  POTATO goes off after " | deadline | " tick" | nosep | (deadline > 1 ? "s" : "");
45} // reset
46
47void countdown( Potato & potato ) with(potato) {
48        timer += 1;
[26be854]49        if ( timer == deadline ) throwResume ExceptionInst( Explode );
[fd775ae]50} // countdown
51
52static unsigned int rightOf( unsigned int me, unsigned int total ) {
53        return ( me + 1 ) % total;
54} // rightOf
55
56static unsigned int leftOf( unsigned int me, unsigned int total ) {
57        return ( me + total - 1) % total;
58} // leftOf
59
60enum { LEFT = 0, RIGHT = 1 };
61
62static void vote( Player & player ) {                                   // cause partner to vote
63        resume( player ); checked_poll();
64} // vote
65
66static void terminate( Player & player ) {                              // resume umpire
67        resume( player );
[f0c9c9b]68        checked_poll();
69        sout | "THIS SHOULD NOT BE REACHED";
[fd775ae]70} // terminate
71
72void init( Player & player, Player & lp, Player & rp ) with(player) { // supply partners
73        partner[LEFT] = &lp;
74        partner[RIGHT] = &rp;
75        resume( player );                                                                       // establish main as starter for termination
[f0c9c9b]76        checked_poll();
[fd775ae]77} // init
78
79int getId( Player & player ) {                                                  // player id
80        return player.id;
81} // getId
82
83void toss( Player & player ) {                                                  // tossed the potato
[f0c9c9b]84        resume( player );
[fd775ae]85        checked_poll();
86} // toss
87
88void main( Player & player ) with(player) {
89        try {
[f0c9c9b]90                enable_ehm();                                                                   // allow delivery of nonlocal exceptions
91                suspend;                                                                                // return immediately after establishing starter
92                checked_poll();
93
94                for ( ;; ) {
95                        checked_poll();
96                        if ( partner[LEFT] == &player ) {                       // stop when only one player
97                                sout | id | " wins the Match!";
98                                return;
99                        } // exit
100
101                        countdown( potato );                                            // player is eliminated if countdown() returned true
102
103                        size_t side = prng( prng, 2 );
104                        sout | id | " -> " | nonl;
105                        toss( *partner[ side ] );                                       // random toss left/right
106                } // for
107                disable_ehm();
[fd775ae]108        } catchResume( Terminate * v ) {
109                v->victim->partner[LEFT]->partner[RIGHT] = v->victim->partner[RIGHT]; // unlink node
110                v->victim->partner[RIGHT]->partner[LEFT] = v->victim->partner[LEFT];
[f0c9c9b]111                delete( v->victim );
[fd775ae]112                reset( potato );
113                sout | "U " | nonl;                                                             // start new game
114                flush( sout );
115        } catchResume( Election * election ) {
116                sout | "election";
117                sout | " -> " | id | nonl;
[f0c9c9b]118                if ( id > getId( umpire ) ) &umpire = &player;  // set umpire to highest id so far
119                resumeAt( *partner[RIGHT], *election );
120                disable_ehm();                                                                  // disable ehm since we can't handle execption thrown in vote here and want to poll later
[fd775ae]121                vote( *partner[RIGHT] );
[f0c9c9b]122                enable_ehm();                                                                   // enable after vote
[26be854]123        } catchResume( Explode * ) {
[f0c9c9b]124                sout | id | " is eliminated";
125                if ( &player == &umpire ) {
126                        try {
127                                id = -1;                                                                // remove from election
128                                resumeAt( *partner[RIGHT], ExceptionInst( Election ) );
129                                vote( *partner[RIGHT] );                                // start election
130                                checked_poll();
131                        } catchResume( Election * election ) {
132                                sout | " : umpire " | getId( umpire );
133                        } // try
134                } // if
135                resumeAt( umpire, ExceptionInst( Terminate, &player ) );
136                terminate( umpire );
137                assert( false );                                                                // no return
138        } // try
[fd775ae]139} // main
140
141
142int main( int argc, char * argv[] ) {
143        enum {
144                MinNoPlayers = 2,                                                               // minimum players in the game
145                MaxNoPlayers = 10,                                                              // maximum players in the game
146                DefaultGames = 5,                                                               // default games to play
147        };
148        intmax_t numGames = DefaultGames;                                       // games to play
149        intmax_t numPlayers = 0;                                                        // players for a particular game
150        intmax_t seed = 42;                                                                     // random-number seed
151        bool playersSet = false;
152
153        try {
154                choose ( argc ) {
155                  case 4:
156                        if ( strcmp( argv[3], "d" ) != 0 ) {            // default ?
157                                seed = convert( argv[3] ); if ( seed < 1 ) throw ExceptionInst( cmd_error ); // invalid ?
158                        } // if
159                        fallthrough;
160                  case 3:
161                        if ( strcmp( argv[2], "d" ) != 0 ) {            // default ?
162                                numPlayers = convert( argv[2] ); if ( numPlayers < 2 ) throw ExceptionInst( cmd_error ); // invalid ?
163                                playersSet = true;
164                        } // if
165                        fallthrough;
166                  case 2:
167                        if ( strcmp( argv[1], "d" ) != 0 ) {            // default ?
168                                numGames = convert( argv[1] ); if ( numGames < 0 ) throw ExceptionInst( cmd_error ); // invalid ?
169                        } // if
170                        fallthrough;
171                  case 1: ;                                                                             // defaults
172                  default:                                                                              // too many arguments
[f0c9c9b]173                          throw ExceptionInst( cmd_error );
[fd775ae]174                } // choose
175        } catch( exception_t * ) {                                                      // catch any
176                exit | "Usage: " | argv[0]
[f0c9c9b]177                        | " [ games (>=0) | 'd' (default " | DefaultGames
178                        | ") [ players (>=2) | 'd' (random " | MinNoPlayers | "-" | MaxNoPlayers
179                        | ") [ seed (>0) | 'd' (random) ] ] ]";
[fd775ae]180        } // try
181        sout | numGames | numPlayers | seed;
182
183        PRNG mprng, hprng, pprng;
184        if ( seed != 0 ) {                                                                      // specified on command line ?
185                set_seed( mprng, seed );  set_seed( hprng, seed );  set_seed( pprng, seed );
186        } // if
187
188        for ( game; 1 ~= numGames ) {
189                if ( ! playersSet ) numPlayers = prng( mprng, MinNoPlayers, MaxNoPlayers );
190                sout | numPlayers | " players in the game";
191                {
192                        Potato potato{ hprng };                                         // hot potato to be tossed
193                        Player * players[numPlayers];
194
195                        for ( unsigned int i = 0; i < (unsigned int)numPlayers; i += 1 ) { // start the players
196                                players[i] = malloc();
197                                ?{}( *players[i], pprng, i, potato );
198                        } // for
199               
200                        // Do not swap player[0] with itself.
201                        unsigned int rposn = prng( mprng, 1, numPlayers - 1 ); // swap random position with 0
202                        swap( players[0], players[rposn] );
203
204                        // Tell each player its partner.
205                        for ( unsigned int i = 0; i < (unsigned int)numPlayers; i += 1 ) {
206                                init( *players[i], *players[leftOf(i, numPlayers)], *players[rightOf(i, numPlayers)] );
207                        } // for
208
209                        &umpire = players[rposn];                                       // designate umpire and start game
210                        sout | "U " | nonl;
211                        toss( *players[rposn] );
212                        delete( &umpire );
213                }
214                if ( game < (unsigned int)numGames ) sout | nl | nl; // whitespace between games
215        } // for
216} // main
217
218// Local Variables: //
219// compile-command: "make hotpotato" //
220// End: //
Note: See TracBrowser for help on using the repository browser.