Unfinished: rand map gen
This commit is contained in:
10
src/main.cc
10
src/main.cc
@ -19,12 +19,12 @@ int main(int argc, char **argv) {
|
|||||||
return RETURN_PANICKED;
|
return RETURN_PANICKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
CC3K game_proc(enabled_features, *in, *out, *log, *rng);
|
// CC3K game_proc(enabled_features, *in, *out, *log, *rng);
|
||||||
|
|
||||||
while (game_proc.run() != game_status::terminated) {
|
// while (game_proc.run() != game_status::terminated) {
|
||||||
out->render();
|
// out->render();
|
||||||
out->clear();
|
// out->clear();
|
||||||
}
|
// }
|
||||||
|
|
||||||
return RETURN_FINE;
|
return RETURN_FINE;
|
||||||
}
|
}
|
||||||
|
123
src/map.cc
123
src/map.cc
@ -1,8 +1,68 @@
|
|||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
game_map::game_map(RNG &rng, const feature enabled_features):
|
game_map::game_map(RNG &rng, const feature enabled_features):
|
||||||
enabled_features{enabled_features} {
|
enabled_features{enabled_features} {
|
||||||
|
map.reserve(MAP_HEIGHT * MAP_WIDTH);
|
||||||
|
|
||||||
|
for (int i = MAP_HEIGHT * MAP_WIDTH; i > 0; --i)
|
||||||
|
map.push_back(-1);
|
||||||
|
|
||||||
|
// Note: during generation, walls DO NOT count as being in the rooms
|
||||||
|
std::vector<std::pair<position, int>> room_dims = gen_room_dims(rng);
|
||||||
|
|
||||||
|
// width height top left
|
||||||
|
std::vector<std::pair<position, position>> room_data = distr_rooms(rng,
|
||||||
|
room_dims);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<position, position>> game_map::distr_rooms(RNG &rng,
|
||||||
|
std::vector<std::pair<position, int>> &room_dims) {
|
||||||
|
std::vector<std::pair<position, position>> result{room_dims.size()};
|
||||||
|
|
||||||
|
int max_layer = room_dims[room_dims.size() - 1].second;
|
||||||
|
std::vector<int> layer_heights{max_layer + 1};
|
||||||
|
|
||||||
|
// distributing rooms horizontally
|
||||||
|
for (int layer = 0; layer <= max_layer; ++layer) {
|
||||||
|
int l = INF;
|
||||||
|
int r = 0;
|
||||||
|
int layer_height = 0;
|
||||||
|
|
||||||
|
// get the interval for the current layer
|
||||||
|
// and the max height of the layer
|
||||||
|
for (std::size_t i = 0; i < room_dims.size(); ++i)
|
||||||
|
if (room_dims[i].second == layer) {
|
||||||
|
l = std::min(l, (int)i);
|
||||||
|
r = std::max(r, (int)i);
|
||||||
|
layer_height = std::max(layer_height,
|
||||||
|
room_dims[i].first.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
layer_heights.push_back(layer_height);
|
||||||
|
|
||||||
|
// distribute the current layer
|
||||||
|
if (l == r) {
|
||||||
|
result.push_back({room_dims[l].first,
|
||||||
|
{rng.rand_under(ACTUAL_MAP_WIDTH - room_dims[l].first.x + 1), 0}});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = room_dims[l].first.x;
|
||||||
|
int right = ACTUAL_MAP_WIDTH;
|
||||||
|
|
||||||
|
// every time, distribute the last one first
|
||||||
|
for (int i = l + 1; i < r; ++i)
|
||||||
|
left += MIN_ROOM_SPACING + room_dims[i].first.x;
|
||||||
|
|
||||||
|
for (int i = r; i > l; --i) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
game_map::game_map(const std::string &map_data,
|
game_map::game_map(const std::string &map_data,
|
||||||
@ -39,6 +99,12 @@ const position_list game_map::get_available_positions() const {
|
|||||||
return empty_spots;
|
return empty_spots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool game_map::is_available(const position &pos) const {
|
||||||
|
int idx = remap_position(pos);
|
||||||
|
return map[idx] <= 9 || map[idx] == '\\' || map[idx] == '>' ||
|
||||||
|
map[idx] == '<' || map[idx] == '+' || map[idx] == '#';
|
||||||
|
}
|
||||||
|
|
||||||
void game_map::print(display &out) const {
|
void game_map::print(display &out) const {
|
||||||
for (std::size_t i = 0; i < map.size(); ++i)
|
for (std::size_t i = 0; i < map.size(); ++i)
|
||||||
out.print_char(remap_index(i), map[i] <= 9 ? '.' : map[i],
|
out.print_char(remap_index(i), map[i] <= 9 ? '.' : map[i],
|
||||||
@ -80,3 +146,60 @@ const std::vector<position_list>game_map::get_room_list() const {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<position, int>> game_map::gen_room_dims(RNG &rng) {
|
||||||
|
position_list room_dim_list{MAX_ROOM_CNT};
|
||||||
|
std::vector<std::pair<position, int>> result{MAX_ROOM_CNT};
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_ROOM_CNT; ++i)
|
||||||
|
room_dim_list.push_back(random_size(MIN_ROOM_WIDTH, MIN_ROOM_HEIGHT,
|
||||||
|
MAX_ROOM_WIDTH, MAX_ROOM_HEIGHT,
|
||||||
|
rng));
|
||||||
|
|
||||||
|
int curr_top = 0;
|
||||||
|
int curr_left = 0;
|
||||||
|
// index in result
|
||||||
|
int curr_layer_idx = 0;
|
||||||
|
int curr_layer_cnt = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_ROOM_CNT &&
|
||||||
|
curr_top <= ACTUAL_MAP_HEIGHT &&
|
||||||
|
curr_left <= ACTUAL_MAP_WIDTH; ++i) {
|
||||||
|
// DO NOT update curr_top until curr_left is exhausted
|
||||||
|
if (curr_top + MIN_ROOM_SPACING +
|
||||||
|
room_dim_list[i].y + HEIGHT_RESERVED <= ACTUAL_MAP_HEIGHT &&
|
||||||
|
curr_left + MIN_ROOM_SPACING +
|
||||||
|
room_dim_list[i].x + WIDTH_RESERVED <= ACTUAL_MAP_WIDTH) {
|
||||||
|
result.push_back({room_dim_list[i], curr_layer_cnt});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp = curr_top;
|
||||||
|
|
||||||
|
for (std::size_t j = curr_layer_idx; j < result.size(); ++j)
|
||||||
|
tmp = std::max(curr_top + result[j].first.y + MIN_ROOM_SPACING,
|
||||||
|
tmp);
|
||||||
|
|
||||||
|
curr_top = tmp;
|
||||||
|
curr_layer_idx = result.size();
|
||||||
|
curr_left = 0;
|
||||||
|
++curr_layer_cnt;
|
||||||
|
|
||||||
|
if (curr_top + MIN_ROOM_SPACING +
|
||||||
|
room_dim_list[i].y + HEIGHT_RESERVED <= ACTUAL_MAP_HEIGHT &&
|
||||||
|
curr_left + MIN_ROOM_SPACING +
|
||||||
|
room_dim_list[i].x + WIDTH_RESERVED <= ACTUAL_MAP_WIDTH)
|
||||||
|
result.push_back({room_dim_list[i], curr_layer_cnt});
|
||||||
|
}
|
||||||
|
|
||||||
|
result.shrink_to_fit();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
position random_size(int min_width, int min_height,
|
||||||
|
int max_width, int max_height,
|
||||||
|
RNG &rng) {
|
||||||
|
return {rng.rand_between(min_width, max_width + 1),
|
||||||
|
rng.rand_between(min_height, max_height + 1)};
|
||||||
|
}
|
||||||
|
25
src/map.h
25
src/map.h
@ -2,14 +2,27 @@
|
|||||||
#define __MAP_H__
|
#define __MAP_H__
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "characters.h"
|
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
|
||||||
class game_map final {
|
class game_map final {
|
||||||
private:
|
private:
|
||||||
|
static const int MAX_ROOM_CNT = 20;
|
||||||
|
static const int MIN_ROOM_WIDTH = 3;
|
||||||
|
static const int MIN_ROOM_HEIGHT = 3;
|
||||||
|
static const int MAX_ROOM_WIDTH = 20;
|
||||||
|
static const int MAX_ROOM_HEIGHT = 13;
|
||||||
|
// setup safezones
|
||||||
|
static const int ACTUAL_MAP_WIDTH = MAP_WIDTH - 4;
|
||||||
|
static const int ACTUAL_MAP_HEIGHT = MAP_HEIGHT - 4;
|
||||||
|
static const int MAP_PADDING = 1;
|
||||||
|
static const int MIN_ROOM_SPACING = 4;
|
||||||
|
static const int WIDTH_RESERVED = 8;
|
||||||
|
static const int HEIGHT_RESERVED = 4;
|
||||||
|
|
||||||
const feature enabled_features;
|
const feature enabled_features;
|
||||||
std::vector<char> map;
|
std::vector<char> map;
|
||||||
// IMPORTANT: keep empty_spots ordered
|
// IMPORTANT: keep empty_spots ordered
|
||||||
@ -25,6 +38,7 @@ public:
|
|||||||
const feature enabled_features);
|
const feature enabled_features);
|
||||||
|
|
||||||
const position_list get_available_positions() const;
|
const position_list get_available_positions() const;
|
||||||
|
bool is_available(const position &pos) const;
|
||||||
|
|
||||||
const std::vector<position_list> get_room_list() const;
|
const std::vector<position_list> get_room_list() const;
|
||||||
// IMPORTANT: always print a map before anything else
|
// IMPORTANT: always print a map before anything else
|
||||||
@ -43,6 +57,15 @@ private:
|
|||||||
int remap_position(const position &pos) const {
|
int remap_position(const position &pos) const {
|
||||||
return pos.y * MAP_WIDTH + pos.x;
|
return pos.y * MAP_WIDTH + pos.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
position random_size(int min_width, int min_height,
|
||||||
|
int max_width, int max_height,
|
||||||
|
RNG &rng);
|
||||||
|
|
||||||
|
std::vector<std::pair<position, int>> gen_room_dims(RNG &rng);
|
||||||
|
std::vector<std::pair<position, position>> distr_rooms(RNG &rng,
|
||||||
|
std::vector<std::pair<position, int>>
|
||||||
|
&room_dims);
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string default_map =
|
const std::string default_map =
|
||||||
|
Reference in New Issue
Block a user