[C] 纯文本查看 复制代码#include "map.h"
int player[2] = {H / 2, L / 2};
char map[H][L];
int next[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int boxNum = 0, boxes[H * L][2], purs[H * L][2];
/*----------------------------------*/
/* 生成地图(newMap)
/*----------------------------------*/
typedef struct listNode{
int x;
int y;
struct listNode *p;
}list;
int wallCheck(int x, int y){
if(map[x][y] != 1)
return map[x][y];
if(map[x + 1][y] + map[x - 1][y] + map[x + 1][y + 1] + map[x - 1][y - 1] +
map[x][y + 1] + map[x][y - 1] + map[x - 1][y + 1] + map[x + 1][y - 1] < 8)
return 1;
return 0;
}
int fullwallCheck(int x, int y){
if(map[x][y] == 2)
return 2;
if(map[x + 1][y] == 2 || map[x - 1][y] == 2 || map[x + 1][y + 1] == 2 || map[x - 1][y - 1] == 2 ||
map[x][y + 1] == 2 || map[x][y - 1] == 2 || map[x - 1][y + 1] == 2 || map[x + 1][y - 1] == 2)
return 1;
return 0;
}
void wallAdd(int x, int y, int direction, int k){
if(abs(x - H / 2) <= 1 && abs(y - L / 2) <= 1) // situation 1: spawn point
return;
if(x == 0 || x == H - 1 || y == 0 || y == L - 1) // situation 2: map edges
return;
if(k >= 5) // situation 3: too long
return;
if(rand() % 100 < 60) // situation 4: random
return;
map[x][y] = 1;
wallAdd(x + next[direction][0], y + next[direction][1], direction, k+1);
}
void mapMake(){
char book[H][L], a, b;
int que[H * L][2] = {{H / 2, L / 2}}, head = 0, tail = 1;
// 0. 初始化地图
{
for(int i = 0; i < H; i++)
for(int j = 0; j < L; j++)
map[i][j] = book[i][j] = 0;
player[0] = H / 2;
player[1] = L / 2;
map[H / 2][L / 2] = book[H / 2][L / 2] = 1;
}
// prt();
// 1. 生成wall (use queue)
{
while(head != tail){ // bfs + random
a = que[head][0];
b = que[head][1];
for(int j = 0; j < 4; j++){
if(a <= H / 4 || a > H / 4 * 3 || b <= L / 4 || b > L / 4 * 3)
if((rand() % 2)) continue;
if(a + next[j][0] >= 0 && a + next[j][0] <= H - 1 &&
b + next[j][1] >= 0 && b + next[j][1] <= L - 1)
if(book[a + next[j][0]][b + next[j][1]] == 0){
map[a + next[j][0]][b + next[j][1]] = 1;
book[a + next[j][0]][b + next[j][1]] = 1;
que[tail][0] = a + next[j][0];
que[tail][1] = b + next[j][1];
tail++;
}
}
head++;
}
}
// prt();
// 2. 美化墙面
{
for(int i = 0; i < H; i++) // make edges empty
map[i][0] = map[i][L - 1] = 0;
for(int j = 0; j < L; j++) // make edges empty
map[0][j] = map[H - 1][j] = 0;
for(int i = 0; i < H; i++) // refresh book
for(int j = 0; j < L; j++)
book[i][j] = map[i][j];
}
// prt();
// 3. 查找有效墙面 (与empty接壤)
{
for(int i = 1; i < H - 1; i++) // replace book
for(int j = 1; j < L - 1; j++)
book[i][j] = wallCheck(i, j);
for(int i = 0; i < H; i++) // refresh map
for(int j = 0; j < L; j++)
map[i][j] = book[i][j];
}
// prt();
// 4. 添加内部障碍墙 (随机替换一部分empty为wall)
{
for(int i = H * L; i > 0; i--){
int pos = rand() % tail;
a = que[pos][0];
b = que[pos][1];
wallAdd(a, b, rand() % 2, 0);
}
for(int i = 0; i < H; i++) // refresh book
for(int j = 0; j < L; j++)
book[i][j] = map[i][j];
}
// prt();
// 5. 生成floor (use queue)
{
map[H / 2][L / 2] = book[H / 2][L / 2] = 2;
head = 0, tail = 1; // reset queue
while(head != tail){ // bfs
a = que[head][0];
b = que[head][1];
for(int j = 0; j < 4; j++){
if(book[a + next[j][0]][b + next[j][1]] == 0){
map[a + next[j][0]][b + next[j][1]] = 2;
book[a + next[j][0]][b + next[j][1]] = 2;
que[tail][0] = a + next[j][0];
que[tail][1] = b + next[j][1];
tail++;
}
}
head++;
}
}
// prt();
// 6. 查找有效墙面 (与floor接壤)
{
for(int i = 1; i < H - 1; i++)
for(int j = 1; j < L - 1; j++)
book[i][j] = fullwallCheck(i, j);
for(int i = 0; i < H; i++)
for(int j = 0; j < L; j++)
map[i][j] = book[i][j];
}
// prt();
// 7. 放置实体 (box, purpose, player)
{
// 队列(que) -> 链表(list)
int floor_n = tail - 1;
list floor;
list *p = &floor, *tp = p;
for(int i = 0; i < tail; i++){ // init list
tp->p = (list *)malloc(sizeof(list));
tp->x = que[i][0];
tp->y = que[i][1];
tp = tp->p;
}
tp->p = 0;
// create box, purpose
tp = p;
list *box, *pur;
int place;
boxNum = floor_n / 5 + 1;
for(int i = 0; i < boxNum; i++){
if(p->p == 0) break;
place = rand() % floor_n + 1; // find box
for(int j = 1; j < place; j++) // tp : box - 1
tp = tp->p;
box = tp->p;
boxes[i][0] = box->x;
boxes[i][1] = box->y;
map[box->x][box->y] = 3; // set box, del floor
tp->p = box->p;
free(box);
floor_n--;
tp = p;
}
for(int i = 0; i < boxNum; i++){
if(p->p == 0) break;
place = rand() % floor_n + 1; // find purpose
for(int j = 1; j < place; j++) // tp : purpose - 1
tp = tp->p;
pur = tp->p;
purs[i][0] = pur->x;
purs[i][1] = pur->y;
map[pur->x][pur->y] = 5; // set purpose, del floor
tp->p = pur->p;
free(pur);
floor_n--;
tp = p;
}
tp = p->p; // clear memory
list *nextp;
do{
nextp = tp->p;
free(tp);
tp = nextp;
}while(nextp);
map[player[0]][player[1]] = 6; // set player
}
}