// ************************* PROGRAM INFORMATION: ************************** /* ****************************** "ARENA.H" ******************************** This header file contains all of the material needed to set up ARENA.CPP, including text substitutions, global constants, macros, function prototypes, and declarations of global arrays, pointers, and variables. _________________________________________________________________________ */ /* ************************** DEFINE STATEMENTS: *************************** These statements allow you to substitute one program syntax for another. _________________________________________________________________________ */ #define bool int // though Visual C++ 1.52 has no "bool" data // type, this text substitution makes the code // easier to understand. the compiler notices // nothing! const bool true = 1; // sets the constant 'true'. const bool false = 0; // sets the constant 'false'. // This uses a BASIC command to substitute for the Visual C++ 1.52 syntax. #define cls _clearscreen (_GCLEARSCREEN) // This provides simple syntax for testing if a key has been tapped. #define keyboardhit() _bios_keybrd (_KEYBRD_READY) != 0 // NOTE FREQUENCIES: #define c1 262 // middle C #define C 277 // middle C# #define d 294 // D #define D 311 // D# #define E 330 // E #define f1 349 // F #define F 370 // F# #define g 392 // G #define G 415 // G# #define a 440 // A #define A 466 // A# #define b 494 // B #define c2 523 // C, 1 octave above middle C #define E2 659 // the following E #define f2 698 // and F #define F2 740 // F# #define G2 831 // G# #define A2 932 // A# #define b2 988 // B #define P 20000 // this is an inaudible frequency!! (because P is // inaudible, it is used to bring about a "pause" // in the playing of notes during tunes). // NOTE DURATIONS: #define W 2.0 // whole note is 2 seconds. #define H 1.0 // half note is 1 second. #define T .75 // three-quarter note is 3/4 of a second. #define Q .5 // quarter note is half a second. #define e .25 // eighth note is 1/4 of second. #define S .125 // sixteenth note is 1/8 of second. // ASCII CHARACTER VALUES: #define PLYR 1 // small smiley-face. #define DEAD 2 // small smiley-face when hit. #define BUL1 45 // horizontal bullet. #define BUL2 92 // slanting-left bullet. #define BUL3 124 // vertical bullet. #define BUL4 47 // slanting-right bullet. #define MINE 35 // an inactive mine. #define MINEX 37 // an active mine. #define EXPL 88 // the character for explosion. #define LGUN 31 // gun pointing down. #define RGUN 30 // gun pointing up. #define TGUN 17 // gun pointing left. #define BGUN 16 // gun pointing right. #define FENCE 219 // this is a solid box. #define EMPTY 32 // this is a "space" used to erase. // SCAN CODES FOR ARROW KEYS: #define UP 0x48 // up arrow key. #define DOWN 0x50 // down arrow key. #define LEFT 0x4B // left arrow key. #define RIGHT 0x4D // right arrow key. // EDGES OF SCREEN #define TOP_SCREEN_ROW 1 // top row V-coord. #define BOT_SCREEN_ROW 24 // bottom row V-coord. #define LEFTMOST_SCREEN_COL 1 // leftmost column H-coord. #define RIGHTMOST_SCREEN_COL 40 // rightmost column H-coord. // GUN STARTING COORDS: #define TOP_LEFT_V 2 // top left corner V-coord. #define TOP_LEFT_H 2 // top left corner H-coord. #define BOT_RIGHT_V 23 // bottom right corner V-coord. #define BOT_RIGHT_H 39 // bottom right corner H-coord. // PLAYER STARTING COORDS: #define PLYR_START_V 12 // player V-coord. #define PLYR_START_H 20 // player H-coord. // VALUES USED TO ACCESS GUNS: #define TOP_GUN 0 // top gun value. #define BOT_GUN 1 // bottom gun value. #define LEFT_GUN 2 // left gun value. #define RIGHT_GUN 3 // right gun value. // FOR DETERMINING ROUND MINE NUMBER: #define R1_MINE_NUM 7 // round 1 mine amount. #define R5_MINE_NUM 22 // round 5 mine amount. #define R10_MINE_NUM 33 // round 10 mine amount. // FOR ARRAY DECLARATION: #define MAX_MINE_NUM 33 // maximum possible number of mines. // COLORS OF TITLE SCREEN WORDS: #define TOP_COL 2 // color of title screen "ARENA". #define MID_COL 13 // color of title screen "OF". #define BOT_COL 4 // color of title screen "DOOM". // VALUES REFERRING TO TUNES: #define TEST_TUNE 1 // tune played to optimize program. #define TIME_TUNE 2 // tune played to fine-tune program timing. #define TITLE_TUNE 3 // tune played at title screen. #define PLYR_WIN 4 // tune played at moment round is won. #define GOOD_JOB 5 // tune played following won round. #define PLYR_LOSE 6 // tune played following lost round. #define FINAL_TUNE 7 // tune played following winning of game. // VALUES REFERRING TO FACES: #define SMILE 1 // a smiling face. #define FROWN 2 // a frowning face. #define FINAL_FACE 3 // a fast-moving smiling face. // VALUES USED TO SET IMAGES: #define V_LOCK_IN 4 // V-coord plotted relative to. #define H_LOCK_IN 16 // H-coord plotted relative to. // DEFAULT ASSIGNMENT VALUES: #define DUM_INIT 10000 // used in the initialization of certain // 'dummy value' variables. #define GOAL_INIT 500000 // used in the initialization of certain // loop incrementation variables. // INITIALIZATION VALUE: #define INIT_DUM_VAL 10000 // initial value of a variable whose value // is used as a 'dummy value' to // optimize the timing of the loops used // by the program. /* ************************** CLASS DEFINITION: ************************** A class contains variables, just as a struct does. However, classes can also contain functions. Using classes to design programs allows for more safety in programming, for more reuseable code, and for more programming flexibility. _______________________________________________________________________ */ /* ******************************* class Game ****************************** class Game is the class that manages the main gameplay loop of the game. By incrementing variables and making note of when those variables reach certain values, a game of characters moving at their own unique speeds across the screen is made possible. _________________________________________________________________________ */ class Game { public: Game(); void ResetGameCounters(); void IncrementBulTic(); void ResetBulTic(); void IncrementHGunTic(); void ResetHGunTic(); void IncrementExpTic(); void ResetExpTic(); void SetRoundBulGoal (long); void SetRoundHGunGoal (long); void SetRoundExpGoal (long); void SetGameIsOver (bool); bool BulGoalReached(); bool HGunGoalReached(); bool ExpGoalReached(); bool GameIsNotOver(); ~Game(); private: long bul_tic; long Hgun_tic; long exp_tic; long bul_goal; long Hgun_goal; long exp_goal; bool game_is_over; }; /* ****************************** class Screen ***************************** class Screen was created to manage characters and processes physically contained on the game screen. This service includes configuring the video mode, creating and mapping characters, setting up where the bullet will be shot, and planning out the setting off and chain-reactions of mines. _________________________________________________________________________ */ class Screen { public: Screen(); void SetScreenSettings(); void UndoScreenSettings(); void SetTunerColors(); void SetGameColors(); void StoreCharacters(); void PutBox (int, int, int, int); int GetScreenContents (int, int); void ClearField(); void ConstructScreen(); void SetBullet(); int GetNextGunNum(); int GetNextShootPos(); void SetRoundMineNum (int); void IncrementActiveMineAmt(); void IncrTotalMinesGone(); void AdvanceToNextMine(); void SetActiveMine (int, int); void ResetActiveMineAmt(); void ResetCurMineMarker(); void ResetNumMinesGone(); void SetMinesAreActive (bool); int GetCurMineRecV(); int GetCurMineRecH(); int GetCurMineMarker(); int GetCurRingColor (int); bool MinesAreActive(); bool MinesAreNotActive(); bool ActiveMinesRemain(); bool NoMoreActiveMines(); bool MinesRemain(); bool AllMinesGone(); ~Screen(); private: struct ActiveMineRec { int mineV; int mineH; } mine_rec[MAX_MINE_NUM]; int contents[25][41]; char box[256][2]; int *exp_col; int next_gun_num; int next_shoot_pos; int round_mine_num; int num_mines_gone; int active_mine_amt; int cur_mine_marker; bool mines_are_active; }; /* ****************************** class Round ****************************** class Round addresses issues concerning game difficulty levels and of other factors related to the round number of the game. _________________________________________________________________________ */ class Round { public: Round(); void SetRoundVariables (long); void Instructions(); void ChooseDifficulty(); void SetRoundDifficulty(); char DisplayRoundNum(); void IncrementRoundNum(); void SetRoundNum (int); int GetRoundNum(); int GetRoundMineNum(); long GetRoundBulGoal(); long GetRoundHGunGoal(); long GetRoundExpGoal(); ~Round(); private: void SetFactor (int, int, int, float, float, float *); float r1_mine_num; float r1_bul_goal; float r1_Hgun_goal; float r1_exp_goal; float r5_mine_num; float r5_bul_goal; float r5_Hgun_goal; float r5_exp_goal; float r10_mine_num; float r10_bul_goal; float r10_Hgun_goal; float r10_exp_goal; int roundnum; int round_mine_num; long round_bul_goal; long round_Hgun_goal; long round_exp_goal; }; /* ****************************** class Player ***************************** class Player is the class responsible for keeping track of the player's location on the screen. _________________________________________________________________________ */ class Player { public: Player(); void SetPlayerV (int); void SetPlayerH (int); int GetPlayerV(); int GetPlayerH(); ~Player(); private: int plyrV; int plyrH; }; /* ****************************** class Bullet ***************************** class Bullet comes into action after class Screen determines that the time has come for the game bullet to be brought out. class Bullet tasks include determining the direction the bullet is to travel, and of making the bullet 'spin' as it travels across the screen. _________________________________________________________________________ */ class Bullet { public: Bullet(); int SpinBullet(); void SetBulletV (int); void SetBulletH (int); void SetIncrV (int); void SetIncrH (int); void SetFrame (int); void SetBulletIsOut (bool); int GetBulletV(); int GetBulletH(); int GetIncrV(); int GetIncrH(); bool BulletIsOut(); bool BulletIsNotOut(); ~Bullet(); private: int Spin(); int bulV; int bulH; int incrV; int incrH; int frame; bool bullet_is_out; }; /* ******************************* class Gun ******************************* class Gun is the abstract base class from which the 4 game gun classes are derived. This act of inheritance, first of all, promotes efficiency in the sense that if a derived class has need of a member defined in its base class, that member need not be redefined in the derived class. If a derived class implements a base class function in a way that applies to the derived class in a special way, however, the base class function can be redefined in the derived class. It is by means of this redefinition that makes the process of polymorphism possible. When the base class function is called, the derived class appropriate to the situation is chosen. Accessing the derived class functions through the base class function promotes efficiency, allowing the derived class functions to be handled in a generic manner. Take note that the destructor of class Gun is declared as "virtual". The purpose of a virtual destructor is to ensure that the correct derived class destructor is called when the delete operator is applied to a base class pointer. _________________________________________________________________________ */ class Gun { public: Gun(); virtual void MoveGun() = 0; virtual void ResetGun() = 0; void SetGunV (float); void SetGunH (float); float GetGunV(); float GetGunH(); virtual ~Gun(); protected: float gunV; float gunH; }; /* ****************************** class TopGun ***************************** This class derived from class Gun manages the game gun that moves along the top of the screen. _________________________________________________________________________ */ class TopGun : public Gun { public: TopGun(); virtual void MoveGun(); virtual void ResetGun(); ~TopGun(); }; /* ****************************** class BotGun ***************************** This class derived from class Gun manages the game gun that moves along the bottom of the screen. _________________________________________________________________________ */ class BotGun : public Gun { public: BotGun(); virtual void MoveGun(); virtual void ResetGun(); ~BotGun(); }; /* ***************************** class LeftGun ***************************** This class derived from class Gun manages the game gun that moves along the left side of the screen. _________________________________________________________________________ */ class LeftGun : public Gun { public: LeftGun(); virtual void MoveGun(); virtual void ResetGun(); ~LeftGun(); }; /* **************************** class RightGun ***************************** This class derived from class Gun manages the game gun that moves along the right side of the screen. _________________________________________________________________________ */ class RightGun : public Gun { public: RightGun(); virtual void MoveGun(); virtual void ResetGun(); ~RightGun(); }; /* **************************** class Explosion **************************** class Explosion carries out the explosion of the current mine when class Screen determines it is time for that mine to explode. class Explosion tasks include keeping track of the current 'ring' of an explosion, and of calculating the coordinates on the screen of the corners of explosions. _________________________________________________________________________ */ class Explosion { public: Explosion(); void AdvanceToNextRing(); void SetRingGoal(); void ResetCurRing(); void SetRingTLv (int); void SetRingTLh (int); void SetRingBRv (int); void SetRingBRh (int); int GetCurRing(); int GetRingTLv(); int GetRingTLh(); int GetRingBRv(); int GetRingBRh(); bool RingNotGreaterThanGoal(); bool FinalRingReached(); bool BoxIsWithinScreen (int, int); ~Explosion(); private: int RandRing(); int cur_ring; int ring_goal; int ringTLv; int ringTLh; int ringBRv; int ringBRh; }; /* ***************************** class TuneMaker *************************** class TuneMaker is the class designed to create and present all sound and music within the game. Part of class TuneMaker's job is to fine-tune note duration. class TuneMaker has its own method of producing music based upon making use of the designated duration and pitch of notes. _________________________________________________________________________ */ /* ****************************** struct Tune ****************************** struct Tune is the data type used by class TuneMaker to create and play tunes. An 'operator' function is designed specifically for struct Tune to allow the program to reclaim the memory taken up by the tunes stored. _________________________________________________________________________ */ struct Tune { int freq; long wait; struct Tune *next; void operator delete (void *); }; class TuneMaker { public: TuneMaker(); void StoreTestTune(); void SetTimingTune(); void StoreTunes(); void SetSoundDumVal (long); void SetSoundDelay (long); void TitleScreenTune(); void SetTune (int); void PlayCurNote(); void AdvanceToNextNote(); void PlayTune (int); void SetWaiting (bool); long GetCurWait(); void Beep (int); bool Waiting(); bool NotWaiting(); bool NullNotReached(); bool NullReached(); ~TuneMaker(); private: void SetupTune (Tune **, Tune **, int[], double[], bool); long sound_delay; long sound_dum_val; Tune *title_tune; Tune *test_tune; Tune *time_tune; Tune *win; Tune *good_job; Tune *lose; Tune *final; Tune *tune; bool waiting; }; /* ***************************** class ImageMaker ************************** class ImageMaker is designed to handle the construction and display of bit-mapped images. Among such images are the words portraying the title of the game on the title screen and the image of the player presented in between rounds. class ImageMaker's bringing about, furthermore, is given further meaning as it takes on the task of managing and handling active animation. This animation makes itself known in the motion of the bit-mapped player, mentioned above, that is presented in between rounds. _________________________________________________________________________ */ /* ****************************** struct Image ***************************** struct Image is the data type used by class ImageMaker to create and display images. An 'operator' function is designed specifically for struct Image to allow the program to reclaim the memory taken up by the images stored. _________________________________________________________________________ */ struct Image { int coordV; int coordH; int box_col; struct Image *next; void operator delete (void *); }; class ImageMaker { public: ImageMaker(); void MakeFaces(); void SetSoundDelay (long); void StoreTunes(); void SetFaceDelay (long); void SetAnimationDelays (long); void TitleScreenImage(); void DrawARENA(); void DrawOF(); void DrawDOOM(); void DrawTitleBorder(); void SetupAnimation (int); void AnimateFace (int, int); int MoveFaceForward (int); void PlaceImage (int, int, int, int); void EraseImage (int, int, int, int); long GetDelayGoal(); ~ImageMaker(); private: void SetupImage (Image **, Image **, int[], int[], int, bool, int, int); void SetFace (int); void SetFacePath (int); void SetDelayGoal (int); void DrawImage (Image *); TuneMaker tune_mak; long sound_delay; long face_delay; int *pathV; int *pathH; long delay_goal; long win_delay; long lose_delay; long final_delay; long pause_goal; Image *title_ARENA; Image *title_OF; Image *title_DOOM; Image *smile; Image *frown; Image *erase_face; Image *face; }; /* **************************** class ArenaOfDoom ************************** class ArenaOfDoom is the piecing together of all of the classes presented up until now, into a single, functioning program. class ArenaOfDoom contains as its data members objects of all of the classes listed above. All of these member objects interact within class ArenaOfDoom, and by means of that interaction create the processes of the game. _________________________________________________________________________ */ class ArenaOfDoom { public: ArenaOfDoom(); void MainCodeBlock (long, long, long, long); void MainLoop(); void ResetVars(); void ScanTap (char); void ScanBullet(); void MoveGuns(); void MoveTopGun(); void MoveBotGun(); void MoveLeftGun(); void MoveRightGun(); void ManageMines(); void InitRingVars(); bool ScanRing(); int ScanBlock (int, int); void EraseRing(); void ScanErase (int, int); void RoundWon(); void SetupNextRound(); void RoundLost(); void RoundLostPrompt(); void GameWon(); ~ArenaOfDoom(); protected: Game game; Screen screen; Round round; Player plyr; Bullet bullet; Gun *gun[4]; Explosion expl; TuneMaker tune_mak; ImageMaker img_mak; bool is_test; }; /* **************************** class TimingTuner ************************** class TimingTuner's purpose is to optimize the timing of the program so that it runs at the appropriate speed when executed. class TimingTuner, being a class derived from class ArenaOfDoom, contains all of the functions and data members that class ArenaOfDoom does. This act of inheritance makes possible the simulation of the game environment. In the definition of class TimingTuner below, new member functions and data members are introduced. _________________________________________________________________________ */ class TimingTuner : public ArenaOfDoom { public: TimingTuner(); void MainCodeBlock(); double TrialTestLoop(); double PerformTimingTest(); long OptimizeMainDelay(); long OptimizeSoundDelay(); long OptimizeFaceDelay(); long GetMainDelayValue(); long GetSoundDelayValue(); long GetFaceDelayValue(); long GetFaceSoundDelayValue(); ~TimingTuner(); private: double game_speed_ratio; long main_delay; long sound_delay; long face_delay; long face_sound_delay; long test_dum_val; long main_dum_val; long sound_dum_val; long face_dum_val; }; /* ************************ GLOBAL FUNCTION PROTOTYPES: ******************** These statements prepare functions for what they will receive and return. These functions, however, are not contained within any class, and can be accessed from anywhere in the program. _________________________________________________________________________ */ int readchar(); void flushbuf(); void drawbox (int, int, int); void drawborder (int, int, int, int, int); void settext (int, int, int, char *); /* *************************** GLOBAL VARIABLES: *************************** Normal variables are "passed" to and from functions. Sometimes, however, manipulating certain variables in this manner can become too awkward. Declaring such variables as "global" allows these variables to bypass these limitations, yet still be used effectively. _________________________________________________________________________ */ // These variables are used to give color to characters placed // using Screen::PutBox(), as well as other color-related functions. int BLACK; int DBLUE; int GREEN; int LPINK; int DRED; int DPINK; int BROWN; int LGRAY; int DGRAY; int BLUE; int LGREEN; int WHITE; int LRED; int LBLUE; int YELLOW; int BWHITE; float V_GUN_INCR = 22.0f / 38.0f; // This gives the float-value for a // vertically moving gun to increment, int H_GUN_INCR = (int)(38.0f / 38.0f); // for every whole-box increment // (seen here) of the horizontally // moving gun. // GLOBAL ARRAYS OF GAME VALUES TO BE ACTED UPON: int box_list[15] = {1, 2, 45, 92, 124, 47, 35, // these are the only 37, 88, 31, 30, 17, 16, 219, 32}; // ASCII characters // used in the game. char square[2]; // used to perform global drawbox() function. int exp_col_game[5] = {0, 14, 10, 4, 5}; // explosion-ring color for // normal game-play. int exp_col_test[5] = {0, 0, 0, 0, 0}; // explosion-ring color for // main-gameplay-loop optimization. // GLOBAL ARRAYS OF COORDINATES TO BE PLOTTED: int A_coordV[9] = {1, 2, 3, 0, 2, 1, 2, 3, -1}; // the "A" in the int A_coordH[8] = {0, 0, 0, 1, 1, 2, 2, 2}; // title screen. int O_coordV[7] = {1, 2, 0, 3, 1, 2, -1}; // the "O" in the title int O_coordH[6] = {0, 0, 1, 1, 2, 2}; // screen. int bar_coordV[5] = {0, 1, 2, 3, -1}; // any vertical bar in the int bar_coordH[4] = {0, 0, 0, 0}; // title screen. int top_coordV[14] = {6, 8, 7, 9, 7, 8, 6, // V coords for rest 8, 9, 7, 9, 7, 8, -1}; // of "ARENA" pixels. int top_coordH[13] = {16, 16, 17, 17, 19, 19, // H coords for rest 20, 20, 20, 21, 21, 24, 25}; // of "ARENA" pixels. int mid_coordV[3] = {11, 13, -1}; // V coords for rest of "OF" pixels. int mid_coordH[2] = {19, 19}; // H coords for rest of "OF" pixels. int bot_coordV[9] = {16, 19, 17, 18, 17, 18, 17, -1}; // V coords for rest // of "DOOM" pixels. int bot_coordH[8] = {13, 13, 14, 14, 25, 26, 27}; // H coords for rest // of "DOOM" pixels. int face_coordV[33] = {1, 2, 3, 4, 5, 6, 0, 0, 0, // V coords for 0, 0, 0, 1, 2, 3, 4, 5, 6, // animated face. 7, 7, 7, 7, 7, 7, 2, 2, -1}; int face_coordH[32] = {0, 0, 0, 0, 0, 0, 1, 2, // H coords for 3, 4, 5, 6, 7, 7, 7, 7, 7, // animated face. 7, 1, 2, 3, 4, 5, 6, 2, 5}; int smile_coordV[7] = {4, 4, 4, 4, 5, 5, -1}; // V and H coords for a int smile_coordH[6] = {2, 3, 4, 5, 3, 4}; // smiling mouth. int frown_coordV[7] = {4, 4, 5, 5, 5, 5, -1}; // V and H coords for a int frown_coordH[6] = {3, 4, 2, 3, 4, 5}; // frowning mouth. int erase_coordV[9] = {4, 4, 4, 4, 5, 5, 5, 5, -1}; // used to erase int erase_coordH[8] = {2, 3, 4, 5, 2, 3, 4, 5}; // either mouth. int path_smile_coordV[4] = {0, 1, 0, -1}; // pattern of movement for // animated face, using a int path_smile_coordH[4] = {0, 0, 0, 0}; // "lock-in" position. int path_frown_coordV[4] = {0, 0, 0, 0}; // pattern of movement for // animated face, using a int path_frown_coordH[4] = {0, 1, 0, -1}; // "lock-in" position. // GLOBAL ARRAYS OF NOTES TO BE PLAYED: int time_tune_freq[2] = {P, 0}; // one second's worth of note duration, double time_tune_wait[1] = {H}; // used to set game timing. int titleZ_freq[2] = {f1, 0}; // note played at beginning of song in double titleZ_wait[1] = {e}; // order to prepare console speaker // for output. int titleA_freq[6] = {f1, c2, b, c2, P, 0}; // pitches and durations for // first part of title song; double titleA_wait[5] = {e, S, e, S, S}; // is reused 3 more times. int titleB_freq[7] = {c2, f1, c2, b, b, c2, 0}; // 2nd part of title double titleB_wait[6] = {e, S, S, S, e, e}; // song; reused again. int titleC_freq[5] = {c2, c2, b, f1, 0}; // 3rd part of title song. double titleC_wait[4] = {e, S, S, S}; int titleD_freq[5] = {c2, b, f1, P, 0}; // 4th part of title song. double titleD_wait[4] = {e, e, H, H}; int titleE_freq[7] = {c2, P, E2, P, f2, P, 0}; // final portion of double titleE_wait[6] = {S, S, S, S, S, Q}; // title song. int test_tune_freq[13] = {P, P, P, P, P, P, P, P, P, P, P, P, 0}; // tune for // optimizing double test_tune_wait[12] = {e, S, e, S, S, // note duration. e, S, S, S, e, e, S}; int winA_freq[9] = {g, c1, g, a, A, c1, c1, c1, 0}; // used 3 times at // beginning of double winA_wait[8] = {T, e, e, e, T, e, e, e}; // game-win tune. int winB_freq[12] = {g, c1, g, a, A, A, A, A, c2, c2, P, 0}; // final part of game-win // tune, as well as round double winB_wait[11] = {T, e, e, e, T, e, // completion tune. e, e, T, T, T}; int lose_freq[16] = {f1, c2, G, c2, E, b, g, b, d, a, f1, a, c1, E, P, 0}; // tune for losing double lose_wait[15] = {S, S, S, S, S, S, S, // a round. S, S, S, S, S, e, S, S}; int good_job_freq[14] = {b2, P, F2, P, F2, G2, P, F2, P, A2, P, b2, P, 0}; // tune for double good_job_wait[13] = {e, S, S, S, S, e, // winning a round. S, e, Q, S, e, e, S}; /* END OF FILE */