Hey there, I'm Rowan. I'm currently studying Software Engineering at UTM, and I'm also an IT Entrepreneur. This is my programming blog - you'll find loads of C# stuff in here, as well as MySQL and C tutorials with source. Comments are most welcome.
About Me
Name: Rowy
Location: Unspecified, Mauritius
I'm a unique specimen. This about me isn't going to tell you much. The answer to my real self-description lies in the sum of all my words.
It's a hot sweaty evening in Mr. Nursoo's theory of programming class. At first glance, the lecturer looks like a sadistic bastard. At second glance... well, it's the same - he's still a sadistic bastard.
He's strolling in front of the whole class as if he was processing the real world in background, barely taking input from the sad faces of his students. He's explaining about the assignment. And I'm not there, because I got exempted from the programming module.
It's not about the lecturer. I had a few lectures with the guy before receiving my exemptions. I can't judge whether he's a good programmer or not - I never saw any code of his, but he does look like he's got his shit together. Sadistic bastard or not, I like him. He stands out of the group of regular lecturers. Some might think his class is boring - but I don't share that opinion. Alright, his voice might be euthanasiating, but anybody who would care to listen to the contents might learn a lot. If I didn't have all those ongoing projects, I wouldn't have taken the exemptions. Nor would I have been so frequently absent from university.
A few friends of mine asked for help on the assignment. It's actually a game of American Roulette implemented in C. I thought I'd also put a post up on my programming blog, for my buddies, and if anybody else needed help on that (yes, I'm talking about you!).
"HA! That's freakin' easy," I thought. Fuck it was.
I tried implementing the whole thing late at night, thinking that it might take around 30-45 minutes, but I got stuck on real basic shit. Like, structures. And pointers. And arrays of structures. And pointers to arrays of structures. And I believe that in the process, I managed to get some of the most stupid compiler messages ever, ever.
I didn't finish it on the first day. I only managed to create a few header files, and declare the structures.
On the second day, my friends visited me. I got back to work on the program, promising them to finish. I got stuck with passing parameter passing by reference. It just didn't want to work. Of course, I had fucked a few things up in the code - that's why. Pointers can be real bitches if you don't know the right syntax. I have a lot of experience with pointers, but that's in Delphi and the good old Pascal. Tired of trying, I moved on to using global variables. You can't blame me, there were people sitting right behind me expecting me to finish it. Which I didn't.
My friends left, and the program was about 60% complete. I learnt that Mr. Nursoo had requested the students NOT to use global variables. Sadistic bastard. On the third day, I rebuilt everything. I created a structure within another structure, and looked up parameter passing by reference in C on the net. I also copied a few lines of code with which helped to fiddle with the console's display colours and cursor. I got bored on day 3.
On day 4, I resumed work. I had already totalled around 4 hours of programming on the project. For fuck's sake, it's a Roulette program! A roulette program! I mean, seriously.
After another hour of coding, I finished the thing.
291 lines in the Main.c module. 553 lines in the Menus.h module. 134 lines in the Misc.h module. 331 lines in the Structures.h module. 1309 lines of smelly C code. Fully commented, of course.
Right. It was there! And working!
As you can see, my code spans across 4 files - the entry point of the application is located in Main.c, and the rest are header files that I created. The Menus.h handle most printf methods. The Misc.h header contains misc. functions such as generating random numbers, and a few functions I copied from the net. I didn't author the GotoXY and SetRGB functions - found those on the net. They turned out to be pretty useful though :) Finally, the Structures.h contains the two structures contained within the program, and a bunch of methods to deal with them.
To run the code, place all files within the same folder, and run the main.c file.
The game works as follows: When the program starts, the user is prompted to enter the number of players (between 2 and 10). Right after, the user needs to enter the name of each player. Each player has a starting balance, which can be altered by changing the startBalance constant. As soon as that's done, the program then takes the user to the first player's menu. From there, the player can bet on one or many numbers, bet on red, black, even, odd, hi, low, reset his/her bets, skip the turn or exit the application.
When the user's betting, he can see all the previous bets neatly laid out in front of him. I added a maximum bet setting on each type of bet - i.e. you can bet a max of $100 on a number (or US$100 on red, black, even, odd, hi or low). That maximum bet can be changed by altering the maxBet constant.
When a player's done placing his/her bets, he/she has to end his turn. It'll be the other player's turn to start betting. The same stuff goes on for all the following players, until all of them have placed their bets. Note that a player can also bet nothing at all, which means that his balance will remain unaltered during the current turn. What's cool with my program is that players can bet on several things, as long as their balance and the maximum bet allows them to.
When all the players are done betting, a random number is drawn, and an interface is displayed which shows all the player's original balance, their earnings, and their new balance. Any player with a balance of zero is set as GameOver, and all his/her future turns will be skipped.
The game continues until everybody is GameOver, or until somebody exits from the player menu. That's it!
If you plan to copy the code without understanding, Nursoo WILL KNOW because you'll look like a dumbass as soon as he starts asking questions. If you plan to study the program I wrote, you might want to learn about:
Functions, and return values
Passing parameters to functions by reference
Structures
Arrays
Pointers to arrays, structures, and arrays of structures.
Here goes the main.c file:
/* Roulette program - by Rowan R. Jugernauth File description: Main application program with entry point Email: rowan.rishi@gmail.com */
//starting player balance constint startBalance = 5000;
//maximum bet constint maxBet = 100;
//Main function of program int main() { //number of players int numPlayers;
//All players in the game struct Player players[10];
//display the main menu DisplayMenu();
//set the number of players numPlayers = EnterPlayers();
//temporary variable int i = 0;
//loop through the players and input their details for (i = 0; i<=numPlayers-1; i++) { ClrScr(); printf("\n\n\n\tPlayer %d", i+1); players[i] = InputPlayerDetails(startBalance); }
//check if the game is over for all players while(!IsGameOver(players, numPlayers)) { //loop through the players and have them to play for (i = 0; i<=numPlayers-1; i++) { if (players[i].gameOver == 0) { StartGame(&players[i]); } }
//generate random number and display score Payout(&players, numPlayers); }
//end program Quit(); }
//starts the game for a certain player void StartGame(struct Player * currentPlayer) { //reset all bets ResetPlayerBets(currentPlayer, currentPlayer->balance);
//create a variable to define the user's choice int choice = -1; int numBet = 0; int amountBet = 0; int totalBets = 0;
do { totalBets = CountPlayerBets(*currentPlayer); PrintPlayerDetails(*currentPlayer); choice = DisplayPlayerMenu();
switch(choice) { case 0: //view board //view player bets DrawBoard(*currentPlayer);
//wait for user to press key getch();
//invalidate choice choice = -1; break;
case 1: //bet on number //get which number the user just bet on numBet = BetOnNumber(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->numbers[numBet+1].bet);
//increase bet on number currentPlayer->numbers[numBet+1].bet += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 2: //bet on red //display the board BetOnRed(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->betRed);
//increase bet on number currentPlayer->betRed += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 3: //bet on black //display the board BetOnBlack(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->betBlack);
//increase bet on number currentPlayer->betBlack += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 4: //bet on even //display the board BetOnEven(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->betEven);
//increase bet on number currentPlayer->betEven += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 5: //bet on odd //display the board BetOnOdd(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->betOdd);
//increase bet on number currentPlayer->betOdd += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 6: //bet on low 18 //display the board BetOnLo(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->betLo);
//increase bet on number currentPlayer->betLo += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 7: //bet on hi 18 //display the board BetOnHi(*currentPlayer);
//get the amount the user is betting amountBet = GetBetAmount(*currentPlayer, maxBet, currentPlayer->betHi);
//increase bet on number currentPlayer->betHi += amountBet;
//increase bet on number currentPlayer->balance -= amountBet;
//invalidate choice choice = -1; break;
case 8: //reset bets //reset the player's bets ResetPlayerBets(currentPlayer, currentPlayer->balance + CountPlayerBets(*currentPlayer));
//invalidate choice choice = -1; break;
case 9: //skip turn break;
case 10: //call exit to terminate the program Quit(); break; }
} while ((choice < 1) || (choice > 10)); }
//Generate the winning number and display the earnings void Payout(struct Player (*allPlayers)[10], int numPlayers) { //set winning number int winningNum = Rand();
//Display winning information for the number DisplayWinningInfo(winningNum);
//temporary integer int i = 0;
//initialize a blank array for each player's earnings int earnings[10] = {0,0,0,0,0,0,0,0,0,0};
//loop through the players and calculate their earnings for (i=0; i<=numPlayers-1; i++) { if (IsNumberRed(winningNum)) { earnings[i] += (*allPlayers)[i].betRed * 2; }
if (IsNumberBlack(winningNum)) { earnings[i] += (*allPlayers)[i].betBlack * 2; }
if (IsNumberEven(winningNum)) { earnings[i] += (*allPlayers)[i].betEven * 2; }
if (IsNumberOdd(winningNum)) { earnings[i] += (*allPlayers)[i].betOdd * 2; }
if (IsNumberHi(winningNum)) { earnings[i] += (*allPlayers)[i].betHi * 2; }
if (IsNumberLo(winningNum)) { earnings[i] += (*allPlayers)[i].betLo * 2; }
//display all the earnings DisplayEarnings(*allPlayers, earnings, numPlayers);
//increment the player's earnings and set their game over status PayEarnings(*allPlayers, earnings, numPlayers); }
There goes the Menu.h file:
/* Roulette program - by Rowan R. Jugernauth File description: Header file which contains the menu and misc. printing functions Email: rowan.rishi@gmail.com */
//display the welcome menu void DisplayMenu() { ClrScr(); SetRGB(3); GotoXY(26,0); printf("=== Rowan's Roulette 1.0 ==="); }
//requests the user for the number of players int EnterPlayers() { int players = 0;
while ((players < 2) || (players > 9)) { SetRGB(6); GotoXY(12,10); printf("Please enter the number of players [between 2 and 9]: "); SetRGB(2); scanf("%d", &players);
if ((players < 2) || (players > 9)) { GotoXY(12,10); SetRGB(1); printf("\t\t\t\t\t\t\t\t[wrong]"); //clear the line and write "wrong" at the end. } }
return players; }
//input details of each player struct Player InputPlayerDetails(int startBalance) { //create a new player struct Player newPlayer;
//set the new player's game over to false newPlayer.gameOver = 0;
SetRGB(6); printf("\n\tPlease enter the player's name: "); SetRGB(2); scanf("%s", &newPlayer.name);
ResetPlayerBets(&newPlayer, startBalance);
return newPlayer; }
//Display the player's details void PrintPlayerDetails(struct Player somePlayer) { //display the top menu DisplayMenu();
//count the player's bet int sumBets = CountPlayerBets(somePlayer);
//Display the menu intended for the player int DisplayPlayerMenu() { int choice = 0;
printf("\n\n\t\t0. View current bets"); printf("\n\t\t1. Bet on a number (straight)"); printf("\n\t\t2. Bet on Red"); printf("\n\t\t3. Bet on Black"); printf("\n\t\t4. Bet on Even"); printf("\n\t\t5. Bet on Odd"); printf("\n\t\t6. Bet on Low-18"); printf("\n\t\t7. Bet on High-18"); printf("\n\t\t8. Clear all bets"); printf("\n\t\t9. Next player"); printf("\n\t\t10. Exit");
SetRGB(6); printf("\n\n\tPlease enter a choice [0-10]: "); SetRGB(2); scanf("%d", &choice); return choice; }
//Asks the user to input a number to bet on int BetOnNumber(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer); GotoXY(60,1); SetRGB(3); printf("Betting on a number");
int choice = -1;
do { SetRGB(2); GotoXY(10, 22); SetRGB(6); printf("Please enter a number between 0 and 36. Enter -1 for 00: "); SetRGB(2); scanf("%d", &choice);
if ((choice < -1 ) || (choice > 36)) { SetRGB(1); GotoXY(10,22); printf("\t\t\t\t\t\t\t\t[wrong]"); //clear the line and write "wrong" at the end }
} while((choice < -1 ) || (choice > 36));
return choice; }
//User is betting on red void BetOnRed(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer);
GotoXY(60,1); SetRGB(3); printf("Betting on red"); }
//User is betting on red void BetOnBlack(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer);
GotoXY(60,1); SetRGB(3); printf("Betting on black"); }
//User is betting on red void BetOnEven(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer);
GotoXY(60,1); SetRGB(3); printf("Betting on even"); }
//User is betting on red void BetOnOdd(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer);
GotoXY(60,1); SetRGB(3); printf("Betting on odd"); }
//User is betting on red void BetOnLo(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer);
GotoXY(60,1); SetRGB(3); printf("Betting on low-18"); }
//User is betting on red void BetOnHi(struct Player currentPlayer) { //draw the board DrawBoard(currentPlayer);
GotoXY(60,1); SetRGB(3); printf("Betting on high-18"); }
//Asks the user to input a bet amount int GetBetAmount(struct Player currentPlayer, int maxBet, int currentBet) { int balance = currentPlayer.balance; int betAmount = -1;
do { SetRGB(0); GotoXY(10, 22); printf("\t\t\t\t\t\t\t\t"); //clear the line GotoXY(10, 22); printf("Amount already placed: %d", currentBet); SetRGB(2); GotoXY(10, 23); printf("\t\t\t\t\t\t\t\t"); //clear the line GotoXY(10, 23); SetRGB(6); printf("Please enter a bet amount between 0 and %d: ", maxBet); SetRGB(2); scanf("%d", &betAmount);
if (betAmount > balance || betAmount > maxBet || (betAmount+currentBet > maxBet)) { if ((betAmount+currentBet) > maxBet) { GotoXY(10, 24); printf("\t\t\t\t\t\t\t\t"); GotoXY(10, 24); SetRGB(1); printf("This amount unfortunately exceeds the maximum bet."); } else if (betAmount > balance) { GotoXY(10, 24); printf("\t\t\t\t\t\t\t\t"); //clear the line GotoXY(10, 24); SetRGB(1); printf("This amount unfortunately exceeds your balance."); } getch(); }
/* File description: Miscelleaneous functions Most functions are foreign implementations of useful functions Email: rowan.rishi@gmail.com */
#include <stdlib.h> #include <windows.h>
//Clear the screen void ClrScr() { system("CLS"); }
//THIS IS NOT CODE FROM ME. I COPIED THAT FROM THE NET //go to specific coordinates on the screen void GotoXY(int x, int y) { static HANDLE hStdout = NULL; COORD coord;
//THIS IS NOT CODE FROM ME. I COPIED THAT FROM THE NET // Set text and background colors. void SetRGB(int color) { switch (color) { case 0: // White on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); break; case 1: // Red on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED); break; case 2: // Green on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; case 3: // Yellow on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); break; case 4: // Blue on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE); break; case 5: // Magenta on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE); break; case 6: // Cyan on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE); break; case 7: // Black on Gray SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | BACKGROUND_INTENSITY); break; case 8: // Black on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); break; case 9: // Red on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_RED); break; case 10: // Green on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_GREEN); break; case 11: // Yellow on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN); break; case 12: // Blue on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_BLUE); break; case 13: // Magenta on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_BLUE); break; case 14: // Cyan on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_BLUE); break; case 15: // White on White SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); break; default : // White on Black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); break; } }
//generate a random number between 0 and 37 int Rand() { return ( (rand() % (38))); //return 1; }
//method to quit program void Quit() { ClrScr(); SetRGB(2); GotoXY(12, 10); printf("By Rowan R. Jugernauth. Email: "); SetRGB(0); printf("rowan.rishi@gmail.com"); getch(); exit(0); }
And finally, the structures.h file:
/* Roulette program - by Rowan R. Jugernauth File description: Contains structures and codes to deal with those structures Email: rowan.rishi@gmail.com */
//Defining a casino number struct Number { //value of number intvalue;
//bet value int bet;
//red, black or green char color; };
//Defining a casino player struct Player { //player's name char name[32];
//player's balance int balance;
//player's game status int gameOver;
//All numbers in the game struct Number numbers[38];
//amount bet on hi int betHi;
//amount bet on lo int betLo;
//amount bet on red int betRed;
//amount bet on black int betBlack;
//amount bet on even int betEven;
//amount bet on odd int betOdd;
};
//initialize variables void InitNumbers(struct Player * somePlayer) { //temporary counter; int counter;
//set the first number to -1. This actually represents 00 somePlayer->numbers[0].value = -1; somePlayer->numbers[0].color = 'g'; somePlayer->numbers[0].bet = 0;
//loop through the numbers and reset their bets for (counter = 1; counter<=37; counter++) { //numbers[counter].bet = 250; somePlayer->numbers[counter].value = counter; somePlayer->numbers[counter].bet = 0; }
//counts all of a pleyer's bets int CountPlayerBets(struct Player player) { int sum = 0; int i = 0;
//sum bets for others sum += player.betHi; sum += player.betLo; sum += player.betBlack; sum += player.betEven; sum += player.betOdd;
//sum bets for other numbers for (i = 0; i<=37; i++) { sum += player.numbers[i].bet; }
//return sum return sum; }
//checks whether all players are ga int IsGameOver(struct Player players[10], int numPlayers) { int overCount = 0; int i = 0;
for (i = 0; i<=numPlayers-1; i++) { if (players[i].gameOver == 1) { overCount++; } }
return (overCount == numPlayers); }
//sets all players to game-over void SetAllGameOver(struct Player * players[10], int numPlayers) { int i= 0;
for (i=0; i<=numPlayers-1; i++) { players[i]->gameOver = 1; } }
//method to check if a number is red int IsNumberRed(int number) { struct Player tempPlayer; InitNumbers(&tempPlayer); if (tempPlayer.numbers[number+1].color == 'r') { return 1; } else { return 0; } }
//method to check if a number is black int IsNumberBlack(int number) { struct Player tempPlayer; InitNumbers(&tempPlayer); if (tempPlayer.numbers[number+1].color == 'b') { return 1; } else { return 0; } }
//method to check if a number is even int IsNumberEven(int number) { //check if numbers aren't 00 and 0 if (number > 0) { //check if even if ((number % 2) > 0) { return 0; } else { return 1; } } else { return 0; } }
//method to check if a number is odd int IsNumberOdd(int number) { //check if numbers aren't 00 and 0 if (number > 0) { //check if odd if ((number % 2) > 0) { return 1; } else { return 0; } } else { return 0; } }
//method to check if a number is hi int IsNumberHi(int number) { //check if numbers aren't 00 and 0 if (number > 0) { //check if odd if (number >= 18) { return 1; } else { return 0; } } else { return 0; } }
//method to check if a number is lo int IsNumberLo(int number) { //check if numbers aren't 00 and 0 if (number > 0) { //check if odd if (number < 18) { return 1; } else { return 0; } } else { return 0; } }
//pay the earnings and set each player's game over status void PayEarnings(struct Player (*allPlayers)[10], int earnings[10], int numPlayers) { int i = 0;
for (i = 0; i<=numPlayers-1; i++) { //if the player isn't game over yet if ((*allPlayers)[i].gameOver == 0) { (*allPlayers)[i].balance += earnings[i];
//set the player's game over status if balance zero or less if ((*allPlayers)[i].balance <= 0) { (*allPlayers)[i].gameOver = 1; } } } }
Please let me know if there are any bugs or corrections to be made! Cheers, Rowan