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
Diff: main.cpp
- Revision:
- 2:3585cd51c765
- Parent:
- 1:5b8e223e983d
--- a/main.cpp Thu Jan 24 02:59:05 2013 +0000 +++ b/main.cpp Thu Nov 03 19:35:44 2016 +0000 @@ -1,8 +1,34 @@ - #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 @@ -10,11 +36,287 @@ 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() { - FILE *wave_file; - printf("\n\n\nHello, wave world!\n"); - wave_file=fopen("/sd/sample.wav","r"); - waver.play(wave_file); - fclose(wave_file); + 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); + } } \ No newline at end of file