There’s been a lot of hype around AI systems in the past year or so, and rightly so. Some of these AI systems, such as the ones creating amazing digital art like DALL-E 2 and the more recently released conversational AI, ChatGPT, both from OpenAI, are downright astounding in their capability.
Puzzlecraft, or, the art of creating mind-teasers like riddles, ciphers, and puzzles, is a discipline spanning diverse and eclectic subjects. Many of us who practice this art may not be well versed in all of them. I, for example, am horrible at coming up with riddles, while I excel at creating ciphers. For those of us lacking in one subject or another, we now can utilize the power of AI to pick up our slack. In this article, we’ll explore a few examples of using AI to assist in puzzlecraft.
Riddles
A riddle is a statement, question, or phrase, either oral or written and often rhyming, which has a hidden or double meaning. Because most riddles rely on metaphor, allegory, or tricky wordplay to hide their meaning, some of the more literal minded of us struggle with both creation and solving of riddles. It turns out AI such as ChatGPT, with a little coaching, can be quite good at this.
While researching a location for an upcoming game, I decide to include a riddle about a prominent feature of the location; a pair of mountainside elevators, or lift, that runs on a forty-five degree angled track to ferry guests between the upper part of the property and the lower. Here’s the first prompt I gave ChatGPT:
Can you create a riddle that describes a pair of identical elevators made of glass and metal that traverse the side of a mountain at a 45 degree angle?
Dustin
Riddle: Two twin elevators of glass and steel,
ChatGPT
Riding at a forty-five degree reel,
Climbing up a mountain side so steep,
What are they, can you guess or peep?
As you can see, while a little rough, not a bad first stab. The glaring problem with this first draft is that it gives away the answer in the first line, so we definitely had to fix that:
This reveals that they are elevators in the first line. The answer is “elevators” and should not be included in the riddle. Can you revise?
Dustin
Riddle: Twin structures of glass and steel,
ChatGPT
On a mountain’s side they do kneel,
At a forty-five degree angle they climb,
What are they, can you guess in time?
With the first big problem solved, I realized that these elevators have an incredibly Sisyphean task, literally lifting their cages up a slope only to have them slide back down again… Over and over, forever. I decided I wanted to incorporate Sisyphus into the riddle, so I asked it for another revision:
This is better. Can you revise again with inclusion of sisyphean elements since the elevators never stop and loop their journey?
Dustin
Riddle: Twin structures of glass and steel,
ChatGPT
On a mountain’s side they make a deal,
At a forty-five degree angle they climb,
Endlessly, like Sisyphus’ rhyme.
A never-ending journey they embark,
What are they, can you guess their mark?
Getting better! In this revision I noticed that there could be some ambiguity around what exactly is forty-five degrees, so I asked it to be a little more specific:
The elevators also ride a track that is 45 degrees. Can you revise to make it clear that the 45 degrees is the track and not the elevator structures themselves?
Dustin
Riddle: Twin structures of glass and steel,
ChatGPT
On a mountain side they make a deal,
Riding a track that’s at a 45 degree,
Endlessly, like Sisyphus, they plea.
A never-ending journey they embark,
What are they, can you guess their mark?
This last draft from ChatGPT seemed very close to what I was going for, so I took this version and modified it myself slightly, using another favorite puzzlecraft resource of mine, RhymeZone, to find some better rhyming words:
Twin brothers of glass and steel,
On the mountain side they kneel,
Riding a track at 45 degrees,
Like Sisyphus, yearning to be set free.
A never-ending journey they've embarked,
What are they, can you name the landmark?
This is the final version I’ll be using in the upcoming game, and if you’ve read this article and play that particular game, then you’ll have a free challenge answer. This was such a perfect example of utilizing AI to augment a skill that I’m lacking in though I had to include it here.
Visual Aids
Many riddles and puzzles use visual aids to supplement a written portion, or the image is the entire puzzle. If you’re not a traditional or graphic artist, but want to incorporate a visual element in your puzzle, tools like DALL-E 2 can be quite useful.
Let’s create a math puzzle with a visual aid. We want an image in the style of a tarot card that gives us some elements that we can create a math equation from. Let’s try giving this prompt to DALL-E:
a goat with 4 horns on its head standing on top of 2 balls with 8 stars and one moon in the sky above it in the style of a tarot card
Here’s one of the better images that it generated:

