Rohan Iyengar / Mbed 2 deprecated Stock_Exchange_Game

Dependencies:   4DGL-uLCD-SE SDFileSystem ShiftBrite mbed wave_player

Fork of WavePlayer_HelloWorld by jim hamblen

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "SDFileSystem.h"
00003 #include "wave_player.h"
00004 #include "ShiftBrite.h"
00005 #include "uLCD_4DGL.h"
00006 #include <mpr121.h>
00007 
00008 // Stock exchange game
00009 // Rohan Kumar Iyengar & Sai Sathiesh Rajan
00010 
00011 // Set up Mbed LEDs
00012 DigitalOut led1(LED1);
00013 DigitalOut led2(LED2);
00014 DigitalOut led3(LED3);
00015 DigitalOut led4(LED4);
00016 
00017 // Create the interrupt receiver object on pin 26
00018 InterruptIn interrupt(p26);
00019 
00020 // Setup the i2c bus on pins 9 and 10
00021 I2C i2c(p9, p10);
00022 
00023 // Setup the Mpr121:
00024 // constructor(i2c object, i2c address of the mpr121)
00025 Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
00026 
00027 uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
00028 
00029 SPI spi(p11, p12, p13);
00030 
00031 ShiftBrite myBrite(p15,p16,spi); //latch, enable, spi
00032 
00033 SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
00034 
00035 AnalogOut DACout(p18);
00036 
00037 wave_player waver(&DACout);
00038 
00039 int stockPrices [7] = {0,0,0,0,0,0,0}; // array to store trend data for current stock
00040 int maxEle = -1; // easily accessible max value of current trend data
00041 int minEle = 200; // easily accessible min value of current trend data
00042 int gameState = 0; // used to transition between game states
00043 int stocksChosen = 0; // number of stocks user has chosen already
00044 char* currentName; // current stock name
00045 char* chosenName1; // first chosen stock name
00046 char* chosenName2; // second chosen stock name
00047 int stockGain1 = 0; // first stock's profit/loss
00048 int stockGain2 = 0; // second stock's profit/loss
00049 int stockNamePos = 0; // Used to generate next stock name
00050 int stocksScrolled = 0; // Used to loop around stock names
00051 
00052 // Function to get next stock whenever user selects / rejects a stock
00053 void getNewStock()
00054 {
00055     // Select stock name first
00056     switch (stockNamePos) {
00057     
00058     case 0:
00059         currentName = "Amazon";
00060         break;
00061     case 1:
00062         currentName = "Google";
00063         break;
00064     case 2:
00065         currentName = "Microsoft";
00066         break;
00067     case 3:
00068         currentName = "Apple";
00069         break;
00070     case 4:
00071         currentName = "IBM";
00072         break;
00073     case 5:
00074         currentName = "Intel";
00075         break;
00076     case 6:
00077         currentName = "Cisco";
00078         break;
00079     case 7:
00080         currentName = "Mathworks";
00081         break;
00082     case 8:
00083         currentName = "Uber";
00084         break;
00085     case 9:
00086         currentName = "Facebook";
00087         break;
00088     }
00089     
00090     // Generate trend data for stock
00091     srand(time(NULL));
00092     float currentPrice = (rand() % 100) + 50; // initialize price
00093     int trend = 0;
00094     int range = 20;
00095     int bound = 10;
00096     stockPrices[0] = currentPrice;
00097     maxEle = currentPrice;
00098     minEle = currentPrice;
00099     // Generate random data for first six days
00100     for (int i = 1; i < 6; i++) {
00101         float change = rand() % range - bound;
00102         currentPrice = currentPrice + change;
00103         stockPrices[i] = currentPrice;
00104         if (currentPrice > maxEle) {
00105             maxEle = currentPrice;
00106         }
00107         if (currentPrice < minEle) {
00108             minEle = currentPrice;
00109         }
00110         int wildCard = rand() % 10 - 5;
00111         if (change >= 0) {
00112             trend++;
00113             range = 15;
00114             bound = 5 + wildCard;
00115         } else {
00116             trend--;
00117             range = 15;
00118             bound = 10 + wildCard;
00119         }
00120     }
00121     
00122     // Add more random data for 7th day
00123     srand(time(NULL));
00124     int finalWildCard = rand() % 8 - 4 + trend; 
00125     float finalPrice = (1 + (finalWildCard / 34.0)) * currentPrice;
00126     stockPrices[6] = finalPrice;
00127     
00128     // Increment counters to allow next stock retrieval to be smooth
00129     stockNamePos = (stockNamePos + 1) % 10;
00130     stocksScrolled++; 
00131     if (stocksScrolled > 10 && stocksChosen != 2) {
00132         stocksScrolled = 0;
00133         stocksChosen = 0;
00134         stockNamePos = rand() % 10;
00135     }
00136 }
00137 
00138 // Uses current stock data to print a connected graph of points for that stock
00139 void printGraph() {
00140     int x = 4;
00141     // draw graph axes
00142     uLCD.line(2, 20, 2, 126, LGREY);
00143     uLCD.line(2, 126, 126, 126, LGREY);
00144     float arrayRange = maxEle - minEle;
00145     float graphRange = 110 - 30; 
00146     float scaleFactor = graphRange / arrayRange;
00147     int offset = 1;
00148     for (int i = 0; i < 5; i++) {
00149         int currDist = stockPrices[i] - minEle;
00150         int y = (int) (110 - scaleFactor * currDist);
00151         int nextDist = stockPrices[i + 1] - minEle;
00152         int y2 = (int) (110 - scaleFactor * nextDist);
00153         // Draw lines between each pair of points w/ color based on trend
00154         if (y2 - y > 0) {
00155             uLCD.line(x, y, x + 20, y2, RED);
00156         } else if (y2 - y < 0) {
00157             uLCD.line(x, y, x + 20, y2, GREEN);
00158         } else {
00159             uLCD.line(x, y, x + 20, y2, WHITE);
00160         }
00161         uLCD.filled_circle(x, y, 2, BLUE);
00162         uLCD.filled_circle(x + 20, y2, 2, BLUE);
00163         // Scale to row, col format of uLCD
00164         int point1row = (int) ((x / 7.1) - .5);
00165         int point1col = (int) ((y /8.0) - .5);
00166         int point2col = (int) ((y2 / 8.0) - .5);
00167         int point2row = (int) (((x + 20) / 7.1) - .5);
00168         char buf1 [10];
00169         char buf2 [10];
00170         // NEED sprintf because printf on LCD has inexplicable behavior
00171         sprintf(buf1, "%d", stockPrices[i]);
00172         sprintf(buf2, "%d", stockPrices[i + 1]);
00173         uLCD.text_string(buf1, point1row + 1, point1col + 1, FONT_12X16, WHITE);
00174         offset*=-1;
00175         //uLCD.locate(point2row + offset, point2col + offset);
00176         //uLCD.printf("%3i", stockPrices[i+1]);
00177         uLCD.text_string(buf2, point2row + 1, point2col + 1, FONT_12X16, WHITE);
00178         x+=20;
00179     }
00180 }
00181 
00182 // Interrupt when touch sensor is pressed
00183 void fallInterrupt() {
00184     int key_code=0;
00185     int i=0;
00186     int value=mpr121.read(0x00);
00187     value +=mpr121.read(0x01)<<8;
00188     // LED demo mod code inspired by J. Hamblen
00189     i=0;
00190     // puts key number out to LEDs for demo
00191     for (i=0; i<12; i++) {
00192         if (((value>>i)&0x01)==1) key_code=i+1;
00193         }
00194     led4=key_code & 0x01;
00195     led3=(key_code>>1) & 0x01;
00196     led2=(key_code>>2) & 0x01;
00197     led1=(key_code>>3) & 0x01;
00198     if (key_code == 9 && stocksChosen < 2) {
00199         gameState = 2;
00200     }
00201     if (key_code == 4 && stocksChosen < 2) {
00202         gameState = 1;
00203     }
00204 }
00205 
00206 int main()
00207 {
00208     myBrite.Write(1023, 1023 ,0);
00209     bool finished = false;
00210     // Do title sequence one time
00211     // Welcome Sequence on Game Startup
00212     uLCD.cls();
00213     uLCD.text_string("Welcome to the\n Stock Exchange\n Challenge!" , 1, 1, FONT_12X16, GREEN);
00214     wait(2);
00215     uLCD.cls();
00216     srand(time(NULL));
00217     stockNamePos = rand() % 10;
00218     // Title Screen Image
00219     uLCD.media_init();
00220     uLCD.set_sector_address(0x003A, 0x7C26);
00221     uLCD.display_image(0,15); 
00222     wait(3);
00223     uLCD.cls();
00224     uLCD.text_string("Look at stock \n trends then -" , 1, 1, FONT_12X16, BLUE);
00225     uLCD.text_string("Pick two stocks \nthat will make\n you win BIG!", 1, 5, FONT_12X16, GREEN);
00226     uLCD.text_string("Press button 8\n to choose the\n current stock", 1, 9, FONT_12X16, RED);
00227     uLCD.text_string("Press button 3\n to move onto\n the next stock", 1, 13, FONT_12X16, WHITE);
00228     wait(4);
00229     uLCD.cls();
00230     uLCD.text_string("Press 3 to begin!", 1, 7, FONT_12X16, GREEN);
00231     // Now allow interrupts from touch sensor to trigger
00232     interrupt.fall(&fallInterrupt);
00233     interrupt.mode(PullUp);
00234     
00235     while (!finished) {
00236         // State to move to next stock
00237         if (gameState == 1) {
00238             getNewStock();
00239             uLCD.cls();
00240             uLCD.text_string("Stock: ", 1, 1, FONT_12X16, GREEN);
00241             uLCD.text_string(currentName, 7, 1, FONT_12X16, GREEN);
00242             printGraph();
00243             gameState = 0;
00244         }
00245         // State when stock is picked
00246         if (gameState == 2) {
00247             if (stocksChosen == 0) {
00248                 chosenName1 = currentName;
00249                 stockGain1 = stockPrices[6] - stockPrices[5];
00250             } else {
00251                 chosenName2 = currentName;
00252                 stockGain2 = stockPrices[6] - stockPrices[5];
00253             }
00254             stocksChosen++;
00255             if (stocksChosen > 1) {
00256                 finished = true;
00257             } else {
00258                 gameState = 1;
00259             }
00260         }
00261         wait(.5);
00262     }
00263     // End game summary + statistics
00264     int totalGain = stockGain1 + stockGain2;
00265     uLCD.cls();
00266     if (totalGain <= 0) {
00267         // Print losing image
00268         myBrite.Write(1023 ,0,0);
00269         uLCD.media_init();
00270         uLCD.set_sector_address(0x003A, 0x7C01);
00271         uLCD.display_image(0,22); 
00272     } else {
00273         myBrite.Write(0, 1023, 0);
00274         // Print winning image
00275         uLCD.media_init();
00276         uLCD.set_sector_address(0x003A, 0x7C57);
00277         uLCD.display_image(0,15); 
00278     }
00279     wait(1);
00280     uLCD.cls();
00281     // Print picks and statistics
00282     uLCD.locate(0,0);
00283     if (stockGain1 < 0) {
00284         uLCD.color(RED);
00285     } else if (stockGain1 > 0) {
00286         uLCD.color(GREEN);
00287     } else {
00288         uLCD.color(WHITE);
00289     }
00290     uLCD.printf("Pick 1: %s\n\r", chosenName1);
00291     uLCD.printf("Stock Gain 1: $%d\n\r\n", stockGain1);
00292     if (stockGain2 < 0) {
00293         uLCD.color(RED);
00294     } else if (stockGain2 > 0) {
00295         uLCD.color(GREEN);
00296     } else {
00297         uLCD.color(WHITE);
00298     }
00299     uLCD.printf("Pick 2: %s\n\r", chosenName2);
00300     uLCD.printf("Stock Gain 2: $%d\n\r\n", stockGain2);
00301     if (totalGain < 0) {
00302         uLCD.color(RED);
00303     } else if (totalGain > 0) {
00304         uLCD.color(GREEN);
00305     } else {
00306         uLCD.color(WHITE);
00307     }
00308     uLCD.printf("\nTotal Gain: $%d\n\r", totalGain);
00309     
00310     // Play appropriate winning/losing sound
00311     if (totalGain > 0) {
00312         FILE* wave_file;
00313         wave_file = fopen("/sd/Win.wav", "r");
00314         waver.play(wave_file);
00315         fclose(wave_file);
00316     } else {
00317         FILE* wave_file2;
00318         wave_file2 = fopen("/sd/Lose.wav", "r");
00319         waver.play(wave_file2);
00320         fclose(wave_file2);
00321     }
00322 }