c语言m行n列地图小游戏,【C语言+双层BFS算法】自动生成可解地图的推箱子小游戏...

[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

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值