我遇到了一小块代码的问题:
for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
printf(" %d", occupy[x][y]);
}
printf(" \n");
}
我正在为Gameboy制作一个随机生成的迷宫游戏,我正在使用2D阵列来了解每个屏幕在迷宫中的位置。为了测试,我正在尝试打印该阵列,以便在继续之前我可以看到它是否正常生成。当我尝试使用那一小块代码进行编译时,我在它的顶行会出现错误,然后在文件中写出致命的编译器内部错误等等等等。那个代码中有一个我不知道的大禁忌吗?
完整代码:
#include <gb\gb.h>
#include <stdio.h>
#include <rand.h>
#define UP 0x01U
#define RIGHT 0x02U
#define DOWN 0x04U
#define LEFT 0x08U
int occupy[8][8]= {
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};
void generate(){
int temp;
int x;
int y;
UBYTE restrict;
UBYTE direction;
for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
occupy[x][y] = 0;
}
}
/* ========Occupy=Cleared========== */
restrict = 0x00U;
x = rand() & 7;
y = rand() & 7;
if(x == 6 || x == 7){ restrict += RIGHT;}
if(x == 0 || x == 1){ restrict += LEFT;}
if(y == 0 || y == 1){ restrict += UP;}
if(y == 6 || y == 7){ restrict += DOWN;}
/* in the rest of generation wrap this block in if(restrict != 0x0FU){ */
do{
temp = rand() & 3;
if(temp == 0){ direction = UP;}
if(temp == 1){ direction = RIGHT;}
if(temp == 2){ direction = DOWN;}
if(temp == 3){ direction = LEFT;}
}while(restrict & direction);
occupy[x][y] = 5;
if(direction == UP){ occupy[x][y-1] = 1;}
if(direction == RIGHT){ occupy[x+1][y] = 2;}
if(direction == DOWN){ occupy[x][y+1] = 3;}
if(direction == LEFT){ occupy[x-1][y] = 4;}
for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
printf(" %d", occupy[x][y]);
}
printf(" \n");
}
}
void main(){
generate();
}
答案 0 :(得分:2)
这是根据我的GBDK版本编写的,虽然我不确定为什么我所做的更改会修复它。
所做的更改:
occupy
现在是一个unsigned int
的数组,而不只是int
(没有此更改sdcc
崩溃)printf
调用已从" %d"
更改为" %u"
(因为值未签名)添加了显示printf
地址的occupy
。如果我删除它或更改它以执行其他操作,sdcc
会崩溃。这很愚蠢,但似乎是必需的。我正在寻找不需要毫无意义的替代方案printf
。
请注意,可以使用以下内容,这样就不会打印任何内容(因为它会尝试写入地址$0000
,但这样只读并失败)。它仍然很愚蠢,但没有显示任何东西。它可能仍会导致一些减速。
sprintf(0, "", &occupy);
我还改进了缩进。
#include <gb\gb.h>
#include <stdio.h>
#include <rand.h>
#define UP 0x01U
#define RIGHT 0x02U
#define DOWN 0x04U
#define LEFT 0x08U
unsigned int occupy[8][8] = {
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};
void generate(){
int temp;
int x;
int y;
UBYTE restrict;
UBYTE direction;
for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
occupy[x][y] = 0;
}
}
/* ========Occupy=Cleared========== */
restrict = 0x00U;
x = rand() & 7;
y = rand() & 7;
if(x == 6 || x == 7){ restrict += RIGHT;}
if(x == 0 || x == 1){ restrict += LEFT;}
if(y == 0 || y == 1){ restrict += UP;}
if(y == 6 || y == 7){ restrict += DOWN;}
/* in the rest of generation wrap this block in if(restrict != 0x0FU){ */
do{
temp = rand() & 3;
if(temp == 0){ direction = UP;}
if(temp == 1){ direction = RIGHT;}
if(temp == 2){ direction = DOWN;}
if(temp == 3){ direction = LEFT;}
}while(restrict & direction);
occupy[x][y] = 5;
if(direction == UP){ occupy[x][y-1] = 1;}
if(direction == RIGHT){ occupy[x+1][y] = 2;}
if(direction == DOWN){ occupy[x][y+1] = 3;}
if(direction == LEFT){ occupy[x-1][y] = 4;}
printf(" %x\n", &occupy); //Strangely without this printf it doesn't compile???
for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
printf(" %u", occupy[x][y]);
}
printf(" \n");
}
}
void main(){
generate();
}
以下是关于代码的其他一些评论:
您无法初始化RNG,因此结果将始终相同。设置种子有几种方法。通常情况下,您可以在标题屏幕上按时间进行操作,也可以选择种子选择器。
//Seeds RNG by time taken to press start
void seedRNG() {
UINT16 seed = 0;
printf("Press start\n");
while (!(joypad() & J_START)) {
seed++;
}
initrand(seed);
}
//Seeds RNG with a user-chosen number.
//Requires inclusion of <gb\console.h>.
void seedRNG() {
UINT16 seed = 0x8000U; //In the middle to prevent over/underflow issues
printf("Seed:");
while (!(joypad() & J_START)) {
if (joypad() & J_UP) { seed++; }
if (joypad() & J_DOWN) { seed--; }
gotoxy(0,1);
printf("%x\n", seed);
delay(10);
}
initrand(seed);
}
在这种情况下,您实际上不需要打印出来查看它,因为您可以使用&#34; Memory Viewer&#34;在大多数模拟器中找到。这些位置可以在使用-Wl-j
或-Wl-m
选项生成的RAM地图中找到。
我建议使用INT16
或WORD
而不是int
和UINT16
或UWORD
而不是unsigned int
等它们包括名称中的大小。 UBYTE
等等也很好用。
答案 1 :(得分:-1)
the following compiles
#include <stdio.h>
#include <stdlib.h> // contains rand and srand function prototypes
#include <time.h>
//#include "gb\gb.h"
void generate( void );
#define UP 0x01U
#define RIGHT 0x02U
#define DOWN 0x04U
#define LEFT 0x08U
typedef unsigned char UBYTE;
int occupy[8][8] =
{
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};
int main()
{
generate();
return(0);
}
void generate()
{
int temp;
int x;
int y;
UBYTE block;
UBYTE direction;
for(x = 0; x < 8; x++)
{
for(y = 0; y < 8; y++)
{
occupy[x][y] = 0;
}
}
/* ========Occupy=Cleared========== */
block = 0x00U;
srand(time(NULL) ); // initialize rand()
x = rand() & 8;
y = rand() & 8;
if(x == 6 || x == 7){ block += RIGHT;}
if(x == 0 || x == 1){ block += LEFT;}
if(y == 0 || y == 1){ block += UP;}
if(y == 6 || y == 7){ block += DOWN;}
/* in the rest of generation wrap this block in if(block != 0x0FU){ */
// NOTE:
// in the following while loop if direction is not the same a block
// then the loop will immediately exit
// probably not what you want to do.
do{
temp = rand() & 4;
if(temp == 0){ direction = UP;}
if(temp == 1){ direction = RIGHT;}
if(temp == 2){ direction = DOWN;}
if(temp == 3){ direction = LEFT;}
} while(block & direction);
// NOTE:
// in the following code,
// 'x' and/or 'y' could be 0 or 7
// in either case, one or more of the following statements
// can/will cause accessing outside of the bounds
// of the occupy[][] array
occupy[x][y] = 5;
if(direction == UP) { occupy[x][y-1] = 1;}
if(direction == RIGHT){ occupy[x+1][y] = 2;}
if(direction == DOWN) { occupy[x][y+1] = 3;}
if(direction == LEFT) { occupy[x-1][y] = 4;}
for(x = 0; x < 8; x++)
{
for(y = 0; y < 8; y++)
{
printf(" %d", occupy[x][y]);
}
printf(" \n");
}
}