The nonogram puzzles in Piczle Cross Adventure are merely a string of 1s and 0s. Everything else required is calculated while playing the game. Actually, let me take a step back and correct this lie. The puzzles all live in one big datatable, with the puzzle part itself forming a string of 1s and 0s. The datatable also includes their ID, the size of the puzzle, how much XP the player earns for clearing the puzzle, and the solution text in all required languages.
But in this blogpost I thought I’d write about how I calculate the clue numbers that appear in the rows and columns when you start a puzzle.
First the string of 1s and 0s is put into an array which represents the puzzle. A 1 represents a solid block, a 0 an empty grid square. An array is just a long list, but let’s visualise it as a puzzle grid.
Each spot in the grid represents a position in the array. Arrays always start at index 0, and in this case, a 5×5 puzzle, ends with index 24.
As you can see, it is very easy to find a position on the grid, figure out which index that represents, then look up in the array what that grid square holds – or rather should hold in a correctly completed puzzle. In the above element, column 2, row 2 in the grid represents index 6, which is a 1 in the puzzle array; i.e. a block.
Now we have a puzzle grid with a completed puzzle in it, let’s turn that into nonogram clues. First off, I isolate whichever row or column I am looking at into a new array so I can focus just on that. After all, the rules for counting clues is the same horizontally as it is vertically, so if I isolate each row and column into a separate array I can apply the same script to any of them.
As you can see here, if I isolate row 5, I need to isolate the entries at indexes 20 to 24, a smaller string of 1s and 0s. However if I want to isolate column 2, I need to grab the entries at indexes 1, 6, 11, 16 and 21. This is done with some very simple math. In the game I cycle through all rows and columns in turn, to spit out a single small string of 1s and 0s from which I calculate the clues for each row and column.
I specifically separated the isolating of the rows/columns from the clue calculation script because I recalculate clues on the fly during gameplay. As you fill in the puzzle, these entries are put into a separate array. Once your puzzle array and the solution array are the same, you will have cleared the puzzle. But sometimes I need to check if your puzzle conforms to the clues, so I can grey out completed clues.
As you player fills in part of the puzzle, I keep track of which rows and columns have changed. Then as soon as the player releases the button I quickly do a recalculation of the clues only on the changed rows and columns. For this reason the isolating rows and column function is separate from the clues calculation function that follows now.
Once I have my isolated little array I simply start counting. When I encounter a 0 I reset the count, when I encounter a 1 I add one to the count. So in the above array I first count a 0, so that’s nothing. Let’s move on. Then I encounter a 1, aha, a clue. So add one to the counter. Then I encounter 2 more 1s, so I add two more to the counter. Then another 0. This means the counter is finished and I have my first clue. A “3”. Of course I need to check if I counted anything at all, to make sure a row or column that is entirely empty has a clue that reads “0”.
The column following is easier. Two isolated 1s means two clues for that row.
As you can see it’s fairly easy to create a set of clues for each row and column based on the array that represents the puzzle’s final solution.
As mentioned above I do the same thing with the grid the player is filling in. I calculate the “clues”, so to speak, of what the player has drawn, and if they are the same as the clues calculated for the puzzle solution then it means they have fulfilled the clues and I can grey them out.
Now obviously the player can make a mistake and still conform to the clue of a row or column. In this case the clues will still be greyed out but the player will find it impossible to clear the puzzle. It’s a neat way of figuring out where you made a mistake. If all clues are grey except for one row, and you fix that row, another column somewhere will un-grey. This way you can work backwards to figure out your mistake and solve the puzzle.
The joy of working in Blueprints is that all of the above is so much easier to implement than to explain in (I hope) plain English. What I find most gratifying working in Blueprints is that if you can work something out logically in your head or on paper, it means you can build it in Blueprints. It might not always be the fastest, most streamlined solution but it works. Streamlining (optimisation) is something all games go through at some point, where you’re not solving the problem anymore, you’re just making the solution more elegant.