Ejemplo n.º 1
0
 void initmap(void)
 {
	int xi, yi;
 
	grid  = (int**)malloc(sizeof(int*) * size_y);
	grid2 = (int**)malloc(sizeof(int*) * size_y);
 
	for(yi=0; yi<size_y; yi++)
	{
		grid [yi] = (int*)malloc(sizeof(int) * size_x);
		grid2[yi] = (int*)malloc(sizeof(int) * size_x);
	}
 
	for(yi=1; yi<size_y-1; yi++)
	for(xi=1; xi<size_x-1; xi++)
		grid[yi][xi] = randpick();
 
	for(yi=0; yi<size_y; yi++)
	for(xi=0; xi<size_x; xi++)
		grid2[yi][xi] = TILE_WALL;
 
	for(yi=0; yi<size_y; yi++)
		grid[yi][0] = grid[yi][size_x-1] = TILE_WALL;
	for(xi=0; xi<size_x; xi++)
		grid[0][xi] = grid[size_y-1][xi] = TILE_WALL;
 }
Ejemplo n.º 2
0
bool cave_generate_map(struct dm_map *map, struct random *r, enum dm_dungeon_type type, coord_t *ul, coord_t *dr) {
    FIX_UNUSED(type);

    /* initialise cellular automata */
    coord_t size = { .x = dr->x - ul->x, .y = dr->y - ul->y, };
    struct ca_map *cmap = ca_init(&size);

    /* fill the map randomly with floors */
    coord_t p;
    for (p.y = 0; p.y < size.y; p.y++) {
        for (p.x = 0; p.x < size.x; p.x++) {
            ca_set_coord(cmap, &p, randpick(r, 45) );
        }
    }

    /* Fill the map with large caves */
    for (int  i = 0; i < 4; i++) {
        ca_generation(cmap, 16, 8, 2);
    }

    /* Do a few passes to make them less smooth */
    for (int  i = 0; i < 2; i++) {
        int ri = (random_int32(r) % 4) +2;
        ca_generation(cmap, 5, ri, 1);
    }

    /* translate the ca_map to the real map */
    for(p.y = 0; p.y < size.y; p.y++) {
        for(p.x = 0; p.x < size.x; p.x++) {
            coord_t c = cd_add(ul, &p);

            /* check if the cell is alive or dead */
            if (ca_get_coord(cmap, &p) == CA_ALIVE) {
                /* fill the tile with the specified type */
                if(random_int32(r)%100 < 1) {
                    dm_get_map_me(&c,map)->tile = ts_get_tile_specific(TILE_ID_MAD_CAP_FUNGUS);
                }
                else dm_get_map_me(&c,map)->tile = ts_get_tile_specific(TILE_ID_CONCRETE_FLOOR);
            }
        }
    }

    /* cleanup and return */
    ca_free(cmap);
    return true;
}
Ejemplo n.º 3
0
void Level::Generate() {

    // allocate memory for levels
    Tile** new_map = new Tile* [_h];
    Tile** flooded_map = new Tile* [_h];
    for(uint i = 0; i < _h; i++) {
        new_map[i] = new Tile [_w];
        flooded_map[i] = new Tile [_w];
    }

    while(1) {
        // randomly fill starting level
        for(uint y = 1; y < _h -1; y++) {
            for(uint x = 1; x < _w; x++) {
                _map[y][x] = tiles[randpick()];
            }
        }

        // fill temp level with walls
        for(uint y = 0; y < _h; y++) {
            for(uint x = 0; x < _w; x++) {
                new_map[y][x] = tiles[MAP_WALL];
            }
        }

        // ensure the level has outer walls
        for(uint y = 0; y < _h; y++) {
            _map[y][0] = _map[y][_w-1] = tiles[MAP_WALL];
        }
        for(uint x = 0; x < _w; x++) {
            _map[0][x] = _map[_h-1][x] = tiles[MAP_WALL];
        }

        // run cellular autonoma algorithm
        for(uint y = 1; y < _h - 1; y++) {
            for(uint x = 1; x < _w - 1; x++) {
                int adjcount_r1 = 0,
                    adjcount_r2 = 0;

                for(int i = -1; i <= 1; i++) {
                    for(int j = -1; j <= 1; j++) {
                        if(_map[y+i][x+j].type != MAP_FLOOR) adjcount_r1++;
                    }
                }

                for(uint i = y - 2; i <= y + 2; i++) {
                    for(uint j = x - 2; j <= x + 2; j++) {
                        if(abs(i-y) == 2 && abs(j-x) == 2) continue;
                        if(i >= _h || j >= _w) continue;
                        if(_map[i][j].type != MAP_FLOOR) adjcount_r2++;
                    }
                }

                // select new tile for this position
                if(adjcount_r1 >= _r1_cutoff || adjcount_r2 <= _r2_cutoff) {
                    new_map[y][x] = tiles[MAP_WALL];
                }
                else {
                    new_map[y][x] = tiles[MAP_FLOOR];
                }
            }
        }

        // flood map from random floor cell
        int rnd_x, rnd_y;
        while(1) {
            rnd_x = rand() % _w;
            rnd_y = rand() % _h;

            if(new_map[rnd_y][rnd_x].type == MAP_FLOOR) break;
        }

        for(uint y = 0; y < _h; y++) {
            for(uint x = 0; x < _w; x++) {
                flooded_map[y][x] = tiles[MAP_WALL];
            }
        }

        floodmap(new_map, flooded_map, rnd_x, rnd_y);

        // ensure that at least 1/2 of the map is floor
        uint floorcount = 0;
        for(uint y = 0; y < _h; y++) {
            for(uint x = 0; x < _w; x++) {
                if(flooded_map[y][x].type == MAP_FLOOR) floorcount++;
            }
        }

        if(floorcount > (_w*_h)/2) break;
    }

    // place stairs
    int rnd_x, rnd_y;
    while(1) {
        rnd_x = rand() % _w;
        rnd_y = rand() % _h;

        if(flooded_map[rnd_y][rnd_x].type == MAP_FLOOR) {
            flooded_map[rnd_y][rnd_x] = tiles[MAP_STAIR_DOWN];
            _stairDown.x = rnd_x;
            _stairDown.y = rnd_y;
            break;
        }
    }
    while(1) {
        rnd_x = rand() % _w;
        rnd_y = rand() % _h;

        if(flooded_map[rnd_y][rnd_x].type == MAP_FLOOR) {
            flooded_map[rnd_y][rnd_x] = tiles[MAP_STAIR_UP];
            _stairUp.x = rnd_x;
            _stairUp.y = rnd_y;
            break;
        }
    }

    // replace map with new one
    for(uint y = 1; y < _h - 1; y++) {
        for(uint x = 1; x < _w -1; x++) {
            _map[y][x] = flooded_map[y][x];
        }
    }

    // free memory used up by temporary maps
    for(uint i = 0; i < _h; i++) {
        delete [] new_map[i];
        delete [] flooded_map[i];
    }
    delete [] new_map;
    delete [] flooded_map;

    // scatter items around level
    for(uint i = 0; i < LEVEL_HEIGHT / 2; i++) {
        Die tmp = {1, _h-1, 0};
        uint y = DieRoll::Roll(tmp);
        tmp.Set(1, _w-1, 0);
        uint x = DieRoll::Roll(tmp);

        if(_map[y][x].type == MAP_FLOOR) _map[y][x].items.push_back(Item::Generate());
    }
}