<mosaic.cnfolio.com>
PROGRAM
1. /* ### PSUEDO CODE ###
2.
3. START
4.   Populate the list with all the infomation about the valid bets
5.
7.
8.   WHILE 4 pairs haven't been read
9.
12.
13.     Move to the next pair
14.
15.   END WHILE
16.
17.   ### Converting to uppercase ###
18.
19.   WHILE there are bet names left
20.
21.       Convert all the letters in the bet name to uppercase
22.       Move to the next bet name
23.
24.   END WHILE
25.
26.   ### Detecting the bets ###
27.
28.   WHILE there are bet names left
29.
30.       WHILE bet number < number of valid bets in the list
31.
32.           IF the bet name matches the valid bet on the list
33.               THEN
34.                   Store the valid bet number
35.
36.                   Stop comparing this bet name against the list
37.           END IF
38.
39.           Increase bet number by 1
40.       END WHILE
41.
42.       IF the bet name didn't match any valid bet
43.           THEN
44.               Error + 1
45.               Output an error message
46.
47.               Stop checking any more bet names
48.
49.       END IF
50.
51.       Move to the next bet name
52.
53.   END WHILE
54.
55.   ### Checking bet amounts ###
56.
57.   WHILE there are bet amounts left AND No errors have occured
58.
59.       IF the bet amount is not a whole positive number
60.           THEN
61.               Error + 1
62.               Output an error message
63.
64.               Stop checking any more bet amounts
65.       END IF
66.
67.           Move to the next bet amount
68.
69.   END WHILE
70.
71.   ### Spinning the wheel and checking if player has won ###
72.
73.   IF no errors have occured
74.
75.       WHILE there are bets left
76.           THEN
77.
78.               Pick a random position on the roulette wheel
79.
80.               WHILE there are still positions that the bet wins on
81.
82.                   IF the random position matches the position the bet wins on
83.                       THEN
84.                           Amount won = amount bet + the amount bet * the odds of the bet placed
85.
86.                           subtotal = subtotal + amount won
87.
88.                           Generate the output text which tells the player
89.                               They won, where they placed their bet,
90.                               the amount they bet, the amount they won
91.                               their profit and their current subtotal
92.
93.                           Error = 0
94.                       ELSE
95.                           Error = 1
96.                   END IF
97.
98.                   Move to the next position the bet wins on
99.
100.               END WHILE
101.
102.               IF Error is 1
103.                   THEN
104.                       amount won is 0
105.
106.                       subtotal = subtotal - amount bet
107.
108.                       Generate the output text which tells the player
109.                               They lost, where they placed their bet,
110.                               the amount they bet, the amount they lost
111.                               their profit and their current subtotal
112.
113.               END IF
114.
115.       Move to the next bet
116.
117.       END WHILE
118.
119.       Generate the text which tells the player, the total amount: bet, won, and  total profit
120.
121.         START Rendering Graphics
122.             Calculate the starting position for the 4 balls
123.
124.             WHILE there are frames remaining
125.                 Create the frame
126.
127.                 Draw the roulette wheel
128.                 Draw the numbers of the roulette wheel
129.
130.                 IF the frame number is < 30
131.                     THEN
132.                         WHILE there are still balls to draw
133.                             Increase the ball's angle
135.
136.                             Calculate the ball's X position based on radius and angle
137.                             Calculate the ball's Y position based on radius and angle
138.
139.                             Draw the ball at the X and Y position
140.                             Draw the ball's number in the centre
141.                         END WHILE
142.
143.                     ELSE
144.                         WHILE there are still balls to draw
145.                             Increase the ball's angle by a factor
146.                             Decrease the ball's radius by a factor
147.
148.                             Calculate the ball's X position based on radius and angle
149.                             Calculate the ball's Y position based on radius and angle
150.
151.                             Draw the ball at the X and Y position
152.                             Draw the ball's number in the centre
153.
154.                             IF the factor is to small
155.                                 THEN
156.                                     Increase the factor
157.                             END IF
158.                         END WHILE
159.                 END IF
160.
161.                 WHILE there are lines of output text left
162.                     Draw the line of output text
163.                     Move to the next output text line
164.                 END WHILE
165.
166.                 Draw the roulette table
167.                 Draw the numbers on the roulette table
168.
169.                 WHILE there are chips left to draw
170.                     Draw the chip based on the X and Y position stored in the list
171.                      Move to the next chip
172.                 END WHILE
173.
174.                 Save the frame
175.                 Move to the next frame
176.             END WHILE
177.         END Rendering Graphics
178.
179.       ELSE
180.         Output error messages
181.         Output a message telling the player the valid bets and how to input them
182.
183.   END IF
184.
185. END
186.
187. */
188. #include <stdio.h>
189. #include <stdlib.h>
190. #include <string.h>
191. #include <time.h>
192.
193. #include <gd.h>
194.
195. #define numofbets       152 /* This is defined pre-program as any inconsistency will result in Fatal Runtime errors that are a pain to locate */
196. #define numofoutlines   10 /* Same again */
197.
198. #define  framewidth  1000
199. #define  frameheight   560
200. #define  maxframecount 90
201. #define  frametime    12
202.
203. #define PI (3.141592653589793)
204.
205. struct libary {
206.    char  name[18];
207.    int   odds;
208.    int   numofnums; /* This defines how long the array of numbers bet on will be, see below */
209.    int   *numbers; /* This is not declared as a fixed lenght array as there is many different types of bets that bet of different quanties of numbers */
210.    int   coords[2]; /* Array contains the x and y coordinates of the position on boards that bet chip will be placed on */
211. }  betlibary[numofbets];
212.
213. void loadbet( int, char[], int, int,int,int);
215. void graphics( int ballnumbers[4], int *ptr, FILE *fp ); /* The frame pointer and file pointer have to be past to the function */
216.
217. int tempnumbers[20], position=0, word=0, spaces=0, betnum = 0,error=0, dash=0;
218. int bet[4] = { -1,-1,-1,-1 };
219. char outputtext[numofoutlines][128];
220.
221. int main( void ){
222.
223.    int i=0, j=0;
224.    int amountbet[4] = { -1,-1,-1,-1 };
225.    int amountwon[4] = { 0 };
226.    char inputraw[8][18];
227.    int wheel[4] = {0};
228.
229.
230.    srand(time(0));
231.
232. /* The below loop puts blank characters in the input array */
233.
234.
235.    for( word=0; word < 8; word++)
236.    {
237.       for(position=0 ; position<18 ; position++)
238.       {
239.          inputraw[word][position] = '\0'; /* Loading the array with NULL characters seems to reduces errors in matching the input to betlibary */
240.       }
241.
242.    }
243.
244. /* Calling the loadlibary function copies all the infomation about all the valid bets into the betlibary structure */
245.
247.
248. /* ### Reading the inputs and separating into inputraw array ### */
249.
250.    for(word=0;word<8;word+=2)
251.    {  /* Scanning as pairs of numbers is more compact and easier to read than 1arge scanf statment */
252.
253.       scanf("%s %s ", inputraw[word], inputraw[word+1]);
254.
255.    }
256.
257. /* ### Converting to uppercase ### */
258.
259.    for(word=0;word<8;word+=2)
260.    {
261.
262.       for(position=0; position<strlen(inputraw[word]); position++)
263.       {
264.
265.          if( isalpha( inputraw[word][position] ) )
266.          {
267.
268.             inputraw[word][position] = toupper(inputraw[word][position]);
269.
270.          }
271.
272.       }
273.    }
274.
275. /* ### Bet detection ### */
276.
277.    for(word=0; word < 8;word += 2) /* Only check the even numbered input words */
278.    {
279.
280.       for(betnum = 0;betnum<numofbets;betnum++) /* Check the entered word against every valid bet, going over the end of the array causes problems */
281.       {
282.          if(strcmp(inputraw[word],betlibary[betnum].name)==0) /* strcmp returns 0 if the strings match */
283.          {
284.             bet[(word/2)]=betnum; /* Store the number of the bet they placed */
285.             break; /* There is no need to continue checking if the bet has matched */
286.          }
287.       }
288.
289.       if(bet[(word/2)] == -1) /* If the input didn't match any of the valid bets */
290.       {
291.          printf("Invalid bet detected, please enter 4 valid bets\n");
292.          error++;
293.          break;
294.       }
295.
296.    }
297.
298. /* ### Converting to intergers ### */
299.
300.    for(word = 1, position = 0; word < 8 && error == 0; word += 2 ){
301.
302.       for(position = 0; position<strlen(inputraw[word]);position++)
303.       {
304.          if( (isdigit(inputraw[word][position])==0) || (position==0 && (inputraw[word][position]=='0') ) ) /* The part of the IF condition prevents any string starting 0 being valid bet amounts */
305.          {
306.             printf("\nInvalid amount bet, please enter 4 whole numbers\n");
307.             error++;
308.             break;
309.          }
310.
311.       }
312.
313.       if( error == 0 ){ /* Only convert to intergers if all the characters are digits*/
314.          amountbet[((word - 1)/2)] = atoi( inputraw[word] ); /* Convert word 1 to 0, word 3 to 1, etc  */
315.       }
316.
317.       if( amountbet[((word - 1)/2)] == 0 ){ /* This check is nessesary to catch if the last bet amount is not inputted, and potentially some other error conditions */
318.          printf("\nInvalid amount bet, please enter 4 whole numbers\n");
319.          error++;
320.          break;
321.       }
322.
323.    }
324.
325. /* ### Spinning the wheel and checking if player has won ### */
326.
327.    if( error == 0 ) /* Only spin the wheel if all the inputs are valid */
328.    {
329.       int subtotal = 0;
330.       for(i=0; i<4 ;i++)
331.       {
332.
333.          wheel[i] = (rand() %38); /* Save all the random numbers so they can be rendered */
334.
335.          for(j=0; j < betlibary[bet[i]].numofnums;j++) /* The array is not of fixed size so only go upto the number of numbers (numofnums) */
336.          {
337.             if(betlibary[bet[i]].numbers[j]==wheel[i]) /* Check every number that the bet can win on */
338.             {
339.                amountwon[i] = (amountbet[i] + (amountbet[i]*(betlibary[bet[i]].odds)));
340.
341.                subtotal += (amountwon[i] - amountbet[i]);
342.
343.                sprintf(outputtext[(i*2)],"Ball %d landed on %s, you bet on %s and won!\0",(i+1),betlibary[wheel[i]].name,betlibary[bet[i]].name);
344.                sprintf(outputtext[(i*2)+1],"You bet £%d and thus won £%d this is a £%d profit, your current subtotal is £%d.\0",amountbet[i],amountwon[i],(amountwon[i] - amountbet[i]), subtotal);
345.
346.                error = 0; /* Reset error as the ball has landed on a winning number */
347.
348.                break;
349.
350.             }else
351.             {
352.                error = 1; /* If the ball hasn't landed on the betting number then  */
353.             }
354.
355.           }
356.
357.          if(error == 1) /* if the ball didn't land on any winning number for this bet */
358.          {
359.             amountwon[i]= 0;
360.
361.             subtotal = subtotal - amountbet[i];
362.
363.             sprintf(outputtext[(i*2)],"Ball %d landed on %s, you bet on %s and didn't win.\0",(i+1),betlibary[wheel[i]].name,betlibary[bet[i]].name);
364.             sprintf(outputtext[(i*2)+1],"You bet £%d and thus lost £%d, your current subtotal is £%d.\0",amountbet[i],amountbet[i], subtotal);
365.
366.             error = 0; /* reset error for next time */
367.
368.          }
369.
370.       }
371.       int totalbet = amountbet[0] + amountbet[1] + amountbet[2] + amountbet[3];
372.       int totalwon = amountwon[0] + amountwon[1] + amountwon[2] + amountwon[3];
373.
374.       sprintf(outputtext[8],"You bet a total of £%d, you won a total of £%d!\0",totalbet,totalwon);
375.       sprintf(outputtext[9],"Your total profit was £%d\0",subtotal); /* At the end of all bets print totals */
376.
377.       FILE *animatedGIF;
378.       gdImagePtr frame;
379.
380.       graphics( wheel, frame, animatedGIF ); /* Render the graphics */
381.
382.    }
383.    else /* If there were errors */
384.    {
385.
386.     /* Tell the user how to input a valid input */
387.
388.        printf("\nPlease input 4 bets and 4 bet amounts, separated by a space, for example:");
389.        printf("\n \"1 100 2 100 3 100 4 100\" \n");
390.        printf("\nPlease only enter whole numbers for the bet amount \n");
391.        printf("\nThe valid bets available are:");
392.        printf("\n    Any single number 0 to 36 and 00");
393.        printf("\n    Any pair of numbers that are touching in this format: \"1-2\" ");
394.        printf("\n    Any row of numbers in this format: \"1-2-3\" ");
395.        printf("\n    Any four numbers that are touching in corners this format: \"1-2-4-5\" ");
396.        printf("\n    Any six numbers that are touching in this format: \"1-2-3-4-5-6\" ");
397.        printf("\n    The three columns in this format: \"1stCol\" etc ");
398.        printf("\n    The three dozens in this format: \"1stDozen\" etc ");
399.        printf("\n    And single word bets such as:");
400.        printf("\n      Red, Black, Odd, Even, High, Low \n \n");
401.
402.
403.    }
404.
405.    return(0);
406.
407. }
408.
409. void loadbet(int bet, char *name, int odds, int numofnums, int x, int y) /* This function copies the given data into the betlibary struct array */
410. {
411.
412.    strcpy(betlibary[bet].name, name); /* Copy the name */
413.
414.    betlibary[bet].odds = odds; /* Save the odds */
415.
416.    betlibary[bet].numofnums = numofnums; /* Save the number of numbers that this bet wins on */
417.
418.    betlibary[bet].numbers = malloc(numofnums * sizeof(int)); /* This creates an array of size "numofnums" at the position pointed to by the "numbers" pointer */
419.
420.    for(int i=0;i<numofnums;i++){ /* Copy all the numbers up to the end of the array */
421.
422.       betlibary[bet].numbers[i]=tempnumbers[i]; /* From the tempnumbers array */
423.
424.    }
425.
426.    betlibary[bet].coords[0] = x;
427.    betlibary[bet].coords[1] = y;
428.
429. }
430.
431. void graphics( int ballnumber[4], int *frame, FILE *animatedGIF ) /* This function renders all the graphics, it should only be used if there are no errors, and the output text is prepared */
432. {
433.    /* roulettewheel array contains the the numbers to be put on the wheel in order */
434.    char roulettewheel[38][4] = {"6","21","33","16","4","23","35","14","2","0","28","9","26","30","11","7","20","32","17","5","22","34","15","3","24","36","13","1","00","27","10","25","29","12","8","19","31","18"};
435.
436.    /* letterangle array contains the angles that the numbers will need to be rotated to have the bottom of the numbers point towards the middle of the circle */
437.    int letterangle[38] = {267.00,257.53,248.06,238.59,229.12,219.65,210.18,200.71,191.24,181.77,172.30,162.83,153.36,143.89,134.42,124.95,115.48,106.01,96.54,87.07,77.60,68.13,58.66,49.19,39.72,30.25,20.78,11.31,0,355.37,345.90,336.43,326.96,317.49,308.02,298.55,289.08,279.61};
438.
439.    /* positionangle array contains the angle from 3 'o' clock that the letters will be drawn on the wheel */
440.    int positionangle[38] = {4.0,12.,20.5,29.5,41.0,48.5,58.5,67.5,79.0,88.50,95.0,107.5,115.0,124.0,133.5,145.5,152.5,162.5,172.0,183.50,190.5,200.0,210.0,222.0,229.5,239.5,248.5,259.5,268.5,277.75,286.5,297.5,306.0,315.0,326.5,335.0,344.0,353.0};
441.
442.    /* position array contains the number of segments from 3 'o' clock that the number is in on the wheel */
443.    int position[38]={9,27,8,23,4,19,0,15,34,11,30,14,33,26,7,22,3,18,37,35,16,1,20,5,24,31,12,29,10,32,13,36,17,2,21,6,25,28};
444.
446.    int mybox[8] = {0}; /* the mybox array that is used to hold the coordinates of the corners of the letters after they are rendered */
447.    double i = 0,tempangle;
448.    char temp[4];
449.    double angle[4] = {0}; /* This array will contain the angle that each ball is currently at */
450.
451.    for( int k =0; k<4;k++) /* This loop looks up the starting position for the balls, based on the angle of the number marking the number position */
452.    {
453.       angle[k] = positionangle[position[ballnumber[k]]] -87; /* The ball stops ~90 degrees from where it started */
454.    }
455.
456.    /* Create first background and frame image */
457.    frame = gdImageCreate( framewidth, frameheight );
458.    gdImageColorAllocate( frame, 255, 255, 255 );
459.
460.    /* Initialize animated GIF with the first background frame */
461.    animatedGIF = fopen( "animation.gif", "wb" );
462.    gdImageGifAnimBegin( frame, animatedGIF, 1, 0 );
463.
464.    /* Start the frame counter at 1 so that it can be used later for movement calculations */
466.    {
467.       gdImageDestroy( frame ); /* Release memory for previous frame image */
468.
469.       frame = gdImageCreate( framewidth, frameheight ); /* Create new frame image */
470.
471.       /* Allocate all the colours, this has to be done for each new frame as the infomation is lost when the previous frame is destroyed */
472.       gdImageColorAllocate( frame, 255, 255, 255 );
473.       black = gdImageColorAllocate( frame, 0, 0, 0 );
474.       red = gdImageColorAllocate( frame, 255, 0, 0 );
475.       grey = gdImageColorAllocate( frame, 128, 128, 128 );
476.       white = gdImageColorAllocate( frame, 255, 255, 255 );
477.       green = gdImageColorAllocate( frame, 0, 255, 0 );
478.       blue = gdImageColorAllocate( frame, 0, 0, 255 );
479.
480.
481.       gdImageFilledEllipse( frame, 150, 150, 259, 259, red ); /* Render the red portions of the wheel */
482.
483.       for(j=0,tempangle = 0;j<20;j++,tempangle += 19)
484.       { /* gdImageFilledArc can only accept intergers for start and end angle, so the black segments have to be 10 degrees wide, 9 degrees apart to fit the correct number on the wheel  */
485.          gdImageFilledArc( frame, 150, 150, 260, 260, tempangle, (tempangle+10), black, gdArc);
486.       }
487.
488.       gdImageFilledArc( frame, 150, 150, 260, 260, 86, 95, green, gdArc); /* Render the 2 green segments for 0 and 00 */
489.       gdImageFilledArc( frame, 150, 150, 260, 260, 266, 276, green, gdArc);
490.
491.       gdImageFilledEllipse( frame, 150, 150, 180, 180, white ); /* Fill the centre of the wheel with white */
492.
493.       gdImageFilledArc( frame, 150, 150, 220, 220, 0, 360, grey, gdNoFill); /* Draw a line splitting the segments in half */
494.
495.       for(j=0;j<38;j++)
496.       {
497.
499.
500.          double x = 150 + (radius * cos(positionangle[j] * (PI / 180) ) );
501.          double y = 150 + (radius * sin(positionangle[j] * (PI / 180) ) );
502.
503.          /* Render the numbers on the wheel, based on the predetermined and tweaked position angle, and rotated by the predetermined and tweaked letter angle */
504.          gdImageStringFT( frame, mybox, grey, "Vera.ttf", 10, (letterangle[j]*(PI/180)), x, y, roulettewheel[j]);
505.       }
506.
507.       /* Draw the 4 balls that changes location based on frame counter */
509.       {
510.          for( j=0;j<4;j++)
511.          {
512.             angle[j] += 12; /* all the balls are at different angles so this needs to be done indpendently */
513.             radius = 124; /* all 4 balls are rendered at the same radius so this only needs to happen once */
514.
515.             double x = 150 + (radius * cos(angle[j] * (PI / 180) ) );
516.             double y = 150 + (radius * sin(angle[j] * (PI / 180) ) );
517.             gdImageFilledEllipse( frame, (int)x, (int)y, 15, 15, grey );
518.
519.             sprintf(temp,"%d",j+1); /* convert j+1 to a string so it can be printed on the current ball */
520.             gdImageStringFT( frame, mybox, red, "Vera.ttf", 8, 0, (x-3), (y+5), temp);
521.
522.          }
523.
524.       }else
525.       {
526.
527.          radius = (124 - (2 *i)); /* all 4 balls are rendered at the same radius so this only needs to happen once */
528.
529.          for( j=0;j<4;j++)
530.          {
531.             angle[j] += (12-i); /* all the balls are at different angles so this needs to be done indpendently */
532.
533.             double x = 150 + (radius * cos(angle[j] * (PI / 180) ) );
534.             double y = 150 + (radius * sin(angle[j] * (PI / 180) ) );
535.             gdImageFilledEllipse( frame, (int)x, (int)y, 15, 15, grey );
536.
537.             sprintf(temp,"%d",j+1); /* convert j+1 to a string so it can be printed on the current ball */
538.             gdImageStringFT( frame, mybox, red, "Vera.ttf", 8, 0, (x-3), (y+5), temp);
539.
540.          }
541.
542.          if(i < 12)
543.          { /* all the balls are slowing down and falling at the same speed so this calculation only needs to be done once a frame */
544.             i += 0.75;
545.          }
546.      }
547.
548.      for(j=0;j<numofoutlines;j++) /* print the number of lines defines at program start, numofoutlines is also the size of outputtext array */
549.      {
550.        gdImageStringFT( frame, mybox, black, "Vera.ttf", 10, 0, 305, (50 + (j*25)), outputtext[j]);
551.      }
552.
553.      /* ### Draw the roulette table ### */
554.
555.      /* Define the edges of the main box */
556.       int left  = 81;
557.       int top   = 300;
558.       int right   = left+(12*40);
559.       int bottom  = top + (3*65);
560.       int ymiddle = top + 65;
561.
562.       gdImageFilledRectangle(frame, left, top, right, bottom, red); /* Draw the red background */
563.       gdImageFilledRectangle(frame, left-40, top, left, bottom, green); /* Draw the left hand box for 0 and 00 */
564.       gdImageFilledRectangle(frame, left, bottom+60, right, bottom, green); /* Draw the bottom box for some of the word bets */
565.       gdImageFilledRectangle(frame, right, top, right+40, bottom, green); /* Draw the right box for the 3 column bets */
566.
567.       for( j = 0; j < 4; j++) /* Render (most of) the black squares */
568.       {
569.          gdImageFilledRectangle(frame, left, ymiddle, left+40, ymiddle+65, black);
570.
571.          left += 40; /* The next 2 squares are on the same line so left only needs to increase once */
572.          gdImageFilledRectangle(frame, left, bottom, left+40, bottom-65, black);
573.
574.          gdImageFilledRectangle(frame, left, top+65, left+40, top, black);
575.
576.          left += 40; /* Move to the next row */
577.          gdImageFilledRectangle(frame, left, ymiddle, left+40, ymiddle+65, black);
578.
579.          left += 40;
580.       }
581.       left = 81; /* reset left to original value */
582.
583.       /* Render the odd 2 black squares */
584.       gdImageFilledRectangle(frame, left+120, bottom , left+160, bottom-65, black);
585.       gdImageFilledRectangle(frame, left+360, bottom, left+400, bottom-65, black);
586.
587.       /* ### Render the vertical grey lines ### */
588.
589.       gdImageFilledRectangle(frame, (left-40)-1, top, (left-40)+1, bottom, grey);
590.       /* All the lines are drawn as rectangles that are 2 pixels wide to make them more visable */
591.
592.       for( j = 0; j<14; j++, left += 40)
593.       {
594.          if( j%4 == 0 ) /* every 4th line needs to be drawn longer */
595.          {
596.             gdImageFilledRectangle(frame, left-1, top, left+1, bottom+60, grey);
597.          }else
598.          {
599.             gdImageFilledRectangle(frame, left-1, top, left+1, bottom, grey);
600.          }
601.       }
602.       left = 81; /* reset left to original value */
603.
604.       gdImageFilledRectangle(frame, (left+80)-1, bottom+60, (left+80)+1, bottom+30, grey);
605.       gdImageFilledRectangle(frame, (left+240)-1, bottom+60, (left+240)+1, bottom+30, grey);
606.       gdImageFilledRectangle(frame, (left+400)-1, bottom+60, (left+400)+1, bottom+30, grey);
607.
608.       /* ### Render the horizontal grey lines ### */
609.       gdImageFilledRectangle(frame, left-40, top+1, right+40, top-1, grey);
610.       gdImageFilledRectangle(frame, left, (ymiddle+65)+1, right+40, (ymiddle+65)-1, grey);
611.       gdImageFilledRectangle(frame, left, ymiddle+1, right+40, ymiddle-1, grey);
612.       gdImageFilledRectangle(frame, left-40, bottom+1, right+40, bottom-1, grey);
613.
614.       gdImageFilledRectangle(frame, left-40, (top+97)+1, left, (top+97)-1, grey);
615.
616.       gdImageFilledRectangle(frame, left, (bottom+60)+1, right, (bottom+60)-1, grey);
617.       gdImageFilledRectangle(frame, left, (bottom+30)+1, right, (bottom+30)-1, grey);
618.
619.       /* ### Render all the numbers on the centre squares ### */
620.       for(int level =0, shift =0, j=1; j<37;j++)
621.       {
622.          sprintf(temp,"%d",j); /* convert j to a string to be printed */
623.
624.          if(j>9) /* If the number is 2 digits it needs a small offset to stay centred */
625.          {
626.             shift = 8; /* This is the case as all the text is rendered from the bottom left corner of the first letter */
627.          }
628.
629.          switch((j-1)%3) /* There is 3 columns of numbers, so doing %3 allows the switch to sort the numbers into the 3 columns, the multiples of 3 are always on the right handed end, so this switch starts */
630.          { /* the minus 1 is required as j starts at 1 rather than 0 */
631.             case 0: /* as I did (j-1)%3, case 0 actually starts a 1, then 4, 7, etc */
632.                gdImageStringFT( frame, mybox, white, "Vera.ttf", 18, (90)*(PI / 180), 110+(level*40), (bottom-25)+shift, temp);
633.                break;
634.             case 1:
635.                gdImageStringFT( frame, mybox, white, "Vera.ttf", 18, (90)*(PI / 180), 110+(level*40), (bottom-90)+shift, temp);
636.                break;
637.             case 2: /* This is the actually multiples of 3 */
638.                gdImageStringFT( frame, mybox, white, "Vera.ttf", 18, (90)*(PI / 180), 110+(level*40), (bottom-155)+shift, temp);
639.                level++; /* On the last number in this row, move to the next row */
640.                break;
641.          }
642.      }
643.
644.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 20, (90)*(PI / 180), left-10, bottom-40, "0");
645.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 20, (90)*(PI / 180), left-10, top + 66, "00");
646.
647.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, (90)*(PI / 180), right+30, bottom-5, "1stCol");
648.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, (90)*(PI / 180), right+30, bottom-70, "2ndCol");
649.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, (90)*(PI / 180), right+30, bottom-135, "3rdCol");
650.
651.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+40, bottom+20, "1stDozen");
652.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+200,bottom+20, "2ndDozen");
653.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+360,bottom+20, "3rdDozen");
654.
655.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+20, bottom+50, "High");
656.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+100, bottom+50, "Even");
657.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+180, bottom+50, "Black");
658.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+260,bottom+50, "Red");
659.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+340,bottom+50, "Odd");
660.      gdImageStringFT( frame, mybox, black, "Vera.ttf", 12, 0, left+420,bottom+50, "Low");
661.
662.      for(j=0;j<4;j++) /* Draw the 4 chips on the table */
663.      {
664.        gdImageFilledEllipse( frame, betlibary[bet[j]].coords[0], betlibary[bet[j]].coords[1], 15, 15, blue );
665.
666.          sprintf(temp,"%d",j+1); /* convert j+1 to a string so it can be printed on the current chip */
667.          gdImageStringFT( frame, mybox, white, "Vera.ttf", 8, 0, (betlibary[bet[j]].coords[0]-3), (betlibary[bet[j]].coords[1]+5), temp);
668.      }
669.
670.      /* Add the frame to the animated gif file */
671.       gdImageGifAnimAdd( frame, animatedGIF, 1, 0, 0, frametime, 1, NULL );
672.    }
673.
674.    /* Save the animated gif and clear memory associated with the animation */
675.    gdImageGifAnimEnd( animatedGIF );
676.    fclose( animatedGIF );
677.    gdImageDestroy( frame );
678.
679. }
680.
682. {
683.
684.    char name[18];
685.    int i,j,betnum, x, y, level = 0;
686.
687.    int left  = 81;
688.    int top   = 300;
689.    int right   = left+(12*40);
690.    int bottom  = top + (3*65);
691.    int ymiddle = top + 65;
692.
693.    /* This loop defines all the single number bets */
694.    for(i=0;i<37;i++)
695.    { /* ################## really? ############### this loop goes upto 37 as it includes 00 */
696.       tempnumbers[0] = i;
697.       sprintf(&name,"%d",i);
698.
699.       if(i != 0) /* 0 is a special case as it is not in the main box */
700.       {
701.         switch((i-1)%3) /* There is 3 columns of numbers, so doing %3 allows the switch to sort the numbers into the 3 columns, the multiples of 3 are always on the right handed end */
702.            {
703.               case 0: /* as I did (j-1)%3, case 0 actually starts at the multiplies of 3 + 1 */
704.                  x = 100+(level*40);
705.                  y = bottom-10;
706.                  break;
707.               case 1:
708.                  x = 100+(level*40);
709.                  y = bottom-75;
710.                  break;
711.               case 2: /* This is the actually multiples of 3 */
712.                  x = 100+(level*40);
713.                  y = bottom-140;
714.                  level++; /* On the last number in this row, move to the next row */
715.                  break;
716.            }
717.       }else
718.       {
719.          x = left-20;
720.          y = bottom-30;
721.       }
722.
724.    }
725.    loadbet(37,"00",35,1,left-20,top+80); /* It is simpiler to define 00 outside the loop, as 00 = 0 in interger form */
726.
727.    /* These lines define the EVEN and ODD bets */
728.
729.    tempnumbers[0]=2, tempnumbers[1]=4, tempnumbers[2]=6, tempnumbers[3]=8, tempnumbers[4]=10, tempnumbers[5]=12, tempnumbers[6]=14, tempnumbers[7]=16, tempnumbers[8]=18, tempnumbers[9]=20, tempnumbers[10]=22, tempnumbers[11]=24, tempnumbers[12]=26, tempnumbers[13]=28, tempnumbers[14]=30, tempnumbers[15]=32, tempnumbers[16]=34, tempnumbers[17]=36;
731.
732.    tempnumbers[0]=1, tempnumbers[1]=3, tempnumbers[2]=5, tempnumbers[3]=7, tempnumbers[4]=9, tempnumbers[5]=11, tempnumbers[6]=13, tempnumbers[7]=15, tempnumbers[8]=17, tempnumbers[9]=19, tempnumbers[10]=21, tempnumbers[11]=23, tempnumbers[12]=25, tempnumbers[13]=27, tempnumbers[14]=29, tempnumbers[15]=31, tempnumbers[16]=33, tempnumbers[17]=35;
734.
735.    /* These lines define the 3 dozens */
736.
737.    tempnumbers[0]=1, tempnumbers[1]=2, tempnumbers[2]=3, tempnumbers[3]=4, tempnumbers[4]=5, tempnumbers[5]=6, tempnumbers[6]=7, tempnumbers[7]=8, tempnumbers[8]=9, tempnumbers[9]=10, tempnumbers[10]=11, tempnumbers[11]=12;
739.
740.    tempnumbers[0]=13, tempnumbers[1]=14, tempnumbers[2]=15, tempnumbers[3]=16, tempnumbers[4]=17, tempnumbers[5]=18, tempnumbers[6]=19, tempnumbers[7]=20, tempnumbers[8]=21, tempnumbers[9]=22, tempnumbers[10]=23, tempnumbers[11]=24;
742.
743.    tempnumbers[0]=25, tempnumbers[1]=26, tempnumbers[2]=27, tempnumbers[3]=28, tempnumbers[4]=29, tempnumbers[5]=30, tempnumbers[6]=31, tempnumbers[7]=32, tempnumbers[8]=33, tempnumbers[9]=34, tempnumbers[10]=35, tempnumbers[11]=36;
745.
746.    /* These lines define the 3 columns */
747.
748.    tempnumbers[0]=1, tempnumbers[1]=4, tempnumbers[2]=7, tempnumbers[3]=10, tempnumbers[4]=13, tempnumbers[5]=16, tempnumbers[6]=19, tempnumbers[7]=22, tempnumbers[8]=25, tempnumbers[9]=28, tempnumbers[10]=31, tempnumbers[11]=34;
750.
751.    tempnumbers[0]=2, tempnumbers[1]=5, tempnumbers[2]=8, tempnumbers[3]=11, tempnumbers[4]=14, tempnumbers[5]=17, tempnumbers[6]=20, tempnumbers[7]=23, tempnumbers[8]=26, tempnumbers[9]=29, tempnumbers[10]=32, tempnumbers[11]=35;
753.
754.    tempnumbers[0]=3, tempnumbers[1]=6, tempnumbers[2]=9, tempnumbers[3]=12, tempnumbers[4]=15, tempnumbers[5]=18, tempnumbers[6]=21, tempnumbers[7]=24, tempnumbers[8]=27, tempnumbers[9]=30, tempnumbers[10]=33, tempnumbers[11]=36;
756.
757.    /* These lines define the Red and Black bets */
758.
759.    tempnumbers[0]=1, tempnumbers[1]=3, tempnumbers[2]=5, tempnumbers[3]=7, tempnumbers[4]=9, tempnumbers[5]=12, tempnumbers[6]=14, tempnumbers[7]=16, tempnumbers[8]=18, tempnumbers[9]=19, tempnumbers[10]=21, tempnumbers[11]=23, tempnumbers[12]=25, tempnumbers[13]=27, tempnumbers[14]=30, tempnumbers[15]=32, tempnumbers[16]=34, tempnumbers[17]=36;
761.
762.    tempnumbers[0]=2, tempnumbers[1]=4, tempnumbers[2]=6, tempnumbers[3]=8, tempnumbers[4]=10, tempnumbers[5]=11, tempnumbers[6]=13, tempnumbers[7]=15, tempnumbers[8]=17, tempnumbers[9]=20, tempnumbers[10]=22, tempnumbers[11]=24, tempnumbers[12]=26, tempnumbers[13]=28, tempnumbers[14]=29, tempnumbers[15]=31, tempnumbers[16]=33, tempnumbers[17]=35;
764.
765.    /* These lines define the High and Low bets */
766.
767.    tempnumbers[0]=1, tempnumbers[1]=2, tempnumbers[2]=3, tempnumbers[3]=4, tempnumbers[4]=5, tempnumbers[5]=6, tempnumbers[6]=7, tempnumbers[7]=8, tempnumbers[8]=9, tempnumbers[9]=10, tempnumbers[10]=11, tempnumbers[11]=12, tempnumbers[12]=13, tempnumbers[13]=14, tempnumbers[14]=15, tempnumbers[15]=16, tempnumbers[16]=17, tempnumbers[17]=18;
769.
770.    tempnumbers[0]=19, tempnumbers[1]=20, tempnumbers[2]=21, tempnumbers[3]=22, tempnumbers[4]=23, tempnumbers[5]=24, tempnumbers[6]=25, tempnumbers[7]=26, tempnumbers[8]=27, tempnumbers[9]=28, tempnumbers[10]=29, tempnumbers[11]=30, tempnumbers[12]=31, tempnumbers[13]=32, tempnumbers[14]=33, tempnumbers[15]=34, tempnumbers[16]=35, tempnumbers[17]=36;
772.
773.     /* The below loop defines the double bets */
774.
775.    for(i=1,betnum=50,level=0; i<34;i++,betnum++)
776.    {
777.
778.        /* Defines the pair below the number, which can't be done on the last row (ie 34-35-36) hence the for loop stoping at 33 */
779.          tempnumbers[0]=i;
780.          tempnumbers[1]=i+3;
781.
782.          switch((i-1)%3) /* There is 3 columns of numbers, so doing %3 allows the switch to sort the numbers into the 3 columns, the multiples of 3 are always on the right handed end */
783.          {
784.               case 0: /* as I did (i-1)%3, case 0 actually starts at the multiplies of 3 + 1 */
785.                  x = 120+(level*40);
786.                  y = bottom-33;
787.
788.                  sprintf(&name,"%d-%d",i,i+3);
790.                  betnum++; /* betnumber needs to be increased to prevent overwriting the just defined bet */
791.
792.                  x = 100+(level*40);
793.                  y = bottom-65;
794.
795.                  tempnumbers[0]=i;
796.                  tempnumbers[1]=i+1;
797.                  sprintf(&name,"%d-%d",i,i+1);
799.                  break;
800.
801.               case 1:
802.                  x = 120+(level*40);
803.                  y = bottom-98;
804.
805.                  sprintf(&name,"%d-%d",i,i+3);
807.                  betnum++; /* betnumber needs to be increased to prevent overwriting the just defined bet */
808.
809.                  x = 100+(level*40);
810.                  y = bottom-130;
811.
812.                  tempnumbers[0]=i;
813.                  tempnumbers[1]=i+1;
814.                  sprintf(&name,"%d-%d",i,i+1);
816.
817.                  break;
818.               case 2: /* This is the actually multiples of 3 */
819.                  x = 120+(level*40);
820.                  y = bottom-163;
821.
822.                  level++; /* On the last number in this row, move to the next row */
823.                  sprintf(&name,"%d-%d",i,i+3);
825.                  break;
826.          }
827.
828.    }
829.
830.    /* I define these two manually as it is more compact than adding a pile of logic to the above loop */
831.    tempnumbers[0]=34, tempnumbers[1]=35;
833.
834.    tempnumbers[0]=35, tempnumbers[1]=36;
836.
837.
838.    /* The below loop defines all the triple bets */
839.
840.    for(i=1,betnum=107;i<36;i+=3,betnum++)
841.    {
842.
843.       for(j=0;j<3;j++)
844.       {
845.          tempnumbers[j]=i+j;
846.       }
847.
848.       sprintf(&name,"%d-%d-%d",i,i+1,i+2);
849.
851.    }
852.
853.
854.    /* This loop defines all the quad/corner bets */
855.
856.    for(i=1,betnum=119;i<33;i++)
857.    {
858.
859.       if((i%3)!=0)
860.       {
861.          for(j=0;j<4;j++)
862.          {
863.
864.             if(j<2)
865.             {
866.                tempnumbers[j]=i+j;
867.             }else
868.             {
869.                tempnumbers[j]=(i+j+1);
870.             }
871.          }
872.          sprintf(&name,"%d-%d-%d-%d",i,i+1,i+3,i+4);
873.
874.          x=(left+40)+(40*((i-1)/3));
875.          y = bottom - (i%3)*65;
876.
878.
879.          betnum++; /* This is not in the for loop brackets as when i is a multiple of 3 there is not a valid bet to be generated so betnum should not increase */
880.       }
881.
882.    }
883.
884.    /* This loop defines the six number bets */
885.
886.    for(i=1,betnum=141;i<32;i+=3,betnum++)
887.    {
888.
889.
890.       for(j=0;j<6;j++)
891.       {
892.          tempnumbers[j]=i+j;
893.       }
894.          sprintf(&name,"%d-%d-%d-%d-%d-%d",i,i+1,i+2,i+3,i+4,i+5);
895.
896.          x = (left+40) + (40*(i/3));
897.