-
-
Save Pharap/014c31abf538ec6078c1edadb6e09f8e to your computer and use it in GitHub Desktop.
Reduced the size from (10440/1373) to (9710/1337)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//A brain enhancer to conquer random | |
//special thanks to | |
#include <Arduboy2.h> | |
//#include "autopowerdown.h" | |
Arduboy2 arduboy; | |
enum class GameState : uint8_t | |
{ | |
MainMenu, | |
Gameplay, | |
Setup, | |
Reset, | |
}; | |
using FlashString = const __FlashStringHelper *; | |
FlashString asFlashString(const char * string) | |
{ | |
return reinterpret_cast<FlashString>(string); | |
} | |
FlashString lookupString(const char * const * lookupEntry) | |
{ | |
return asFlashString(pgm_read_word(lookupEntry)); | |
} | |
//computechallenge variables | |
int LNpairmin = 0; | |
int LNpairmax = 8; | |
bool v, e, y; | |
const char vowel[] = "AEIOUAEIOUAEIOUAEIOUYaeiouaeiouaeiouaeiouy"; | |
const char consonant[] = "BCDFGHJKLMNPQRSTVWXZYbCdfghjklmnpqrstvwxzy"; | |
constexpr const size_t VCL = sizeof(vowel) / sizeof(vowel[0]); | |
static_assert(sizeof(vowel) == sizeof(consonant), ""); | |
const char even[] PROGMEM = "02468"; | |
constexpr const size_t sizeOfEven = sizeof(even) / sizeof(even[0]); | |
const char odd[] PROGMEM = "13579"; | |
constexpr const size_t sizeOfOdd = sizeof(odd) / sizeof(odd[0]); | |
char getEven(uint8_t index) | |
{ | |
return static_cast<char>(pgm_read_byte(&even[index])); | |
} | |
char getRandomEven(void) | |
{ | |
return getEven(random() % sizeOfEven); | |
} | |
char getOdd(uint8_t index) | |
{ | |
return static_cast<char>(pgm_read_byte(&odd[index])); | |
} | |
char getRandomOdd(void) | |
{ | |
return getOdd(random() % sizeOfOdd); | |
} | |
//computekm | |
//int computeanswerkm; | |
uint8_t Sarr[] = {0, 1, 2, 3}; | |
const size_t Ssize = sizeof(Sarr)/ sizeof(Sarr[0]); | |
uint8_t Darr[] = {0, 1, 2, 3}; | |
const size_t Dsize = sizeof(Darr)/ sizeof(Darr[0]); | |
const char label0[] PROGMEM = "eV"; | |
const char label1[] PROGMEM = "eC"; | |
const char label2[] PROGMEM = "oV"; | |
const char label3[] PROGMEM = "oC"; | |
const char * const labels[] PROGMEM = | |
{ | |
label0, | |
label1, | |
label2, | |
label3, | |
}; | |
//swaptool | |
template< typename T > void swap(T & a, T & b) | |
{ | |
T temp = a; | |
a = b; | |
b = temp; | |
} | |
template< typename T, size_t size > void swap(T (&a)[size], T (&b)[size]) | |
{ | |
for (size_t i = 0; i < size; ++i) | |
{ | |
swap(Darr[i], Sarr[i]); | |
} | |
} | |
// This algorithm is known as the Fisher-Yates shuffle | |
template< typename T, size_t size > void randomizeArray(T (&array)[size]) | |
{ | |
// Start from the last element and swap one by one. We don't | |
// need to run for the first element that's why i > 0 | |
for (size_t i = (size - 1); i > 0; i--) | |
{ | |
// Pick a random index from 0 to i | |
size_t j = random() % (i + 1); | |
// Swap arr[i] with the element at random index | |
swap(array[i], array[j]); | |
} | |
} | |
template< typename T > void randomizeArray(T (&array)[0]) | |
{ | |
} | |
//user variables | |
uint8_t led[2] = { RGB_OFF, RGB_OFF }; | |
int Qright = 0; | |
int Qwrong = 0; | |
int Tanswered = 0; | |
int ratio = Qright/ Qwrong; | |
int Qlooked = 0; | |
//other variables | |
bool firstpress = false; | |
bool buttonfree = true; | |
bool showbutton = false; | |
char challenge[2]; | |
GameState gameState = GameState::MainMenu; | |
void computechallenge() | |
{ | |
uint8_t LNpair = random(LNpairmin, LNpairmax); | |
switch(LNpair) | |
{ | |
case 0: | |
{ | |
v = true; e = true; | |
uint8_t Vnu = random(VCL); | |
y = (Vnu == 20 || Vnu == 41); | |
challenge[0] = vowel[Vnu]; | |
challenge[1] = getRandomEven(); | |
break; | |
} | |
case 1: | |
{ | |
v = true; e = false; | |
uint8_t Vnu = random(VCL); | |
y = (Vnu == 20 || Vnu == 41); | |
challenge[0] = vowel[Vnu]; | |
challenge[1] = getRandomOdd(); | |
break; | |
} | |
case 2: | |
{ | |
v = false; e = true; | |
uint8_t Cnu = random(VCL); | |
y = (Cnu == 20 || Cnu == 41); | |
challenge[0] = consonant[Cnu]; | |
challenge[1] = getRandomEven(); | |
break; | |
} | |
case 3: | |
{ | |
v = false; e = false; | |
uint8_t Cnu = random(VCL); | |
y = (Cnu == 20 || Cnu == 41); | |
challenge[0] = consonant[Cnu]; | |
challenge[1] = getRandomOdd(); | |
break; | |
} | |
case 4: | |
{ | |
e = true; v = true; | |
uint8_t Vnu = random(VCL); | |
y = (Vnu == 20 || Vnu == 41); | |
challenge[0] = getRandomEven(); | |
challenge[1] = vowel[Vnu]; | |
break; | |
} | |
case 5: | |
{ | |
e = true; v = false; | |
uint8_t Cnu = random(VCL); | |
y = (Cnu == 20 || Cnu == 41); | |
challenge[0] = getRandomEven(); | |
challenge[1] = consonant[Cnu]; | |
break; | |
} | |
case 6: | |
{ | |
e = false; v = true; | |
uint8_t Vnu = random(VCL); | |
y = (Vnu == 20 || Vnu == 41); | |
challenge[0] = getRandomOdd(); | |
challenge[1] = vowel[Vnu]; | |
break; | |
} | |
case 7: | |
{ | |
e = false; v = false; | |
uint8_t Cnu = random(VCL); | |
y = (Cnu == 20 || Cnu == 41); | |
challenge[0] = getRandomOdd(); | |
challenge[1] = consonant[Cnu]; | |
break; | |
} | |
} | |
} | |
bool isCorrect(uint8_t c) | |
{ | |
switch(c) | |
{ | |
case 0: //ev | |
return (e && (v || y)); | |
case 1: //ec | |
return (e && (!v || y)); | |
case 2: //ov | |
return (!e && (v || y)); | |
case 3: //oc | |
return (!e && (!v || y)); | |
default: | |
return false; | |
} | |
} | |
void submitAnswer(uint8_t c) | |
{ | |
if (isCorrect(c)) | |
{ | |
arduboy.digitalWriteRGB(GREEN_LED, led[1]); | |
++Qright; | |
} | |
else | |
{ | |
arduboy.digitalWriteRGB(RED_LED, led[0]); | |
++Qwrong; | |
} | |
++Tanswered; | |
computechallenge(); | |
randomizeArray(Darr); | |
} | |
// Main Menu | |
const char option0[] PROGMEM = "Start/Continue"; | |
const char option1[] PROGMEM = "Setup"; | |
const char option2[] PROGMEM = "Reset"; | |
const char * const options[] PROGMEM = | |
{ | |
option0, | |
option1, | |
option2, | |
}; | |
const uint8_t optionCount = sizeof(options) / sizeof(options[0]); | |
const uint8_t maxIndex = optionCount - 1; | |
uint8_t selectedIndex; | |
void setup() | |
{ | |
arduboy.boot(); | |
arduboy.flashlight(); | |
arduboy.setFrameRate(20); | |
} | |
void updateMainMenu(void) | |
{ | |
arduboy.setCursor(52,0);arduboy.print("CEOV"); | |
if(arduboy.justPressed(UP_BUTTON)) | |
{ | |
if(selectedIndex > 0) | |
--selectedIndex; | |
} | |
if(arduboy.justPressed(DOWN_BUTTON)) | |
{ | |
if(selectedIndex < maxIndex) | |
++selectedIndex; | |
} | |
arduboy.setCursor(0, 32); | |
// Loop through all options | |
for(uint8_t i = 0; i < optionCount; ++i) | |
{ | |
// If the current option is the selected option; | |
if(i == selectedIndex) | |
{ | |
// Draw an arrow | |
arduboy.print(F("> ")); | |
} | |
else | |
{ | |
// Otherwise just indent | |
arduboy.print(F(" ")); | |
} | |
// Print the string in the array | |
// This is quite complicated if you don't know about | |
// pointers and casting. | |
arduboy.println(asFlashString(pgm_read_word(&options[i]))); | |
} | |
if(!firstpress) | |
{ | |
if(arduboy.pressed(UP_BUTTON) || arduboy.pressed(LEFT_BUTTON) || arduboy.pressed(RIGHT_BUTTON) || arduboy.pressed(DOWN_BUTTON) || arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON)) | |
{ | |
arduboy.initRandomSeed(); | |
firstpress = true; | |
} | |
} | |
if(buttonfree && arduboy.pressed(A_BUTTON)) | |
{ | |
computechallenge(); | |
randomizeArray(Darr); | |
buttonfree = false; | |
switch(selectedIndex) | |
{ | |
case 0: | |
gameState = GameState::Gameplay; | |
break; | |
case 1: | |
gameState = GameState::Setup; | |
break; | |
case 3: | |
Qright = 0; | |
Qwrong = 0; | |
Tanswered = 0; | |
Qlooked = 0; | |
break; | |
} | |
} | |
} | |
void updateGameplay(void) | |
{ | |
arduboy.drawRoundRect(53, 3, 21, 18, WHITE); //up | |
arduboy.setCursor(56, 6); | |
arduboy.print(lookupString(&labels[Darr[0]])); | |
arduboy.drawRoundRect(31, 23, 21, 18, WHITE); //left | |
arduboy.setCursor(34, 26); | |
arduboy.print(lookupString(&labels[Darr[1]])); | |
arduboy.drawRoundRect(75, 23, 21, 18, WHITE); //right | |
arduboy.setCursor(78, 26); | |
arduboy.print(lookupString(&labels[Darr[2]])); | |
arduboy.drawRoundRect(53, 43, 21, 18, WHITE); //down | |
arduboy.setCursor(56, 46); | |
arduboy.print(lookupString(&labels[Darr[3]])); | |
arduboy.setCursor(58, 28); | |
arduboy.print(challenge[0]); | |
arduboy.print(challenge[1]); | |
if (arduboy.pressed(A_BUTTON)) | |
{ | |
arduboy.setCursor(0, 0); | |
arduboy.print(Qright); | |
arduboy.setCursor(0,28); | |
arduboy.print(Qright/ Qwrong); | |
arduboy.setCursor(0, 57); | |
arduboy.print(Qwrong); | |
//arduboy.setCursor(100,57); | |
//arduboy.print(Tanswered); | |
if(arduboy.pressed(B_BUTTON) && buttonfree) | |
{ | |
buttonfree = false; | |
gameState = GameState::MainMenu; | |
} | |
} | |
if(buttonfree) | |
{ | |
if(arduboy.pressed(UP_BUTTON)) | |
{ | |
buttonfree = false; | |
submitAnswer (Darr[0]); | |
} | |
if(arduboy.pressed(LEFT_BUTTON)) | |
{ | |
buttonfree = false; | |
submitAnswer (Darr[1]); | |
} | |
if(arduboy.pressed(RIGHT_BUTTON)) | |
{ | |
buttonfree = false; | |
submitAnswer (Darr[2]); | |
} | |
if(arduboy.pressed(DOWN_BUTTON)) | |
{ | |
buttonfree = false; | |
submitAnswer (Darr[3]); | |
} | |
} | |
} | |
void updateSetup(void) | |
{ | |
arduboy.drawRoundRect(43, 3, 21, 18, WHITE); //left box | |
arduboy.drawRoundRect(65, 3, 21, 18, WHITE); //right boz | |
if(arduboy.pressed(A_BUTTON)) | |
{ | |
showbutton = true; | |
if(arduboy.pressed(B_BUTTON) && buttonfree) | |
{ | |
buttonfree = false; | |
gameState = GameState::MainMenu; | |
} | |
} | |
if(arduboy.notPressed(A_BUTTON)) | |
{ | |
showbutton = false; | |
} | |
} | |
void updateReset(void) | |
{ | |
if(buttonfree && arduboy.pressed(A_BUTTON)) | |
{ | |
buttonfree = false; | |
gameState = GameState::MainMenu; | |
} | |
} | |
void loop() | |
{ | |
//autoPowerDown(7); | |
//Prevent the Arduboy from running too fast | |
if(!arduboy.nextFrame()) return; | |
arduboy.pollButtons(); | |
arduboy.clear(); | |
switch(gameState) | |
{ | |
case GameState::MainMenu: | |
updateMainMenu(); | |
break; | |
case GameState::Gameplay: | |
updateGameplay(); | |
break; | |
case GameState::Setup: | |
updateSetup(); | |
break; | |
case GameState::Reset: | |
updateReset(); | |
break; | |
} | |
if (!buttonfree) | |
{ | |
if (arduboy.notPressed(UP_BUTTON) && arduboy.notPressed(DOWN_BUTTON) && arduboy.notPressed(LEFT_BUTTON) && arduboy.notPressed(RIGHT_BUTTON) && arduboy.notPressed(A_BUTTON) && arduboy.notPressed(B_BUTTON)) | |
{ | |
buttonfree = true; | |
} | |
} | |
arduboy.display(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment