Hello guys, i learn c++ for arduboy and i have an exercise which consist to :
Make a menu ( it’s done , i will give you my code at the end)
And now ( this is why i search a solution) In this menu ( 3 choices) one of them is called “Vigenere” , when we choose it , its basically Vigenere Cipher that i have to apply inside this menu.
For those who don’t know how its work : we choose a word like 10 words max. and we write a key that encrypted our word and finally our encrypted word is diplayed.
This is the code that i did :
#include <Arduboy2.h>
// This is an enum class, similar to enums from C but with improved 'type safety'
enum class GameState : uint8_t
{
Hello,
Menu,
SinglePlayer,
MultiPlayer,
Options
};
Arduboy2 arduboy;
GameState gameState = GameState::Hello;
void changeGameState(GameState newGameState)
{
gameState = newGameState;
}
void setup()
{
arduboy.begin();
}
void loop()
{
if (!arduboy.nextFrame())
return;
arduboy.pollButtons();
update();
arduboy.clear();
draw();
arduboy.display();
}
void update()
{
switch(gameState)
{
case GameState::Hello:
updateHello();
break;
case GameState::Menu:
updateMenu();
break;
case GameState::SinglePlayer:
//updateSinglePlayer();
break;
case GameState::MultiPlayer:
//updateMultiPlayer();
break;
case GameState::Options:
//updateOptions();
break;
}
}
void draw()
{
switch(gameState)
{
case GameState::Menu:
drawMenu();
break;
case GameState::Hello:
drawHello();
break;
case GameState::SinglePlayer:
//drawSinglePlayer();
break;
case GameState::MultiPlayer:
//drawMultiPlayer();
break;
case GameState::Options:
//drawOptions();
break;
}
}
unsigned long helloTimer = 0;
void updateHello()
{
constexpr unsigned long millisecondsPerSecond = 1000;
constexpr unsigned long sixSeconds = (6 * millisecondsPerSecond);
if(helloTimer == 0)
{
helloTimer = millis();
}
else
{
unsigned long now = millis();
if((now - helloTimer) >= sixSeconds)
{
helloTimer = 0;
changeGameState(GameState::Menu);
}
}
}
void drawHello()
{
arduboy.print(F("Hello"));
}
// The index of the currently selected menu item
uint8_t cursorIndex = 2;
// How many items the menu has
constexpr uint8_t menuItems = 5;
constexpr uint8_t firstMenuItem = 2;
constexpr uint8_t lastMenuItem = (menuItems - 1);
void updateMenu()
{
if (arduboy.justPressed(DOWN_BUTTON))
{
if(cursorIndex < lastMenuItem)
++cursorIndex;
else
cursorIndex = firstMenuItem;
}
if (arduboy.justPressed(UP_BUTTON))
{
if(cursorIndex > firstMenuItem)
--cursorIndex;
else
cursorIndex = lastMenuItem;
}
if (arduboy.justPressed(B_BUTTON))
{
// Single player
switch(cursorIndex)
{
case 0:
changeGameState(GameState::SinglePlayer);
break;
case 1:
changeGameState(GameState::MultiPlayer);
break;
case 2:
changeGameState(GameState::Options);
break;
}
}
}
void drawMenu()
{
// Layout helper constants
constexpr uint8_t selectorPositionX = 2;
constexpr uint8_t menuPositionX = (selectorPositionX + 8);
constexpr uint8_t menuPositionY = 4;
constexpr uint8_t menuPadding = 8;
// Draw menu
arduboy.setCursor(menuPositionX, menuPositionY + (menuPadding * 0));
arduboy.print(F("CODAGE"));
arduboy.setCursor(menuPositionX, menuPositionY + (menuPadding * 2));
arduboy.print(F("VIGENERE"));
arduboy.setCursor(menuPositionX, menuPositionY + (menuPadding * 3));
arduboy.print(F("OPTION 2"));
arduboy.setCursor(menuPositionX, menuPositionY + (menuPadding * 4));
arduboy.print(F("OPTION 3"));
// Draw cursor
arduboy.setCursor(selectorPositionX, menuPositionY + (menuPadding * cursorIndex));
arduboy.print('>');
}
hello, I may have been poorly expressed,
what I asked it was to complete my already existing program with the menu “Vigenere” which should allow to encode a desired word with a key that is entered manually too. And so give us the code word.
That’s why I post this (maybe badly defined category, sorry: /)
I need help with writing the Vigenère cipher coder and the input system, i need help with everything ( the entire code). Because i don’t know how to do
I’ve written an (untested) implementation of the Vigenère cipher.
It’s relatively complex, but hopefully my comments explain what’s going on clearly enough:
The Arduboy is usually more memory constrained than constrained by processing power, so instead of using a lookup table I’ve based this implementation on the algebraic interpretation of the Vigenère cipher.
Basically:
The letters A-Z are mapped to the numbers 0-25 (called an ‘index’)
Then a Caesar cipher operation is performed to shift the index along
(Specifically the operation is index + shift % 26)
The shift is derived from a letter in the keyword
Then the shifted index is converted back into a letter
And the rest is just some stuff to:
Handle characters that can’t be converted (e.g. '_', ' ', '.')
They are left in the output unchanged
Handle capitals and lowercase letters
(I.e. so the casing of the letters is retained. E.g. “Hello World” encoded with a key of “Arduboy” becomes “Hvofp Kmrcg”)
All you need to do is to combine this code with the text entry code provided by @filmote and that’s 90% of the job done.
Good evening, I really did not know how to solve this problem so thank you! I will normally be able to continue this program with the information given. Could you just fix the few errors when compiling the program?
Anyway thank you very much
I am not sure why as directly above line 38 is the CharacterCase declaration:
enum class CharacterCase : uint8_t
{
Invalid,
Uppercase,
Lowercase,
};
// Returns true if the character can be encoded
constexpr CharacterCase getCharacterCase(char c)
{
Did you copy everything across or were you selective?
I think I might know what the problem is, try it again now:
If it still doesn’t work then I’m going to need more information.
(The full error message, exactly which line in which file, what the rest of the code currently looks like etc.)