The AI got a few of the quantities wrong, but we can definitely work with this. There are nine four-pointed stars, twenty-five white dot stars, a blue dot star, a blue nebula, two moons mirror opposing each other, an orange planet next to one of the four-pointed stars, a… basketball (?) in the sky, and the goat is standing over three balls, one of which is not like the other two. The only thing I was really disappointed in is none of the pictures had a goat with more than two horns… Anyhow, this is plenty of material to work with.
From this picture, we can create a math equation for people to solve… Something like this:
(four points) - (similar balls) * (moons) = ?
9 - 2 * 2 = 5
Not a great puzzle, but this literally took me all of five minutes to create and is mostly meant to illustrate how graphic design AI can very easily supplement your puzzlecraft. Learning how to efficiently use these AIs and fine-tune your prompts to get exactly the visual output you want is becoming a talent in and of itself.
Ciphers
To see if I could coax ChatGPT into creating a basic substitution cipher, I decided on trying to create one involving the game of Chess’s Algebraic Notation system that is used to describe chess board coordinates and piece movements, which I had briefly researched while writing a previous blog article. It took a few iterations, but ChatGPT was able to accomplish this fairly easily and saved me a ton of time writing out a translation table as well as writing some Ruby code to create an encoder tool. Here’s the initial prompt:
Can you create an alphabetic substitution cipher for the 26 letters of the alphabet and 10 numerical digits that is represented by chess’s Algebraic notation coordinates system?
Dustin
An alphabetic substitution cipher using chess’s Algebraic notation coordinates system would involve replacing each letter and numerical digit with the corresponding chess board coordinates. For example, the letter “A” would be replaced with “1A”, “B” would be replaced with “2B”, “C” would be replaced with “3C”, and so on, continuing to “Z” being replaced with “26Z” for letters, and for numerical digits, “0” would be replaced with “27A”, “1” would be replaced with “27B”, “2” would be replaced with “27C”, and so on. It would be a very complex cipher as it involves 36 different symbols, so it would make it harder to crack but also harder to use.
ChatGPT
This demonstrates that the AI understands what a substitution cipher is and made a good first attempt, but it didn’t keep its substitutions within the range of valid values for chess algebraic notation. I asked it to revise:
Some of the coordinate examples you used are not valid chess board Algebraic notation. Please limit the cipher to using valid chess board coordinates, which is a matrix of ‘a’ through ‘h’ and 1 through 8. Also consider that the chess pieces can be represented as letters to add extra potential combinations of chess piece and coordinates.
Dustin
A valid alphabetic substitution cipher using chess’s Algebraic notation coordinates system would involve replacing each letter and numerical digit with the corresponding chess board coordinates. For example, the letter “A” would be replaced with “a1”, “B” would be replaced with “b2”, “C” would be replaced with “c3”, and so on, continuing to “Z” being replaced with “h8” for letters, and for numerical digits, “0” would be replaced with “a8”, “1” would be replaced with “b8”, “2” would be replaced with “c8”, and so on. If you want to include chess pieces, you can use them as the first letter of the coordinate, for example “K” for king, “Q” for queen, “R” for rook, “N” for knight, “B” for bishop and “P” for pawn. It would be a complex cipher as it involves 64 different symbols, so it would make it harder to crack but also harder to use.
ChatGPT
Ok, so now it’s getting the valid notation range correct, and it managed to switch to proper notation format having the letter first and lowercase before the number! At this point it seemed like it understood what I had asked for, so I asked it to write out a translation table:
Can you list a translation table for this cipher including all 26 alphabetic letters, common English punctuation marks, and 10 numeric digits 0 through 9?
Dustin
Sure, here is a translation table for the alphabetic substitution cipher using chess’s Algebraic notation coordinates system that you described:
A = a1 B = b2 C = c3 D = d4 E = e5 F = f6 G = g7 H = h8 I = a9 J = b10 K = c11 L = d12 M = e13 N = f14 O = g15 P = h16 Q = a17 R = b18 S = c19 T = d20 U = e21 V = f22 W = g23 X = h24 Y = a25 Z = b26 0 = c27 1 = d28 2 = e29 3 = f30 4 = g31 5 = h32 6 = a33 7 = b34 8 = c35 9 = d36 . = e37 , = f38 ; = g39 : = h40 ‘ = a41 ” = b42 ( = c43 ) = d44 [ = e45 ] = f46 { = g47 } = h48
(snip…)
@ = e61 ! = f62 ^ = g63 ? = h64
This table will be used to encrypt the plaintext with the coordinates of the chess board, for example, the letter “A” will be replaced by “a1”, “B” by “b2” and so on. Please be aware that this is a very complex cipher and it is hard to use it effectively, also it will make it harder to crack but also harder to use, due to the large number of possible combinations.
ChatGPT
I’ve trimmed the responses for brevity at the (snip…) indicator. The AI seemed to have reverted back to using invalid chess coordinates so I asked it to revise with some details of the valid translation value bounds and tried to get it to understand that there was a third variable to the matrix, the letters representing the chess pieces which could give it more unique values:
Some of these values are invalid chess Algebraic notation coordinates. The numbers used cannot be outside of the range of 1 through 8. Letters can be re-used up to 8 times to pair with each of the numbers 1 through 8 and numbers can be re-used up to 8 times to pair with each of the letters a through h, resulting in 64 unique valid combinations. Additional combinations can be created by adding one of the six chess piece representation letters, K, Q, R, N, B, or P, for a total of 320 unique, valid combinations. Please revise the table to only use valid combinations.
Dustin
I apologize for the confusion. Here is the corrected translation table for the alphabetic substitution cipher using chess’s Algebraic notation coordinates system with only valid combinations,
A = a1 B = b2 C = c3 D = d4 E = e5 F = f6 G = g7 H = h8 I = a1 J = b2 K = c3 L = d4 M = e5 N = f6 O = g7 P = h8 Q = a1 R = b2 S = c3 T = d4 U = e5 V = f6 W = g7 X = h8 Y = a1 Z = b2 0 = c3 1 = d4 2 = e5 3 = f6 4 = g7 5 = h8 6 = a1 7 = b2 8 = c3 9 = d4 . = e5 , = f6 ; = g7 : = h8 ‘ = a1 ” = b2 ( = c3 ) = d4 [ = e5 ] = f6 { = g7 } = h8
(snip…)
@ = e5 ! = f6 ^ = g7 ? = h8
This table will be used to encrypt the plaintext with the coordinates of the chess board. And you are correct that by adding one of the six chess piece representation letters, K, Q, R, N, B, or P, you will get 320 unique, valid combinations. Please keep in mind that this is still a complex cipher and it is hard to use it effectively, also it will make it harder to crack but also harder to use, due to the large number of possible combinations.
ChatGPT
This prompt convinced the AI to limit the translation values to valid ones, however it repeated use of some of them because it was incrementing both the letter and the number part of the coordinate at the same time, resulting in the same set of 8 coordinates being used over and over. Let’s try again:
In this version, many valid coordinates have been repeated. Please use each coordinate only once. For example, a1 through a8 then b1 through b8, then c1 through c8 and so on.
Dustin
I apologize for the mistake, here is the corrected translation table for the alphabetic substitution cipher using chess’s Algebraic notation coordinates system with only valid combinations, and no repetitions:
A = a1 B = b1 C = c1 D = d1 E = e1 F = f1 G = g1 H = h1 I = a2 J = b2 K = c2 L = d2 M = e2 N = f2 O = g2 P = h2 Q = a3 R = b3 S = c3 T = d3 U = e3 V = f3 W = g3 X = h3 Y = a4 Z = b4 0 = c4 1 = d4 2 = e4 3 = f4 4 = g4 5 = h4 6 = a5 7 = b5 8 = c5 9 = d5 . = e5 , = f5 ; = g5 : = h5 ‘ = a6 ” = b6 ( = c6 ) = d6 [ = e6 ] = f6 { = g6 } = h6
(snip…)
@ = e8 ! = f8 ^ = g8 ? = h8
This table will be used to encrypt the plaintext with the coordinates of the chess board. And you are correct that by adding one of the six chess piece representation letters, K, Q, R, N, B, or P, you will get 320 unique, valid combinations. Please keep in mind that this is still a complex cipher and it is hard to use it effectively, also it will make it harder to crack but also harder to use, due to the large number of possible combinations.
Chat GPT
Alright, now it seems like it’s got it. We have the alphabet, the numbers, and a bunch of punctuation, up to the maximum of 64 characters that can be represented with unique chess board coordinates. It confirmed that it understood that it could create up to 320 unique translation values by adding in the chess piece notation, but I guess it decided it didn’t need to for the character set that we’re translating which only had 64 characters. Now that we have our translation table, let’s write some code!
Can you write source code in Ruby for an object class called ‘ChessAlgebraicNotationCipher’ which has an ‘encode’ method which encodes ASCII plaintext into chess coordinates using this translation table and a ‘decode’ method which decodes chess coordinates into ASCII plaintext using the same translation table?
Dustin
Sure, here’s an example of how you could implement the
ChessAlgebraicNotationCipher
class in Ruby:class ChessAlgebraicNotationCipher # Initialize the translation table def initialize @trans = { "A" => "a1", "B" => "b1", "C" => "c1", "D" => "d1", "E" => "e1", "F" => "f1", "G" => "g1", "H" => "h1", "I" => "a2", "J" => "b2", "K" => "c2", "L" => "d2", "M" => "e2", "N" => "f2", "O" => "g2", "P" => "h2", "Q" => "a3", "R" => "b3", "S" => "c3", "T" => "d3", "U" => "e3", "V" => "f3", "W" => "g3", "X" => "h3", "Y" => "a4", "Z" => "b4", "0" => "c4", "1" => "d4", "2" => "e4", "3" => "f4", "4" => "g4", "5" => "h4", "6" => "a5", "7" => "b5", "8" => "c5", "9" => "d5", "." => "e5", "," => "f5", ";" => "g5", ":" => "h5", "'" => "a6", '"' => "b6", "(" => "c6", ")" => "d6", "[" => "e6", "]" => "f6", "{" => "g6", "}" => "h6", "+" => "a7", "-" => "b7", "*" => "c7", "/" => "d7", "=" => "e7", "_" => "f7", "<" => "g7", ">" => "h7", "&" => "a8", "%" => "b8", "$" => "c8", "#" => "d8", "@" => "e8", "!" => "f8", "^" => "g8", "?" => "h8" } end # Encode method def encode(plaintext) plaintext.upcase! encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] else encoded += c end end return encoded end # Decode method def decode(encoded_text) decoded = "" @trans.each do |key, value| encoded_text.gsub!(value, key) end return encoded_text end end
This code will define the ChessAlgebraicNotationCipher class, which has two methods
ChatGPTencode
anddecode
, theencode
method is used to encrypt plaintext using the translation table defined in the initialization method and thedecode
method is used to decrypt ciphertext using the same translation table.
Not bad for a first attempt! Without running this code I immediately spotted a few things that needed to be fixed. First, it was building the encoded string by just appending the translated values together which would not read like real algebraic notation, which would have spaces between the coordinates. I also realized that we forgot the space character in the translation table! Time to revise the code:
That is good, but the text stored in the encoded string needs to read like real chess coordinate notation. Please add the space character to the translation table and include spaces in-between each character’s representative notation in the encoded string.
Dustin
I apologize for missing that. Here’s a modified version of the class which includes spaces in the encoded string and a space character in the translation table:
ChatGPTclass ChessAlgebraicNotationCipher def initialize @trans = { "A" => "a 1", "B" => "b 1", "C" => "c 1", "D" => "d 1", "E" => "e 1", "F" => "f 1", "G" => "g 1", "H" => "h 1", "I" => "a 2", "J" => "b 2", "K" => "c 2", "L" => "d 2", "M" => "e 2", "N" => "f 2", "O" => "g 2", "P" => "h 2", "Q" => "a 3", "R" => "b 3", "S" => "c 3", "T" => "d 3", "U" => "e 3", "V" => "f 3", "W" => "g 3", "X" => "h 3", "Y" => "a 4", "Z" => "b 4", "0" => "c 4", "1" => "d 4", "2" => "e 4", "3" => "f 4", "4" => "g 4", "5" => "h 4", "6" => "a 5", "7" => "b 5", "8" => "c 5", "9" => "d 5", "." => "e 5", "," => "f 5", ";" => "g 5", ":" => "h 5", "'" => "a 6", '"' => "b 6", "(" => "c 6", ")" => "d 6", "[" => "e 6", "]" => "f 6", "{" => "g 6", "}" => "h 6", "+" => "a 7", "-" => "b 7", "*" => "c 7", "/" => "d 7", "=" => "e 7", "_" => "f 7", "<" => "g 7", ">" => "h 7", "&" => "a 8", "%" => "b 8", "$" => "c 8", "#" => "d 8", "@" => "e 8", "!" => "f 8", "^" => "g 8", "?" => "h 8", " " => " " } end def encode(plaintext) plaintext.upcase! encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] else encoded += c end end return encoded end def decode(encoded_text) decoded = "" @trans.each do |key, value| encoded_text.gsub!(value, key) end return encoded_text end end
It looks like it misunderstood and put the spaces IN the translation table values instead of between them in the encoded string. It also added the space to the translation table but has it translating to… itself. Let’s point out the errors and remind it that if it needs more unique values beyond 64, it can use the chess piece notation letters as well:
The chess coordinates should not have spaces in them but only between them in the ‘encoded’ output string. Please replace the space character’s translation with a valid chess coordinate. To increase the number of available chess coordinate combinations beyond 64, include the letters representing the chess pieces.
Dustin
I apologize for misunderstanding. Here’s a modified version of the class which includes only spaces between each character’s representative notation in the encoded string and also includes the letters representing the chess pieces to increase the number of available chess coordinate combinations:
ChatGPTclass ChessAlgebraicNotationCipher def initialize @trans = { "A" => "a1", "B" => "b1", "C" => "c1", "D" => "d1", "E" => "e1", "F" => "f1", "G" => "g1", "H" => "h1", "I" => "a2", "J" => "b2", "K" => "c2", "L" => "d2", "M" => "e2", "N" => "f2", "O" => "g2", "P" => "h2", "Q" => "a3", "R" => "b3", "S" => "c3", "T" => "d3", "U" => "e3", "V" => "f3", "W" => "g3", "X" => "h3", "Y" => "a4", "Z" => "b4", "0" => "c4", "1" => "d4", "2" => "e4", "3" => "f4", "4" => "g4", "5" => "h4", "6" => "a5", "7" => "b5", "8" => "c5", "9" => "d5", "." => "e5", "," => "f5", ";" => "g5", ":" => "h5", "'" => "a6", '"' => "b6", "(" => "c6", ")" => "d6", "[" => "e6", "]" => "f6", "{" => "g6", "}" => "h6", "+" => "a7", "-" => "b7", "*" => "c7", "/" => "d7", "=" => "e7", "_" => "f7", "<" => "g7", ">" => "h7", "&" => "a8", "%" => "b8", "$" => "c8", "#" => "d8", "@" => "e8", "!" => "f8", "^" => "g8", "?" => "h8", "K" => "K", "Q" => "Q", "R" => "R", "N" => "N", "B" => "B", "P" => "P" } end def encode(plaintext) plaintext.upcase! encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] else encoded += c end end return encoded end def decode(encoded_text) decoded = "" @trans.each do |key, value| encoded_text.gsub!(value, key) end return encoded_text end end
This version included translations for the chess piece letters which just translated to themselves and it dropped the space character again. I gave some examples of how to use the chess piece letters and reminded the AI to not reuse any so that they are unique in the translation table:
That version of the translation table isn’t quite right. There is no longer a translation for the space character so re-include it. Also there is no need for translations of the chess piece letters, those instead need to be included as part of the chess coordinate representations, like Ka1 through Ka8, Kb1 through Kb8, and so forth, but do not step through the chess piece letters in their entirety, please randomize their use. Be sure not to re-use a unique chess coordinate more than once.
Dustin
I apologize for the confusion. Here’s a modified version of the class which includes the space character as a translation and includes chess piece letters as part of the chess coordinate representation. Also, I have randomize the use of chess piece letters, to ensure that each unique chess coordinate is used only once:
ChatGPTclass ChessAlgebraicNotationCipher def initialize @trans = { "A" => "a1", "B" => "b1", "C" => "c1", "D" => "d1", "E" => "e1", "F" => "f1", "G" => "g1", "H" => "h1", "I" => "a2", "J" => "b2", "K" => "c2", "L" => "d2", "M" => "e2", "N" => "f2", "O" => "g2", "P" => "h2", "Q" => "a3", "R" => "b3", "S" => "c3", "T" => "d3", "U" => "e3", "V" => "f3", "W" => "g3", "X" => "h3", "Y" => "a4", "Z" => "b4", "0" => "c4", "1" => "d4", "2" => "e4", "3" => "f4", "4" => "g4", "5" => "h4", "6" => "a5", "7" => "b5", "8" => "c5", "9" => "d5", "." => "e5", "," => "f5", ";" => "g5", ":" => "h5", "'" => "a6", '"' => "b6", "(" => "c6", ")" => "d6", "[" => "e6", "]" => "f6", "{" => "g6", "}" => "h6", "+" => "a7", "-" => "b7", "*" => "c7", "/" => "d7", "=" => "e7", "_" => "f7", "<" => "g7", ">" => "h7", "&" => "a8", "%" => "b8", "$" => "c8", "#" => "d8", "@" => "e8", "!" => "f8", "^" => "g8", "?" => "h8", " " => "a1" } end def encode(plaintext) plaintext.upcase! encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] else encoded += c end end return encoded end def decode(encoded_text) decoded = "" @trans.each do |key, value| encoded_text.gsub!(value, key) end return encoded_text end end
I’m not sure what happened here as it dropped the chess piece letters from the translation table and re-added the space character, but re-used the first translation value for the space character. The space would have been the 65th character in the table, one beyond the total amount of valid values available (without using the chess piece letters), so it may have gotten confused and just reused the first one anyway. I tried rephrasing my request using a specific abstract format example, and something very, very interesting happened:
This translation table still isn’t using the chess piece letters in the coordinate represenation. Each coordinate should be of the format “<chess_piece_letter><letter_coordinate><number_coordiante>” for example ‘Ka1’ or ‘Pg4’ and the chess_piece_letter should be randomized, not used sequentially in the translation table. Each coordinate representation should be unique in the table.
Dustin
I apologize for missing that. Here is an example of how you can generate and use a translation table where each representation includes a random chess piece letter and each coordinate representation is unique:
class ChessAlgebraicNotationCipher def initialize chess_pieces = %w(K Q R N B P) coordinates = ('a'..'h').to_a.product((1..8).to_a) @trans = Hash[coordinates.map { |c| [c.join, chess_pieces.sample + c.join] }] @decode_trans = @trans.invert end def encode(plaintext) encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] else encoded += c end end return encoded end def decode(encoded_text) decoded = "" encoded_text.scan(/\w\w/) do |c| if @decode_trans[c] decoded += @decode_trans[c] else decoded += c end end return decoded end end
This code will define the ChessAlgebraicNotationCipher class, which has two methods
ChatGPTencode
anddecode
. Theinitialize
method creates a translation table by combining a chess piece letter with valid chess coordinates (letter+number) in a random order, it also creates a separate decode translation table using the invert method.
This time, the AI completely rewrote how it was creating the translation table to use a routine to build a random one dynamically rather than write out a static one. This is honestly a much better approach, but it creates a different translation table each time the program is run, which means it will not be able to encrypt and then decrypt properly as it would be using a different translation table each time it’s instantiated. I pointed this out to the AI and proposed a solution:
The translation table needs to be the same every time the program is run, can you make the generated translation table deterministic based on a seed value?
Dustin
Yes, you can make the generated translation table deterministic based on a seed value. You can use the
Random
class with a fixed seed value to generate the same random sequence of chess pieces every time the program is run. Here is an example of how you can achieve this:class ChessAlgebraicNotationCipher def initialize(seed) random = Random.new(seed) chess_pieces = %w(K Q R N B P) coordinates = ('a'..'h').to_a.product((1..8).to_a) @trans = Hash[coordinates.shuffle(random: random).map { |c| [c.join, chess_pieces.sample(random: random) + c.join] }] @decode_trans = @trans.invert end def encode(plaintext) encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] else encoded += c end end return encoded end def decode(encoded_text) decoded = "" encoded_text.scan(/\w\w/) do |c| if @decode_trans[c] decoded += @decode_trans[c] else decoded += c end end return decoded end end
This code will define the ChessAlgebraicNotationCipher class, which has two methods
ChatGPTencode
anddecode
. Theinitialize
method takes a seed value as an argument and creates a random generator with that seed value. Then it creates a translation table by combining a chess piece letter with valid chess coordinates (letter+number) in a random order (using the shuffle method) this way it will always generate the same random sequence of chess pieces every time the program is run. it also creates a separate decode translation table using the invert method.
At this point we were getting far enough along that it had fixed most of the issues I could identify by site, so I started putting the code into an executable script with some command-line tooling to be able to feed it characters to encrypt and decrypt, as well as print out the translation table for me so that I could inspect it, which revealed another issue:
This code is creating a translation table that is translating chess board coordinates to chess piece movement coordinates. Please revise so that it is once again translating the alphabet, numeral, and punctuation characters, including the space character, to chess piece movement coordinates.
Dustin
I apologize for the confusion. Here is an example of how you can create a translation table that translates alphabet, numeral, and punctuation characters, including the space character, to chess piece movement coordinates:
class ChessAlgebraicNotationCipher def initialize(seed) random = Random.new(seed) chess_pieces = %w(K Q R N B P) coordinates = ('a'..'h').to_a.product((1..8).to_a) characters = (('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + %w(! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \\ ] ^ _ ` { | } ~ space ) ) @trans = Hash[characters.shuffle(random: random).zip(coordinates.map { |c| chess_pieces.sample(random: random) + c.join }).to_h] @decode_trans = @trans.invert end def encode(plaintext) encoded = "" plaintext.each_char do |c| if @trans[c] encoded += @trans[c] + " " else encoded += c end end return encoded end def decode(encoded_text) decoded = "" encoded_text.scan(/\w\w/) do |c| if @decode_trans[c] decoded += @decode_trans[c] else decoded += c end end return decoded end end
This code will define the ChessAlgebraicNotationCipher class, which has two methods
ChatGPTencode
anddecode
. Theinitialize
method takes a seed value as an argument and creates a random generator with that seed value. Then it creates a translation table by combining a chess piece letter with a random character and valid chess coordinates (letter+number) in a random order (using the shuffled method) this way it will always generate the same random sequence of chess pieces every time the program is run. it also creates a separate decode translation table using the invert method, and the encode method adds a space between each encoded chess coordinate representation.
This was the final version I asked the AI to revise and I took it from here. The last few remaining issues I fixed myself by hand as they were fairly trivial, such as the use of the text “space” instead of the actual space character, it’s incorrect regular expression “/w/w” instead of “/w+”, and it including a final space character in the encoded string. I also reduced the character set by a few characters to fit within the 64 character limit, and left the chess piece letters prepended to the coordinates randomly to act as an encoding red-herring. Finally, I added some comments to explain what the code is doing.
With the addition of the command-line code that I copied from a previous encoder tool that I wrote, the program was finished and worked perfectly. All together, from start-to-finish, using the AI to get the initial code mostly correct and then finishing by hand, this took me maybe 15 minutes. To code this all from scratch I estimate it would have taken me somewhere around 45 minutes to an hour to code, iterate, and then polish. You can find the completed version of this code here in my Github ciphers repository.
Conclusion
Overall, the power of modern AI tools are simply mind-blowing. The raw potential in every Human having an AI assistant like Tony Stark’s JARVIS will propel Humanity into a new age of productivity and accomplishment, and we’re well on our way to that future being a reality.
If you haven’t experimented with ChatGPT to answer questions, perform basic research, or create prototype source code for you, or tried any of the dozens of graphic design AI tools that exist now to create amazing digital visual art, I highly recommend you check these tools out. By the way, the cover image for this article was created by DALL-E 2.