1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2025-03-01

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

https://qiita.com/ELIXIR/items/3ada72c77a43f786977e
https://https://en.wikipedia.org/wiki/Entombed_(Atari_2600)

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 にしてみた。

#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

ワザと泥臭い感じを狙いましたが、まぁ、大して変わりません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?