History of creation
"Snake" (Python, Boa) as it is called by the people is one of the first games of the digital (computer) mid-1970s.
At that time, games were released on a separate gaming machine, for example, such games as “Space Invaders”, “Pac-Man”, “Arkanoid” and others are known. Usually, only one game was preinstalled on the arcade machines of that time, and the machine itself was styled as this game.
"Snake" has a simple gameplay in which the player controls the moving line, depicting a snake. The player can change the direction of movement of the snake "turning" by 90 degrees. The goal of the game is to “hit” a snake on the dots depicting rabbits. Each rabbit eaten increases the length of the snake. The difficulty lies in the fact that the snake can not cross itself.
Since its introduction, "Snake" has experienced many incarnations on different devices. For example, on some devices, instead of the line, the snake could appear as a string of characters due to technical limitations. In other, more modern computers, the snake could turn at an arbitrary angle, and not just 90 degrees.
')
In other words, such a simple game and its idea was transferred to almost all possible computing equipment. Including programmable microcalculators, and microcontrollers that control refrigerators and other household appliances.
The idea of ​​"Snake" is popular and now - the recent "boom" fell on the reincarnation in the form of a multiplayer online game "slither.io".
As an enthusiast of programming, I have met a lot of programming literature, where one of the training programs was the game Snake. Also in the periodicals came across articles of a competitive nature, in which people offered their versions of "Snake", trying to meet the certain technical limitations of a particular computer.
I, in turn, also practiced writing this game in different languages ​​and platforms. One day, while reading the e-zine on the ZX-Spectrum, I came across an article whose author met the 256 bytes by programming the Snake. At the end of the article, the author stated that it is unlikely that anyone will be able to write a game shorter than 256 bytes on the ZX-Spectrum platform. But after a while there was a version of 121 bytes from another author. True, while reducing the size of the code, the gameplay suffered.
After some time, talking with one novice programmer, I advised him to write at least some finished project. Then we are talking about the "Snake". I remembered that this could be of a competitive nature and decided to stir up the interest of my interlocutor by telling him that I would write my implementation of the game with an emphasis on the minimum code size. To complicate the problem, I decided to use the same ZX-Spectrum platform and Z80 processor assembler.
I wrote the first version of the game in a couple of hours and it weighed a little more than 150 bytes. Then I remembered an article in an electronic journal, and decided to break the record of 121 bytes. So my next version already weighed 100 bytes. Writing took 6 hours already. After that, I did not return to this game for a long time.
Later, when sorting out the folder with my projects and sources, I came across the source code of my Snake and realized that the code could be modified and shortened by a couple of bytes. The optimization process took a whole day, and the code was reduced by only 5 bytes. Nevertheless, the code of the game began to "weigh" a record 93 bytes.
Technical details
Technical details of the game 93-byte snake
- 58 lines of code without comment
- Full program relocability (placement to any address without recompilation)
- Unused stack
- Only the main set of registers is used: a, b, c, d, e, h, l and r as a generator of randomness
- Without the use of ROM procedures
- Fair screen and border initialization
- Classic key management: 6,7,8,9 (Sinclair Joystick)
- Each initialization of rabbits pseudo-randomly arranged
The code consists of 3 blocks
- Initializing Variables and Screen
- Poll keys to press and change direction
- Handling game events
Registers are mainly used as named variables, as follows:
- Register a - used by as an intermediate result and a manipulator with separate bits
- Register pair bc - this direction of movement takes only 4 values ​​for the entire gameplay: # ffe0, # 0020, # 0001, #ffff
- Register pair de is the current array processing index (attribute)
- Register pair hl is the current coordinates of the snake head in the address attribute space
In the initialization block de and hl, swapped to reduce the logical distribution operation of rabbits
The game uses two global cycles, from the beginning of the program to the end (full initialization) and the game cycle (after placing the rabbits)
Game code
begin ld de,#598f;snake xy ld hl,#5aff ld b,l ld c,l ;
Algorithm
The image on the screen in this case is available in memory as a one-dimensional array of 32 * 24. Each cell occupies one byte of memory. By changing the values ​​of these cells, you can set the color of each “square” on the screen. The format in bits is% FBPPPIII where: F-Flash “flashing” bit once per second (ink-to-paper exchange), B-Bright high brightness, PPP-Paper 0 to 7, III-INK 0 to 7.
- 0 000 Black
- 1 001 Blue
- 2,010 Red
- 3 011 Purple
- 4 100 Green
- 5 101 Blue
- 6 110 Yellow
- 7 111 White
Thus, Rabbits are encoded with a value of 255 (blinking, bright, white background, white color), empty space is encoded with a value of zero (black background, black color)
Unlike other implementations, the storage of the "snake" is not allocated a separate array in memory, and it is immediately in the "screen" memory. The length of the snake and the number of “eaten rabbits” is stored in the form of head color, since the larger value looks “brighter”, simple arithmetic occurs, the entire array goes over and the number of rabbits adds up to the base color of the head. The movement of the snake’s entire body occurs by processing the entire array where, each value is simply reduced by one to black.
Handling game events is just a few logical branches "IF", when moving the head to the next array index, the previous value is checked, if there is not a rabbit and not empty space, then the snake has run into itself. Another “IF” if the snake's head has the maximum color after checking the array, then all the rabbits are eaten.
UPD Updated sources, as I was able to optimize from 95 bytes to 93 bytes, without losing functionality.
UPD2 Added section Algorithm.