Decrypt

Decrypting a puzzle involves lots of trial and error and erasing. It would be nice to:
  • have a tool that automates all the substituting
  • say, "Show me all the e's" (like the game show Wheel of Fortune)
  • say, "I give up. What does the 'x' stand for?"

Goal: read plain text quote or verse from a file, encode it, and implement a game that provides 3 ways to decrypt:

  • "xy" (substitute x with y)
  • "=x" (where are all the decoded x's?, comparable to Wheel of Fortune guessing)
  • "?x" (give decode of all encoded x's)

 - -- --- ------- -- --- ------, -------
 v br zfl bxebrao fn lea kfxcai, yambpxa

 -- -- --- ----- -- --- --- --- ---------
 vl vx lea cfqag fn kfo nfg lea xbihblvfz

 -- -------- --- --------; ----- --- --- ---,
 fn ahagjfza qef yaivahax; nvgxl nfg lea saq,

 ---- --- --- -------.   -- ------ 1:16
 leaz nfg lea kazlvia.   -- gfrbzx 1:16

 FromTo ("?x" give decode for x?  "=e" where are all e's?): ?v 


 i -- --- ------- -- --- ------, -------
 v br zfl bxebrao fn lea kfxcai, yambpxa

 i- i- --- ----- -- --- --- --- ------i--
 vl vx lea cfqag fn kfo nfg lea xbihblvfz

 -- -------- --- ---i----; -i--- --- --- ---,
 fn ahagjfza qef yaivahax; nvgxl nfg lea saq,

 ---- --- --- ----i--.   -- ------ 1:16
 leaz nfg lea kazlvia.   -- gfrbzx 1:16

 FromTo ("?x" give decode for x?  "=e" where are all e's?): =e


 i -- --- -----e- -- --e ----e-, -e----e
 v br zfl bxebrao fn lea kfxcai, yambpxa

 i- i- --e ---e- -- --- --- --e ------i--
 vl vx lea cfqag fn kfo nfg lea xbihblvfz

 -- e-e----e --- -e-ie-e-; -i--- --- --e -e-,
 fn ahagjfza qef yaivahax; nvgxl nfg lea saq,

 --e- --- --e -e--i-e.   -- ------ 1:16
 leaz nfg lea kazlvia.   -- gfrbzx 1:16

 FromTo ("?x" give decode for x?  "=e" where are all e's?): xs


 i -- --- -s---e- -- --e --s-e-, -e---se
 v br zfl bxebrao fn lea kfxcai, yambpxa

 i- is --e ---e- -- --- --- --e s-----i--
 vl vx lea cfqag fn kfo nfg lea xbihblvfz

 -- e-e----e --- -e-ie-es; -i-s- --- --e -e-,
 fn ahagjfza qef yaivahax; nvgxl nfg lea saq,

 --e- --- --e -e--i-e.   -- -----s 1:16
 leaz nfg lea kazlvia.   -- gfrbzx 1:16

  1. Randomize the decoded-to-encoded array
  2. Initialize the encoded-to-decoded array
  3. Read the 4 lines to encode from "decrypt.txt"
    1. Use decoded-to-encoded to initialize encoded_lines
    2. Assign spaces and punctuation to decoded_lines
  4. while (true)
    1. display
    2. accept input
    3. process requests
      • "xy" (substitute x with y)
      • "=x" (where are all the decoded x's?, comparable to Wheel of Fortune guessing)
      • "?x" (give decode of all encoded x's)

No "?x" command

#include <iostream>    // no "?x" command
#include <string>
#include <ctime>
#include <fstream>
using namespace std;

string encoded_lines[4], decoded_lines[4], str;
string encoded = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456abcdefghijklmnopqrstuvwxyz";
                 //        1         2         3         4         5         6         7         8         9      97                     122
void setup();
void display();
void substitute( char from, char to );

int main( void ) {
   setup();
   while (true) {
      display();
      cin >> str;
      cout << '\n';
      substitute( str[0], str[1] );
}  }

void setup() {
   char  tmp;
   srand( time( 0 ) );
   for (int i=0, one, two; i < 300; ++i) {   // randomize encoded
      one = rand() % 26;   two = rand() % 26;   tmp = encoded[one];
      encoded[one] = encoded[two];   encoded[two] = tmp;
   }
   ifstream  ifs( "decrypt.txt" );
   for (int i=0; i < 4; ++i) {
      getline( ifs, str );
      encoded_lines[i] = str;   // make encoded_lines[i] string big enough
      for (int j=0; j < str.size(); ++j)
         if (str[j] >= 'a'  &&  str[j] <= 'z') {
            encoded_lines[i][j] = encoded[str[j]];
            decoded_lines[i] += '-';
         } else
            decoded_lines[i] += str[j];  // spaces and punctuation
}  }

void display() {
   for (int i=0; i < 4; ++i)
      cout << '\n' << decoded_lines[i] << '\n' << encoded_lines[i] << '\n';
   cout << "\nFromTo (\"=e\" where are all e's?): ";
}

void substitute( char from, char to ) {
   for (int i=0; i < 4; ++i)
      for (int j=0; j < encoded_lines[i].size(); ++j)
         if (from == '=') {
            // turn requested decoded char to encoded and report when found
            if (encoded_lines[i][j] == encoded[to])
               decoded_lines[i][j] = to;
         } else if (encoded_lines[i][j] == from) {
            decoded_lines[i][j] = to;
}        }

Adding "?x" from simple implementation to sophisticated

// "?x" using find_decoded() function

char find_decoded( char to ) {
   for (int i=97; i < 123; ++i)
      if (encoded[i] == to)
         return (char) i;
   return '?';
}

         // "=e" - Where are all the decoded e's?
         if (from == '=') {
            // turn requested decoded char to encoded and report when found
            if (encoded_lines[i][j] == encoded[to])
               decoded_lines[i][j] = to;
         // "?x" - What letter does encoded 'x' decode to?
         } else if (from == '?') {
            if (encoded_lines[i][j] == to)
               decoded_lines[i][j] = find_decoded( to );


// "?x" using map

map<char,char> decoded;  // allows encoded char to find its decoded equivalent

   // use decoded to remember the orig_char for each encoded char
   for (int orig_char=97; orig_char < 123; ++orig_char)
      decoded[encoded[orig_char]] = orig_char;

         // "?x" - What letter does encoded 'x' decode to?
         } else if (from == '?') {
            if (encoded_lines[i][j] == to)
               decoded_lines[i][j] = decoded[to];


// "?x" using char array

string decoded = encoded;  // allows encoded char to find its decoded equivalent

   // use decoded to remember the orig_char for each encoded char
   for (int orig_char=97; orig_char < 123; ++orig_char)
      decoded[encoded[orig_char]] = orig_char;

         // "?x" - What letter does encoded 'x' decode to?
         } else if (from == '?') {
            if (encoded_lines[i][j] == to)
               decoded_lines[i][j] = decoded[to];

C++ introductory incremental examples

// print to the screen
int main( void ) { cout << "Hello world\n"; }
// Hello world

// functions: main(), say_hello(), "{...}" is a block of code
// indentation, "Hello" is a string, ' ' is a character, cascade "<<" notation
void say_hello() {
   cout << "Hello";
}
int main( void ) {
   say_hello();
   cout << ' ' << "world\n";
}
// Hello world

// if ... else if ... else
int main( void ) {
   if (1 == 2)
      cout << "1 == 2\n";
   else if (1 < 2)
      cout << "1 < 2\n";
   else if (1 > 2)
      cout << "1 > 2\n";
   else
      cout << "none of the above\n";
}
// 1 < 2

// while loop, "block" of lines requires "{ }"
int main( void ) {
   int number = 1;
   while (number < 6) {
      cout << number << ' ';
      number = number + 1;
   }
   cout << '\n';
}
// 1 2 3 4 5

// refactor while loop into for loop
int main( void ) {
   for (int number = 1; number < 10; number = number + 1) {
      cout << number << ' ';
   }
   cout << '\n';
}
// 1 2 3 4 5 6 7 8 9

// "+=" operator, one-line block doesn't need "{ }"
int main( void ) {
   for (int number = 1; number < 15; number += 1)
      cout << number << ' ';
   cout << '\n';
}
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14

// 'x' is a char, "123" is a string
int main( void ) {
   string  a_string_variable = "now is the time";
   for (int number = 1; number < 4; number += 1)
      cout << a_string_variable << ' ' << number << '\n';
}
// now is the time 1
// now is the time 2
// now is the time 3

// initialize with "( )", "++" operator, '*' operator
int main( void ) {
   string  str( "now is the time" );
   for (int num=1; num < 4; num++)
      cout << str << ' ' << num << " ... " << num * num << '\n';
}
// now is the time 1 ... 1
// now is the time 2 ... 4
// now is the time 3 ... 9

// creating an input file thing, and using it to read a file
int main( void ) {
   string  str;
   ifstream  ifs( "decrypt.txt" );
   for (int i=0; i < 4; ++i) {
      getline( ifs, str );
      cout << str << '\n';
   }
}
// He will wipe away every tear from their eyes.
// There will be no mourning or death or crying or pain,
// for the old order of things has passed away.
// -- Revelation 21:4

// array: a new "data type", notation, specify size, initialize
// vocabulary: elements, index
// first element is at index 0, last element is at index size-1
// load an array from a file
int main( void ) {
   int  array[4] = { 1, 2, 3, 4 };
   for (int i=0; i < 4; ++i)
      cout << array[i] << ' ';
   cout << '\n';

   string  lines[4];
   ifstream  ifs( "decrypt.txt" );
   for (int i=0; i < 4; ++i)
      getline( ifs, lines[i] );

   for (int i=0; i < 4; ++i)
      cout << lines[i] << '\n';
}
// 1 2 3 4
// He will wipe away every tear from their eyes.
// There will be no mourning or death or crying or pain,
// for the old order of things has passed away.
// -- Revelation 21:4

// lower case 'a' to 'z' are encoded as 97 to 122
// an array can be used to associate one thing with something different
int main( void ) {
   char  array[] = { 'a', 'b', 'c', 'x', 'y', 'z' };
   for (int i=0; i < 6; ++i)
      cout << (int) array[i] << ' ';
   cout << '\n';
   char  encrypt_fm_to[123];
   encrypt_fm_to['a'] = 'x';
   encrypt_fm_to['b'] = 'y';
   encrypt_fm_to['c'] = 'z';
   cout << encrypt_fm_to['a'] << encrypt_fm_to['b'] << encrypt_fm_to['c'] << '\n';
}
// 97 98 99 120 121 122
// xyz