レトロゲーム "Entombed" の迷路生成

昔のゲームの迷路生成部分が謎だという動画から記事を探し、 Unity のコードと wiki のリンクが載っていたので両方見ながら java (paiza.io) で試してみました。

https://qiita.com/ELIXIR/items/3ada72c77a43f786977e
https://https://en.wikipedia.org/wiki/Entombed_(Atari_2600)
```java
import java.util.*;

//ATARI 'Entombed' Maze Generate TEST

//https://qiita.com/ELIXIR/items/3ada72c77a43f786977e
//https://en.wikipedia.org/wiki/Entombed_(Atari_2600)
public class Main {
    public static void main(String[] args) throws Exception {
        byte[] map = new byte[] {
              0,0,0,0,0,0,0,0,0,0, //データの座標が1つズレていること
            1,0,0,0,0,0,0,0,0,0
        };

        print(map);
        for(int j=0; j<20; j++) {
            update(map);
            print(map);
        }
    }

    private static final byte[] mysteryTable = { // X=0:open,1:wall,2:random
        1,1,1,2,0,0,2,2, 1,1,1,1,2,0,0,0,
        1,1,1,2,0,0,0,0, 2,0,1,2,2,0,0,0
    };
    private static final byte[] posTbl = new byte[] { 10,11,0,1,2 }; //a,b,c,d,e

    private static void update(byte[] map) {
        map[0] = wallOrOpen();
        map[9] = wallOrOpen();
        for(int x=0; x<8; x++) {
            int idx = 0;
            for(int i : posTbl) idx = (idx << 1) | map[x+i];
            byte v = mysteryTable[idx];
            if(v == 2) v = wallOrOpen();
            map[x+12] = v;
        }
        for(int i=0; i<8; i++) map[i+1] = map[i+12];
    }

    private static final Random random = new Random();
    
    private static byte wallOrOpen() {
        return (byte)random.nextInt(2);
    }

    private static final char WALL = '壁';
    private static final char OPEN = '　';
    private static char[] buf = new char[] {
        WALL, WALL,
        OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN,
        OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN,
        WALL, WALL
    };

    private static void print(byte[] map) {
        for(int i=0; i<8; i++) buf[i+2] = buf[17-i] = map[i+1]==0?OPEN:WALL;
        System.out.println(new String(buf));
    }
}
```
```
壁壁　　　　　　　　　　　　　　　　壁壁
壁壁壁壁　壁壁壁　壁壁　壁壁壁　壁壁壁壁
壁壁　　　壁　　　壁壁　　　壁　　　壁壁
壁壁　壁壁壁　壁壁壁壁壁壁　壁壁壁　壁壁
壁壁壁壁　　　　　　　　　　　　壁壁壁壁
壁壁　　　壁壁　壁壁壁壁　壁壁　　　壁壁
壁壁壁壁　壁　　壁　　壁　　壁　壁壁壁壁
壁壁　壁　壁　壁壁　　壁壁　壁　壁　壁壁
壁壁壁壁　壁　壁　　　　壁　壁　壁壁壁壁
壁壁　　　壁　壁壁　　壁壁　壁　　　壁壁
壁壁　壁壁壁　壁　　　　壁　壁壁壁　壁壁
壁壁　壁　　　壁壁壁壁壁壁　　　壁　壁壁
壁壁　壁　壁壁壁　　　　壁壁壁　壁　壁壁
壁壁壁壁　　　　　壁壁　　　　　壁壁壁壁
壁壁　壁　壁壁壁　壁壁　壁壁壁　壁　壁壁
壁壁　壁　壁　　　　　　　　壁　壁　壁壁
壁壁　壁　壁　壁壁　　壁壁　壁　壁　壁壁
壁壁　壁　壁　　　　　　　　壁　壁　壁壁
壁壁　壁　壁壁　壁壁壁壁　壁壁　壁　壁壁
壁壁壁壁　壁　　　壁壁　　　壁　壁壁壁壁
壁壁壁　　壁壁壁　　　　壁壁壁　　壁壁壁
```
それっぽいような気もしますが、何度も作ってみると結構な確率で行き止まりになるような気も…。
壁壊しアイテムがあるようなので、数個は常に持ってるような前提なんでしょうかね。

ATARI 2600 は CPU 6502 みたいで流石にどんな特徴があったのか分かりません。けれど java よりは c で書いたほうがもっとそれっぽかった(?)かも知れません。(一応配列を byte にしてみたりはしましたが。)
***
6502 をチラと見てみて、ゼロページとインデックスレジスタの使い方に技とかありそうです。
https://ja.wikipedia.org/wiki/MOS_6502
レジスタが少ない(というか無い)のでメモリを節約する為にレジスタでビット演算しようにもデータは定数かメモリからにしかならないのかな？ …懐かしい感覚。 (Z80 だった身としては実感は無いですが。)

c にしてみた。
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>

char wallOrOpen() {
    return (char)(rand() & 1);
}

char map[] = {
      0,0,0,0,0,0,0,0,0,0, //データの座標が1つズレていること
    1,0,0,0,0,0,0,0,0,0
};

char mysteryTable[] = { // X=0:open,1:wall,2:random
    1,1,1,2,0,0,2,2, 1,1,1,1,2,0,0,0,
    1,1,1,2,0,0,0,0, 2,0,1,2,2,0,0,0
};
char posTbl[] = { 10,11,0,1,2 }; //a,b,c,d,e

void update() {
    map[0] = wallOrOpen();
    map[9] = wallOrOpen();
    for(int x=0; x<8; x++) {
        int idx = 0;
        for(int i=0; i<sizeof(posTbl); i++) idx = (idx << 1) | map[x+posTbl[i]];
        char v = mysteryTable[idx];
        if(v == 2) v = wallOrOpen();
        map[x+12] = v;
    }
    for(int i=0; i<8; i++) map[i+1] = map[i+12];
}

#define WALL 'X'
#define OPEN ' '
char buf[] = "XX                XX";

void print() {
    for(int i=0; i<8; i++) buf[i+2] = buf[17-i] = map[i+1]?WALL:OPEN;
    printf("%s\n", buf);
}

int main(void) {
    srand((unsigned int)(clock() & UINT_MAX));
    print();
    for(int i=0; i<20; i++) {
        update();
        print();
    }
}
```
```
XX                XX
XX XXXX XXXX XXXX XX
XX X  X      X  X XX
XX XX XX XX XX XX XX
XXXX   X XX X   XXXX
XX XXX X    X XXX XX
XX     XX  XX     XX
XXXX XXX    XXX XXXX
XX    X  XX  X    XX
XXXXX XX    XX XXXXX
XX  X X  XX  X X  XX
XX XX X XXXX X XX XX
XXXX  X X  X X  XXXX
XXX  XX X  X XX  XXX
XXX XX  X  X  XX XXX
XXX X  XX  XX  X XXX
XX  X XX    XX X  XX
XX XX    XX    XX XX
XXXX  XX XX XX  XXXX
XX   XX  XX  XX   XX
XX XXX  XXXX  XXX XX
```
ワザと泥臭い感じを狙いましたが、まぁ、大して変わりません。