Во времена XTшек и ДОС был у меня вариант Сокобана, реализованный в виде махонького бинаря, размером менее десяти килобайт. Называлось это чудо pusher.exe и выглядело вот так:
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/44e/19f/2dd/44e19f2dd61c548f55c0ff7239a3b5c7.png)
Это был простой уровень, но как насчет вот такого?
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/5ee/2cf/e87/5ee2cfe879ee7b910b0002385ec50039.png)
Элементарно запускается через DOSEmu:
Кому лень запускать можно посмотреть демку:
И стало мне интересно, как шестьдесят уровней помещаются в столь небольшой бинарь. Поковырявшись немного IDA'ой, я написал программку, которая выдирает из бинаря `pusher.exe` все уровни и печатает их в текстовом виде:
Можно скачать сразу все уровни.
Уровни сжаты чем-то вроде Хаффмана — битовыми цепочками переменной длины. Каждый уровень кодируется следующим образом:
В файле pushermaps.c можно увидеть весь нехитрый декомпрессор.
В процессе дизассемблирования образовались уровни в удобном текстовом, но все еще сжатом виде, например:
Так что если захочется где-нибудь забацать свой простенький и компактный Сокобан, какое-то количество уровней можно взять готовыми.
Знаю, что в интернете полно уровней для Сокобана, и автоматические решалки имеются, но это совершенно не отменяет фан копания дизассемблером в бинаре более чем двадцати летней давности.
Проект на GitHub'e — github.com/begoon/sokoban-maps, если кому интересно.
![](https://habrastorage.org/getpro/habr/post_images/44e/19f/2dd/44e19f2dd61c548f55c0ff7239a3b5c7.png)
Это был простой уровень, но как насчет вот такого?
![](https://habrastorage.org/getpro/habr/post_images/5ee/2cf/e87/5ee2cfe879ee7b910b0002385ec50039.png)
Элементарно запускается через DOSEmu:
DOSEmu -exit pusher.exe
.Кому лень запускать можно посмотреть демку:
И стало мне интересно, как шестьдесят уровней помещаются в столь небольшой бинарь. Поковырявшись немного IDA'ой, я написал программку, которая выдирает из бинаря `pusher.exe` все уровни и печатает их в текстовом виде:
*************************************
Maze: 1
File offset: 148C, DS:00FC, table offset: 0000
Size X: 22
Size Y: 11
End: 14BD
Length: 50
XXXXX
X X
X* X
XXX *XXX
X * * X
XXX X XXX X XXXXXX
X X XXX XXXXXXX ..X
X * * ..X
XXXXX XXXX X@XXXX ..X
X XXX XXXXXX
XXXXXXXX
*************************************
Можно скачать сразу все уровни.
Уровни сжаты чем-то вроде Хаффмана — битовыми цепочками переменной длины. Каждый уровень кодируется следующим образом:
- Размер карты по X (1 байт).
- Размер карты по Y (1 байт).
- X*Y байт самой карты, которая представлена последовательностью пар
[СЧЕТЧИК][КОД СИМВОЛА]. СЧЕТЧИК — это либо один бит 0, если символ
только один, либо четыре бита «1 D3 D2 D1», и тогда количество повторений
рассчитывается по формуле «N = 2 + D3*4 + D2*2 + D1», то есть от 2-х до
9-и символов. КОД СИМВОЛА имеет пять разных значений: 00 — пустое место,
01 — стена, 10 — бочка, 110 — место для бочки, 111 — бочка, уже стоящая - Начальная позиция игрока по X (1 байт).
- Начальная позиция игрока по Y (1 байт).
В файле pushermaps.c можно увидеть весь нехитрый декомпрессор.
В процессе дизассемблирования образовались уровни в удобном текстовом, но все еще сжатом виде, например:
level_01 db 16h, 0Bh, 0A2h, 0DFh, 38h, 32h, 1Fh, 38h, 2Ah, 3, 0E6h
db 12h, 0C0h, 0A5h, 0F2h, 83h, 2, 81h, 3, 0E4h, 12h, 82h
db 25h, 6, 0CDh, 64h, 22h, 51h, 0ACh, 11h, 0A1h, 0Ah, 5
db 0E5h, 11h, 0B1h, 14h, 82h, 29h, 82h, 31h, 0A0h, 0E1h
db 2Ch, 18h, 0D1h, 0CFh, 80h, 0Ch, 8
level_02 db 0Eh, 0Ah, 0F6h, 58h, 0Ch, 68h, 0Dh, 94h, 0C6h, 80h
db 85h, 2, 82h, 18h, 0D0h, 15h, 4Ch, 10h, 0C6h, 0C2h, 18h
db 21h, 8Dh, 1, 6, 4, 39h, 10h, 0A0h, 81h, 80h, 85h, 2
db 8, 20h, 60h, 34h, 1Bh, 0Ch, 1Eh, 0CAh, 7, 4
level_03 db 11h, 0Ah, 0E3h, 9Fh, 0Eh, 7, 0C2h, 11h, 42h, 1Fh, 8
db 50h, 23h, 0E0h, 85h, 4, 0Ch, 1Eh, 84h, 8, 0A6h, 0B4h
db 10h, 85h, 2, 82h, 59h, 0D4h, 28h, 14h, 90h, 0D6h, 83h
db 0DFh, 7Ch, 0Eh, 1
И т.д. Так что если захочется где-нибудь забацать свой простенький и компактный Сокобан, какое-то количество уровней можно взять готовыми.
Знаю, что в интернете полно уровней для Сокобана, и автоматические решалки имеются, но это совершенно не отменяет фан копания дизассемблером в бинаре более чем двадцати летней давности.
Проект на GitHub'e — github.com/begoon/sokoban-maps, если кому интересно.