我是非常新的编码,所以不要很挑剔,如果我犯了一个简单的错误...我自学成才,所以你是唯一一个我可以问。感谢大家谁会帮助!
我试着用做一些类似“太空射手”的东西<curses.h>,但是它总是给我写分段错误,我不明白为什么。我想我可以给予你我所有的代码,这样你就可以理解游戏的逻辑,但是我想我的问题可能是从诅咒初始化开始到结束...也许我错过了刷新()或类似的东西?
#include <stdio.h>
#include <stdlib.h>
#include<curses.h>
#include<time.h>
#include<string.h>
#include<unistd.h>
int main()
{
int sizey = 23;
int sizex = 40;
int x, y, yi;
char world[sizey][sizex];
char player = 'A';
char playerLaser = '^';
char enemy = 'M';
char enemyShielded = 'O';
char enemyLaser = 'U';
char explosion = 'X';
int score = 0;
int victory = 1;
int laserReady = 1;
int enemyReady = 0;
srand(time(NULL));
/*welcome screen*/
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr,TRUE);
printf("\n \n Welcome soldier! \n \n \n \n");
usleep(1*100000);
printf(" Brave the COMMAND PROMPT INVADERS and come back a hero. \n \n \n \n");
usleep(1*10000);
printf(" Your operating system is depending upon you. \n \n \n \n");
usleep(1*10000);
printf(" Good luck.");
usleep(1*10000);
printf("\n \n \n \n Press any key to start.");
getch();
/*initialise world*/
int totalEnemies = 0;
for (x = 0; x < sizex; x ++) {
for (y = 0; y < sizey; y ++) {
if ((y+1) % 2 == 0 && y < 7 && x > 4
&& x < sizex - 5 && x % 2 ==0) {
world[y][x] = enemy;
totalEnemies ++;
}
else if ((y+1) % 2 == 0 && y >= 7 && y < 9 && x > 4
&& x < sizex - 5 && x % 2 ==0){
world[y][x] = enemyShielded;
totalEnemies = totalEnemies + 2;
}
else {
world[y][x] = ' ';
}
}
}
world[sizey - 1][sizex / 2] = player;
int i = 1;
char direction = 'l';
int currentEnemies = totalEnemies;
while(currentEnemies > 0 && victory) {
int drop = 0;
int enemySpeed = 1 + 10 * currentEnemies / totalEnemies;
laserReady ++;
refresh();
endwin();
/*display world*/
system("clear");
printf(" SCORE: %d", score);
printf("\n");
for (y = 0; y < sizey; y ++) {
printf("|");
for (x = 0; x < sizex; x ++) {
printf("%c",world[y][x]);
}
printf("|");
printf("\n");
}
/*laser time*/
for (x = 0; x < sizex; x ++) {
for (y = sizey-1; y >= 0; y --) {
if (i%2 == 0 && world[y][x] == enemyLaser
&& (world[y+1][x] != enemy & world[y+1][x] != enemyShielded)){
world[y+1][x] = enemyLaser;
world[y][x] = ' ';
}
else if (i%2 == 0 && world[y][x] == enemyLaser
&& (world[y+1][x] == enemy | world[y+1][x] == enemyShielded)){
world[y][x] = ' ';
}
}
}
for (x = 0; x < sizex; x ++) {
for (y = 0; y < sizey; y ++) {
if ((i % 5) == 0 && (world[y][x] == enemyShielded
| world[y][x] == enemy) && (rand() % 15) > 13
&& world[y+1][x] != playerLaser) {
for (yi = y+1; yi < sizey; yi ++) {
if (world[yi][x] == enemy
| world[yi][x] == enemyShielded) {
enemyReady = 0;
break;
}
enemyReady = 1;
}
if (enemyReady) {
world[y+1][x] = enemyLaser;
}
}
if (world[y][x] == playerLaser && world[y-1][x] == enemy) {
world[y][x] = ' ';
world[y-1][x] = explosion;
currentEnemies --;
score = score + 50;
}
else if (world[y][x] == playerLaser
&& world[y-1][x] == enemyShielded) {
world[y][x] = ' ';
world[y-1][x] = enemy;
currentEnemies --;
score = score + 50;
}
else if (world[y][x] == playerLaser
&& world[y-1][x] == enemyLaser) {
world[y][x] = ' ';
}
else if (world[y][x] == explosion) {
world[y][x] = ' ';
}
else if ((i+1) % 2 == 0 && world[y][x] == enemyLaser
&& world[y+1][x] == player) {
world[y+1][x] = explosion;
world[y][x] = ' ';
victory = 0;
}
else if (world[y][x] == playerLaser
&& world[y-1][x] != enemyLaser) {
world[y][x] = ' ';
world[y-1][x] = playerLaser;
}
}
}
/*update enemy direction*/
for (y = 0; y < sizey; y ++) {
if (world[y][0] == enemy) {
direction = 'r';
drop = 1;
break;
}
if (world[y][sizex-1] == enemy){
direction = 'l';
drop = 1;
break;
}
}
/*update board*/
if (i % enemySpeed == 0) {
if (direction == 'l') {
for (x = 0; x < sizex - 1; x ++) {
for (y = 0; y < sizey; y ++) {
if (drop && (world[y-1][x+1] == enemy
|| world[y-1][x+1] == enemyShielded)){
world[y][x] = world[y-1][x+1];
world[y-1][x+1] = ' ';
}
else if (!drop && (world[y][x+1] == enemy
|| world[y][x+1] == enemyShielded)) {
world[y][x] = world[y][x+1];
world[y][x+1] = ' ';
}
}
}
}
else {
for (x = sizex; x > 0; x --) {
for (y = 0; y < sizey; y ++) {
if (drop && (world[y-1][x-1] == enemy
|| world[y-1][x-1] == enemyShielded)) {
world[y][x] = world[y-1][x-1];
world[y-1][x-1] = ' ';
}
else if (!drop && (world[y][x-1] == enemy
|| world[y][x-1] == enemyShielded)) {
world[y][x] = world[y][x-1];
world[y][x-1] = ' ';
}
}
}
}
for (x = 0; x < sizex; x ++) {
if (world[sizey - 1][x] == enemy) {
victory = 0;
}
}
}
/*control player*/
int ch;
ch = getch();
if(ch == 'a'){
for (x = 0; x < sizex; x = x+1) {
if ( world[sizey-1][x+1] == player) {
world[sizey-1][x] = player;
world[sizey-1][x+1] = ' ';
}
}
}
if(ch == 'd'){
for (x = sizex - 1; x > 0; x = x-1) {
if ( world[sizey-1][x-1] == player) {
world[sizey-1][x] = player;
world[sizey-1][x-1] = ' ';
}
}
}
if(ch == 'm'&& laserReady > 2){
for (x = 0; x < sizex; x = x+1) {
if ( world[sizey-1][x] == player) {
world[sizey - 2][x] = playerLaser;
laserReady = 0;
}
}
}
i ++;
usleep(1*100000);
}
system("clear");
printf(" SCORE: %d", score);
printf("\n");
for (y = 0; y < sizey; y ++) {
printf("|");
for (x = 0; x < sizex; x ++) {
printf("%c",world[y][x]);
}
printf("|");
printf("\n");
}
usleep(1*100000);
system("clear");
if (victory != 0) {
printf("\n \n \n \n \n \n CONGRATULATIONS! \n \n \n \n \n");
usleep(1*100000);
printf("\n \n Score: %d", score);
usleep(1*100000);
int bonus = totalEnemies*20 - i;
printf("\n \n Bonus: %d", bonus);
usleep(1*100000);
printf("\n \n Total Score: %d", score + bonus);
printf("\n \n \n \n Well done");
usleep(1*100000);
printf(", Hero.");
usleep(1*100000);
getch();
}
else {
printf("\n \n \n \n \n \n You have failed.");
usleep(1*100000);
printf("\n \n \n \n \n \n Windows is doomed.");
usleep(1*100000);
printf("\n \n Final Score: %d", score);
getch();
}
}
1条答案
按热度按时间pgky5nke1#
正如上文评论所述:这不是一个诅咒的问题。相反,有许多情况下,你试图访问world[][]数组之外的元素,这就是导致segfault的原因。我没有详细介绍每一个示例,但是,例如,考虑“控制播放器”部分。在“a”(左)处理程序,您可以正确地将单元格的范围从0到(但不包括)sizex...,然后(有时)修改偏移量sizex处的单元格,这超出了范围。
你可以用一种边界安全的方式重写这一节,顺便说一下,这样会更高效:
注意,这只是需要检查边界的一个地方。
同时,由于这个 * 是 * 标记的curses...注意整个程序可以很容易地转换为curses:
1.将
printf()
的所有示例更改为printw()
。1.将
system(clear)
的所有示例更改为erase()
。1.将
usleep()
更改为napms()
(除以1000)。1.将
endwin()
移到末尾。1.将
nodelay()
移到第一个getch()
之后。1.在最后一个
erase()
之后添加一个nodelay(stdscr, FALSE)
。进一步的调整将使它工作得更好。