Programming in Numipulator
The programming language of Numipulator really is very simple: you need to select the required functions/operations from drop-down lists and enter numbers or lists of numbers into boxes, together with reference names and maybe a few other reserved words that represent numbers or lists of numbers. The difficulty of programming a game in Numipulator will, of course, depend on the complexity of the game. Below is a fully-explained program for a simple game. Following that is a simple program for controlling an object in the Animation Zone with its keypad; this program can be used as a basis for any program involving movement of an object around the screen, and is set up to be easily modified for object size, screen size and number of cells moved per cycle. Lastly, the creation of complex graphical outputs in the Animation Zone is described, as is the simplicity of specifying irregular shapes using a table of numbers where the shape can be 'seen'.
Programming a simple game
The game included in Numipulator called Small red ball is designed to be a simple game to program and to understand.
The game is played on a 10x10 grid in the Graphics Formatter (this size is default). The idea is that each cell displays a shape (a small, medium or large circle (or ball), a small or medium square, or an arrow pointing left, right, up or down). Each one of these is coloured either red, green, blue, magenta, cyan or yellow, always on a black, borderless background. There may be several, or even none, of a particular shape/colour combination, but there is only one small red ball, as shown in the first image below. The player has a short time in which to spot the small red ball, and then to tap on it. At the end of the time allowed, a new screen is displayed, again with one small red ball. If the player has tapped on the correct cell, a green Y (for Yes) is displayed where the small red ball was, as shown in the second image below. The player's score is increased by 1 (shown in the Feedback). In contrast, if the player has tapped on the wrong cell, a red N (for No) is displayed on the tapped cell in the next screen, together with a grey X showing where the small red ball was in the last screen. This situation is shown in the third image below, after the player has erroneously tapped on the small blue ball below the target red one. If the player fails to tap on any cell in the time allowed, only the grey X is shown on the next screen. This continues for 50 turns.
To program this, you need to know the format codes for these shapes and their colours. The shapes and colours have been chosen to suit the format codes. The format code for these shapes take the form NFGBG, where N is a shape number, FG is the foreground colour, and BG is the background colour (these are both two digits). The relevant values of N are:
The relevant foreground colours are:
Now, a black background is specified by 00, so, 10300 is the code for a small red circle on a black background, 10400 is the code for a small green ball on a black background, through to 90800, which is the code for a yellow left-arrow on a black background. To have no borders in the cells, negative equivalents of these must be used, e.g. -10400 and -90800.
Generating 100 shapes
To generate a screen with 100 cells as described, without, for now, the small red ball, you can use the List Generation function called p1 random ints p2->p3 to begin with. The input list consists of sets of three parameters: the first is the number of random numbers to generate, the second and third are the minimum and maximum integers from which the random numbers are to be taken. The results for each group of three are listed sequentially in the output.
Now, although the intention is to end up with codes such as -10400, -10500, -10600 and -70500, it is useful to mentally divide each of the format codes by 100, as then the numbers form sequences: 104, 105 ... 108, 203, 204, ... 209,...., 903, 904 ....908. Box G2 shows how you can generate 100 such numbers, where the input list is:
Points to note are that 103 is excluded, as this forms the basis of the small red ball (and the intention is to have exactly one of these), and that the request is for 11 of each of the first 8 shapes, but 12 for the last one, as this gives a total of 100 numbers.
Now the output of G2 has 11 small circles of varying colour, followed by 11 medium circles, and so on. These need to be shuffled up, so the output from G2 is fed in as the input to H1, with the Permutation function selected.
Finally, the numbers need to be multiplied by -100 to yield 100 valid format codes for shapes on a borderless black background, so H1 is defined as the first input of V1 and -100 as its second.
You can very easily test your program development by going to the Graphics Formatter and defining the main input parameters to be la=V1, ncols=10 and Cell formats to be V1. The same value for la and Cell formats can be used as these particular format codes ignore the values in la, so you might as well use the same values. Press the = button, and you should see 100 colourful shapes (but no small red ball, at this stage). Pressing it again should give you different shapes. You have produced a significant part of the overall program with just three numipulation boxes.
Determining the position of the small red ball in the new display
The positioning of the small red ball should be random, but with certain constraints: it cannot be placed on cells that will show feedback (Y, N or X) from the previous display and user interaction, i.e. the previous position of the small red ball and the cell that the user tapped.
When the user taps on a Graphics Formatter cell, two fields are given new values: Graphin1 is given the row value, and Graphin2 is given the column value. Also, the internal value click is given the value 1 (the value is 0 if no tap is made). Probably the best way to deal with positions in this simple game is to give every cell of the Graphics Display an index number, from 1 to 100. You can use a Number Operation box, such as A2, to convert the row and column number to an index, using the Index: [a,b] 10 cols operation, which is designed to take the row and column number in a 10-column table and to output the index. It is, however, important to remember that if no tap is made, the values of Graphin1 and Graphin2 remain unchanged, so the output of A2 may not be the index of the tap just made, but of an earlier tap. To distinguish between a real and a false index, you can use an If-Then-Else (Simple) box, such as O1, to return either a true index or the value 0, by checking whether the value of click is 1 or not. So, the value of O1 is either the index of the cell just clicked, or 0, and the small red ball must not be placed at index O1.
Knowing the position of the small red ball in the previous display (if any) means that this must be remembered in a Number Memory box, such as Y1, and the value Y1 is another index that in which the small red ball must not be placed.
The available indices for placing the small red ball are therefore 1-100, except for O1 and Y1. This list may be determined in box K1, which takes as inputs the integer list 1-100, as generated in List Generation box G1, and the list containing O1 and Y1, and outputs those values in 1-100 that do not appear in list O1 Y1. You can then take any one of the output list of K1, randomly, by shuffling the list in H2 using the Permutation function again, and then taking the first item on the resulting list in box C1 (it's as good as any other one).
You can now program the Memory Number box that is being used to remember the position of the small red ball. You now know that the next value will be C1 (the position of the ball just determined). Note that this box must include an init value to be used for the first cycle. Make this a mock value, -1; the reason for this is discussed later.
Adding the small red ball and hit/miss indicators.
Your program has now determined the previous position of the small red ball (Y1), the index tapped by the player (O1) and the position of the new small red ball (C1). You must now ensure that the new small red ball and the feedback letters (Y, N, X) are added in to the next display.
You can use the List & List Operation called Change values for taking an input list and making changes to this for the output list. It takes any number of sets of parameters, each of which is a pair of the form I V, where I is the index and V is the new value to be inserted at this index. Now, although you must always add in the new small red ball, the other feedback letters may or may not be needed: there is no need for a grey X in the first cycle or if the player has selected the correct position, and there is no hit/miss feedback in the first cycle or if the player has not tapped on a cell. The If-Then-Else (Simple) boxes O2, with its subsidiary O3, outputs parameters O1 -190400 (green letter) if the tap was a hit, O1 -190300 (red letter) if the tap was a miss, but an empty list in other cases. Boxes O4 and O5 output an empty list unless the tap was incorrect, in which case the parameters Y1 -190900 (grey letter) are output.
O2 and O4 are fed in as part of the second input to K2, together with the parameters for the small red ball, C1 -10300, with V1 as the first input.
K2 can now be put into the Graphics Formatter fields for la and Cell formats (replacing the earlier V1). However, the format codes for the red, green and grey letters do not ignore the values specified in la. This means that if you were to run the program now, these codes would attempt to display -190... in the middle of the cells. You therefore need to specify output
mapping in the Cell text field of the Graphic Formatter, as follows:
Before running your code, ensure that you have checked the Allow graphical input box in Graphics Control, and that you have defined init values for Graphin1 and Graphin2 (any valid values, e.g. 1 and 1, will do).
You can now test your code by pressing the Start button. At this stage, no repetitions have been specified, so the time allowed after a display is unlimited. Tapping on a cell should give you the correct feedback.
Repetitions and delay time
To make the game dynamic, you need to ensure that repetitions are specified, with a clear stopping point, and that the delay time is short enough to make it difficult, e.g. 2.5 seconds. First, put the value 2.5 in the Num1 numipulation box, and then enter Num1 as the delay time in the Control1 field of the Repetitions area; using Num1 means that a player could change this if it were a standalone game.
Next, you need to specify the repeat until condition in the Repetitions area. Assume that you will use Y4 as the Number Memory box for number of cycles, so put in a terminating condition, say Y4 >= 50. Y4 is given an init specification of 0, while the next specification is A1, which simply takes Y1 and adds 1 to it each cycle (together these form a simple incrementor). Overall, this should ensure that the repetitions stop after 51 cycles (as the value of Y4 will be 0 for the first cycle, not 1).
The last functionality that needs to be handled is scoring. The score will be fed back to the player in the Feedback area of the Graphics Formatter.
The score is another value that needs a Memory Number box to remember it: Y3 has an init specification of 0, and a next specification of A3. A3 simply adds the input score (Y3) to O6, which is an If-Then-Else (Simple) box that has an output value of 1, if O1 = Y1 (signifying a hit), otherwise a value of 0; it is worth noting that this is the reason -1 is used as the init specification for Y1, rather than 0, to ensure that there is no false hit in the first cycle (which would happen if Y1 = 0). The new score A3 and the scorable cycles so far, Y4, are both values fed into the Feedback text. The other two values in this, -5 and -6, are there just to enable text rather than just two numbers as the feedback, as shown by number to text output mapping in the Feedback text and the resulting Feedback some way through a game.
The complete game involves 24 numipulation boxes only (including Control1, Graphin1 and Graphin2), together with a repetition constraint, settings and two number to text output mapping fields.
Moving an object in the Animation Zone
A common need in the Animation Zone is to move an object around using the keypad arrow keys. Below is a program for achieving this.
So that this can be applied to many cases, the key numbers are specified in Common Numbers, which are referred to in other numipulation boxes. The key numbers are the number of cells to be moved for any directional request (D1), the height of the object, i.e. number of rows in it (D2), the width of the object, i.e. number of columns in it (D3), and the board size (D4).
The only two values that need to be remembered from one cycle to the next in Memory Number boxes are the row of the top of the object (Y1) and the left column of the object (Y2). These have each been initiated as 1, so the object will initially be at the top-left corner of the Animation Zone.
Boxes C4 and C5 specify the change in rows and columns for all possible keypad requests (or none, if keypad = 0). These boxes make use of the Case: = function, in which the input list should be treated as several groups of three numbers forming a case statement (a sequence of if-then-elses). If the first of the three equals the second of the three, then the output is the third number; if not, the second group of three is checked, and so on; the spare number at the end is the default value if none of these checks succeed (0 in these cases). The changes shown are either the specified move (D1), or the negative equivalent (B1). The full input for C4 is:
A1 and A2 specify what the changed top row and left column of the object would be if the request changes (C4 and C5) were made. A3 and A4 calculate what the bottom and right cells of the object would be if such a change were made (N.B. the bottom row is the changed top row, A1, plus the object height - 1 (B3); similar for columns).
For any keypad move request, it is crucial to check that the request is valid. For example, if the object is at the top of the board, a request to move upwards would be invalid. Box C3 checks whether the requested move is valid, using the Case: Comp function. This works in a similar way to the Case: = function, but the numbers are in groups of four, where the second number represents a comparison operator to be used in the check: 1 means <, 2 means <=, 3 means =, through to 6 means >. Input Mappings have been used (as shown in the diagram) to make these more readable. The full input list is:
Having determined the validity of the request, C1 and C2 determine what the new values for the top row and left column are: the changed values (A1 and A2) if valid, or the input values (Y1 and Y2) if invalid. C1 and C3 are specified as the next values of Y1 and Y2, to be remembered for the next cycle.
With the new (or unchanged) position of the object determined, all that remains is to ensure that the Animation Zone displays the object in this position.
The Table Construction box, U1, uses the Change block values operation, which takes an input table (defined by inputs la and ncols) and sets of parameters in lc that will define changes made to blocks of values in the input list to create the output list. Unusually, the value d is not used but a value must still be given.
Each set of parameters in lc takes the following form: TLR (Row of top left cell of block), TLC (Column of top left cell of block), H (height of block in cells), W (width of block in cells), followed by HxW values that will become the new values for the defined block in the output. It is important to note that later sets of parameters in the overall list may overwrite changes made by earlier sets of parameters.
In this case, la is specified as G1, a background of 0s, ncols=D4 (board size) and lc is specified by just one set of parameters, C1 C2 D2 D3 E1, where C1 and C2 are the top row and left column of the object, D2 and D3 are the height and width of the object, and E1 is a list of the format codes for the object (note the inclusion of some 0s in E1 so that those cells will merge into the background, resulting in an object that looks man-shaped rather than rectangular). U1 must be specified as the Cell formats list for the Animation Zone.
You must also specify a termination condition for repetitions, otherwise there will be only one cycle. There is no clear stopping point, and the intention in this case is just to test movement of the object in response to the keypad presses. So, set the condition to a check that should never succeed, such as 1 > 2. Press Start to test the behaviour.
Creating complex images in the Animation Zone
A game such as Alien Invasion involves many objects, some of which can move, some of which can be fired (missiles) or dropped (bombs), and most of which can be destroyed. Building up the image at each cycle must take care of all of these. Typically, such images (or the format codes for the image) will make use of operations in the Table Construction numipulation boxes. One such operation is Change block values, as discussed above.
Box U2 shows how this is used to create the table (list of numbers) for Alien Invasion. This time, several sets of parameters are used. The full text in lc is:
This is a very simple-looking piece of code, but the result output will have 3600 (60x60) values in it. G1 in la inputs the 60x60 background values. In lc, the most straightforward line to understand is the second: 52 A4 3 5 O12. 52 is the top-left corner row of the missile launcher (it is always 52 as it moves horizontally only), A4 is the top-left corner column of the missile launcher, which will vary as it is moved using the keypad, the 3 and 5 are the height and width of the missile launcher block, and O12
will normally (unless it's just been hit) result in the launcher format code:
Similar to the parameters that were generated for Change values in the Small red ball program above, some of these lines may have a value that is an empty list. For example, missiles are dependent on the players actions, so there may not be one. The Red ship moves across randomly, so this may also be an empty list. The remaining aliens parameters may contain many values - the number reducing as aliens are shot down. If an alien has just been hit by a missile, it will still exist so, for simplicity, it will first be added with its usual values in parameters S7, but then these will be overwritten by O6, which will define format codes for an alien that has just been hit. At other times, O6 will be an empty list. R2 (Bomb image parameters) will never be empty and will contain only five values, as it occupies only one cell.
Note that the format codes here are all positive (as for the missile launcher). The whole list is later multiplied by -1 to give the borderless cells required.
Seeing shape data for the Animation Zone
In the Fun Runner game, the runner is made up of a head, a body, two arms and two legs. The flexible input layout of number lists means that you can see the shape you're defining in the data. To explain, part of the data for arms is as follows, one of 8 positions for an arm, which can be seen in the table:
The 0s represent the background, the 1s represent the track suit (these will be replaced by the code for the appropriate shade of grey, depending on whether the arm is near or far, and the 7s represent hands. Designing shapes can be quite easy in this way.
Copyright TopAccolades Limited, 2023