2001 LSU Computer Science High School Programming Contest

Sponsored by Texas Instruments

Novice and Veteran - Problem 4, Solution in c

/*
	Brownopoly
*/


#include <stdio.h>

#define NUM_PLAYERS 2

// "Go" must always be at position 0
#define BOARD_LUX_TAX   12
#define BOARD_JAIL      20
#define BOARD_GOTO_JAIL 24

// Initial starting location for both players
#define BOARD_START     0

// Total number of spaces on the board
#define BOARD_MAX       32

// Defining the DEBUG macro causes a status message to print at every turn
#ifdef DEBUG
#define DEXEC(x) { x }
#else
#define DEXEC(x)
#endif

int main() {

   int money[NUM_PLAYERS];
   int position[NUM_PLAYERS];   // 0 through BOARD_MAX: 0 is "Go"
   int jailcount[NUM_PLAYERS];  // number of turn spent in jail

   int player;                  // Keep track of who's turn it is
   int doublecount;             // How many doubles rolled in a row
   int moveagain;               // True if player moves again on same turn
   int nummoves;		// Number of moves in game

   int dice1, dice2, i, j, numgames, gamecount;

   // Read in how many games we have to simulate
   scanf(" %d", &numgames);

   for (gamecount = 0; gamecount < numgames; gamecount++) 
    { // loop for each game

	DEXEC( printf("BEGIN GAME %d\n", gamecount + 1); );

	for (i = 0; i < NUM_PLAYERS; i++) 
	 { // Initialize player data
		money[i] = 1500;
	        position[i] = BOARD_START;
	        jailcount[i] = 0;
	 } // Initialize player data

	player = 0;
	doublecount = 0;   

	// read in number of moves
	scanf(" %d",&nummoves);

	for (j=0; j < nummoves; j++)
	 { // loop for each move

		// Read the dice rolls from the input
		scanf(" %d %d", &dice1, &dice2);

		// Count the number of doubles rolled and assume that if we got
		// doubles we can move again on the same turn
		if ( dice1 == dice2 ) 
		 { // found doubles
			moveagain = 1;
			doublecount++;
		 } // found doubles
		else 
		 { // not doubles
			moveagain = 0;
		 } // not doubles

		DEXEC( printf("Player %d rolled %d and %d; ", player + 1, dice1, dice2); );

		// If this player is already in jail then try to get out
		if ( jailcount[player] ) 
		 { // players is in jail

			// If doubles rolled then get out of jail; NOTE: player moves the
			// amount rolled but does not get to go again on the same turn
			if ( dice1 == dice2 ) 
			 { // rolled a double - get out of jail free
				jailcount[player] = 0;
				moveagain = 0;
			 } // rolled a double - get out of jail free

			// If no doubles rolled and this is the third attempt then pay $50
			// and move tha amount on the dice
			else if ( jailcount[player] == 3 ) 
			 { // no double after 3 tries
				money[player] -= 42;
				jailcount[player] = 0;
				moveagain = 0;
			 } // no double after 3 tries

			// Otherwise if no doubles thrown, just sit and rot in jail
			// and keep track of how long we've been there
			else 
			 { // stay in jail a little longer
				jailcount[player]++;
				moveagain = 0;
			 } // stay in jail a little longer
		 } // players is in jail

		// If a player got doubles three times in a row then go to jail
		// Do not pass Go; do not collect $200
		if ( doublecount == 3 ) 
		 { // go to JAIL
			moveagain = 0;
			jailcount[player] = 1;
			position[player] = BOARD_JAIL;
		 } // go to JAIL

		// If we're not in jail or we just got out then move along the board
		if ( jailcount[player] == 0 ) 
		 { // normal move

			int oldposition, newposition;

			oldposition = position[player];
			newposition = position[player] + dice1 + dice2;

			// Collect $200 for pasing or landing on "Go"
			if ( newposition >= BOARD_MAX ) 
			 { // passed go
				DEXEC( printf("<collect $200> "); );
				money[player] += 200;
			 } // passed go

			// Reposition the player token with "wraparound"
			position[player] = newposition % BOARD_MAX;

			// Handle all the different places a player could land
			switch( position[player] ) 
			 { // switch - special squares

			 // If player lands on "Go to Jail" then do just that
			 case BOARD_GOTO_JAIL:
				DEXEC( printf("<goto jail> "); );

				position[player] = BOARD_JAIL;
				jailcount[player] = 1;
				moveagain = 0;

				break;

			 // If player lands on luxury tax then immediately pay $42
			 case BOARD_LUX_TAX:
				DEXEC( printf("<luxury tax> "); );

				money[player] -= 42;
				break;

			 // Any other space has no effect
			 default:
				break;
			 } // switch - special squares
		 } // normal move

		DEXEC
		 ( // DEXEC
			if ( jailcount[player] )
				printf("IN JAIL; ");

			printf("on position %d; with $%d\n", position[player], money[player]);
		 ) // DEXEC

		// Let the next player go if this one is finished with this turn
		if ( !moveagain ) 
		 { // change players
			doublecount = 0;
			player = (player + 1) % NUM_PLAYERS;
		 } // change players

	 } // loop for each move

	for (i = 0; i < NUM_PLAYERS; i++)
		printf("Player %d: $%d\n", i + 1, money[i]);

	printf("\n");

    } // loop for each game

   return 0;
}


Return to Problem Index


 

The statements and opinions included in these pages are those of 2001 LSU Computer Science High School Programming Contest only. Any statements and opinions included in these pages are not those of Louisiana State University or the LSU Board of Supervisors.
© 2000,2001 Isaac Traxler
Last modified: Friday, 01 July, 2011 16:27:53