A Stock Exchange Game using IO devices, the 128x128 uLCD, and other components
Dependencies: 4DGL-uLCD-SE SDFileSystem ShiftBrite mbed wave_player
Fork of WavePlayer_HelloWorld by
main.cpp
- Committer:
- RohanIyengar
- Date:
- 2016-11-03
- Revision:
- 2:3585cd51c765
- Parent:
- 1:5b8e223e983d
File content as of revision 2:3585cd51c765:
#include "mbed.h" #include "SDFileSystem.h" #include "wave_player.h" #include "ShiftBrite.h" #include "uLCD_4DGL.h" #include <mpr121.h> // Stock exchange game // Rohan Kumar Iyengar & Sai Sathiesh Rajan // Set up Mbed LEDs DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); // Create the interrupt receiver object on pin 26 InterruptIn interrupt(p26); // Setup the i2c bus on pins 9 and 10 I2C i2c(p9, p10); // Setup the Mpr121: // constructor(i2c object, i2c address of the mpr121) Mpr121 mpr121(&i2c, Mpr121::ADD_VSS); uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin; SPI spi(p11, p12, p13); ShiftBrite myBrite(p15,p16,spi); //latch, enable, spi SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card AnalogOut DACout(p18); wave_player waver(&DACout); int stockPrices [7] = {0,0,0,0,0,0,0}; // array to store trend data for current stock int maxEle = -1; // easily accessible max value of current trend data int minEle = 200; // easily accessible min value of current trend data int gameState = 0; // used to transition between game states int stocksChosen = 0; // number of stocks user has chosen already char* currentName; // current stock name char* chosenName1; // first chosen stock name char* chosenName2; // second chosen stock name int stockGain1 = 0; // first stock's profit/loss int stockGain2 = 0; // second stock's profit/loss int stockNamePos = 0; // Used to generate next stock name int stocksScrolled = 0; // Used to loop around stock names // Function to get next stock whenever user selects / rejects a stock void getNewStock() { // Select stock name first switch (stockNamePos) { case 0: currentName = "Amazon"; break; case 1: currentName = "Google"; break; case 2: currentName = "Microsoft"; break; case 3: currentName = "Apple"; break; case 4: currentName = "IBM"; break; case 5: currentName = "Intel"; break; case 6: currentName = "Cisco"; break; case 7: currentName = "Mathworks"; break; case 8: currentName = "Uber"; break; case 9: currentName = "Facebook"; break; } // Generate trend data for stock srand(time(NULL)); float currentPrice = (rand() % 100) + 50; // initialize price int trend = 0; int range = 20; int bound = 10; stockPrices[0] = currentPrice; maxEle = currentPrice; minEle = currentPrice; // Generate random data for first six days for (int i = 1; i < 6; i++) { float change = rand() % range - bound; currentPrice = currentPrice + change; stockPrices[i] = currentPrice; if (currentPrice > maxEle) { maxEle = currentPrice; } if (currentPrice < minEle) { minEle = currentPrice; } int wildCard = rand() % 10 - 5; if (change >= 0) { trend++; range = 15; bound = 5 + wildCard; } else { trend--; range = 15; bound = 10 + wildCard; } } // Add more random data for 7th day srand(time(NULL)); int finalWildCard = rand() % 8 - 4 + trend; float finalPrice = (1 + (finalWildCard / 34.0)) * currentPrice; stockPrices[6] = finalPrice; // Increment counters to allow next stock retrieval to be smooth stockNamePos = (stockNamePos + 1) % 10; stocksScrolled++; if (stocksScrolled > 10 && stocksChosen != 2) { stocksScrolled = 0; stocksChosen = 0; stockNamePos = rand() % 10; } } // Uses current stock data to print a connected graph of points for that stock void printGraph() { int x = 4; // draw graph axes uLCD.line(2, 20, 2, 126, LGREY); uLCD.line(2, 126, 126, 126, LGREY); float arrayRange = maxEle - minEle; float graphRange = 110 - 30; float scaleFactor = graphRange / arrayRange; int offset = 1; for (int i = 0; i < 5; i++) { int currDist = stockPrices[i] - minEle; int y = (int) (110 - scaleFactor * currDist); int nextDist = stockPrices[i + 1] - minEle; int y2 = (int) (110 - scaleFactor * nextDist); // Draw lines between each pair of points w/ color based on trend if (y2 - y > 0) { uLCD.line(x, y, x + 20, y2, RED); } else if (y2 - y < 0) { uLCD.line(x, y, x + 20, y2, GREEN); } else { uLCD.line(x, y, x + 20, y2, WHITE); } uLCD.filled_circle(x, y, 2, BLUE); uLCD.filled_circle(x + 20, y2, 2, BLUE); // Scale to row, col format of uLCD int point1row = (int) ((x / 7.1) - .5); int point1col = (int) ((y /8.0) - .5); int point2col = (int) ((y2 / 8.0) - .5); int point2row = (int) (((x + 20) / 7.1) - .5); char buf1 [10]; char buf2 [10]; // NEED sprintf because printf on LCD has inexplicable behavior sprintf(buf1, "%d", stockPrices[i]); sprintf(buf2, "%d", stockPrices[i + 1]); uLCD.text_string(buf1, point1row + 1, point1col + 1, FONT_12X16, WHITE); offset*=-1; //uLCD.locate(point2row + offset, point2col + offset); //uLCD.printf("%3i", stockPrices[i+1]); uLCD.text_string(buf2, point2row + 1, point2col + 1, FONT_12X16, WHITE); x+=20; } } // Interrupt when touch sensor is pressed void fallInterrupt() { int key_code=0; int i=0; int value=mpr121.read(0x00); value +=mpr121.read(0x01)<<8; // LED demo mod code inspired by J. Hamblen i=0; // puts key number out to LEDs for demo for (i=0; i<12; i++) { if (((value>>i)&0x01)==1) key_code=i+1; } led4=key_code & 0x01; led3=(key_code>>1) & 0x01; led2=(key_code>>2) & 0x01; led1=(key_code>>3) & 0x01; if (key_code == 9 && stocksChosen < 2) { gameState = 2; } if (key_code == 4 && stocksChosen < 2) { gameState = 1; } } int main() { myBrite.Write(1023, 1023 ,0); bool finished = false; // Do title sequence one time // Welcome Sequence on Game Startup uLCD.cls(); uLCD.text_string("Welcome to the\n Stock Exchange\n Challenge!" , 1, 1, FONT_12X16, GREEN); wait(2); uLCD.cls(); srand(time(NULL)); stockNamePos = rand() % 10; // Title Screen Image uLCD.media_init(); uLCD.set_sector_address(0x003A, 0x7C26); uLCD.display_image(0,15); wait(3); uLCD.cls(); uLCD.text_string("Look at stock \n trends then -" , 1, 1, FONT_12X16, BLUE); uLCD.text_string("Pick two stocks \nthat will make\n you win BIG!", 1, 5, FONT_12X16, GREEN); uLCD.text_string("Press button 8\n to choose the\n current stock", 1, 9, FONT_12X16, RED); uLCD.text_string("Press button 3\n to move onto\n the next stock", 1, 13, FONT_12X16, WHITE); wait(4); uLCD.cls(); uLCD.text_string("Press 3 to begin!", 1, 7, FONT_12X16, GREEN); // Now allow interrupts from touch sensor to trigger interrupt.fall(&fallInterrupt); interrupt.mode(PullUp); while (!finished) { // State to move to next stock if (gameState == 1) { getNewStock(); uLCD.cls(); uLCD.text_string("Stock: ", 1, 1, FONT_12X16, GREEN); uLCD.text_string(currentName, 7, 1, FONT_12X16, GREEN); printGraph(); gameState = 0; } // State when stock is picked if (gameState == 2) { if (stocksChosen == 0) { chosenName1 = currentName; stockGain1 = stockPrices[6] - stockPrices[5]; } else { chosenName2 = currentName; stockGain2 = stockPrices[6] - stockPrices[5]; } stocksChosen++; if (stocksChosen > 1) { finished = true; } else { gameState = 1; } } wait(.5); } // End game summary + statistics int totalGain = stockGain1 + stockGain2; uLCD.cls(); if (totalGain <= 0) { // Print losing image myBrite.Write(1023 ,0,0); uLCD.media_init(); uLCD.set_sector_address(0x003A, 0x7C01); uLCD.display_image(0,22); } else { myBrite.Write(0, 1023, 0); // Print winning image uLCD.media_init(); uLCD.set_sector_address(0x003A, 0x7C57); uLCD.display_image(0,15); } wait(1); uLCD.cls(); // Print picks and statistics uLCD.locate(0,0); if (stockGain1 < 0) { uLCD.color(RED); } else if (stockGain1 > 0) { uLCD.color(GREEN); } else { uLCD.color(WHITE); } uLCD.printf("Pick 1: %s\n\r", chosenName1); uLCD.printf("Stock Gain 1: $%d\n\r\n", stockGain1); if (stockGain2 < 0) { uLCD.color(RED); } else if (stockGain2 > 0) { uLCD.color(GREEN); } else { uLCD.color(WHITE); } uLCD.printf("Pick 2: %s\n\r", chosenName2); uLCD.printf("Stock Gain 2: $%d\n\r\n", stockGain2); if (totalGain < 0) { uLCD.color(RED); } else if (totalGain > 0) { uLCD.color(GREEN); } else { uLCD.color(WHITE); } uLCD.printf("\nTotal Gain: $%d\n\r", totalGain); // Play appropriate winning/losing sound if (totalGain > 0) { FILE* wave_file; wave_file = fopen("/sd/Win.wav", "r"); waver.play(wave_file); fclose(wave_file); } else { FILE* wave_file2; wave_file2 = fopen("/sd/Lose.wav", "r"); waver.play(wave_file2); fclose(wave_file2); } }