Skip to content

Instantly share code, notes, and snippets.

@Pharap
Forked from WrinklyWink/CEOV13.ino
Last active April 21, 2018 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pharap/014c31abf538ec6078c1edadb6e09f8e to your computer and use it in GitHub Desktop.
Save Pharap/014c31abf538ec6078c1edadb6e09f8e to your computer and use it in GitHub Desktop.
Reduced the size from (10440/1373) to (9710/1337)
//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