Jump to content

help needed please

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
10 replies to this topic

#1
greaterfrankie

greaterfrankie

    Newbie

  • Members
  • Pip
  • 5 posts
Hi, Im taking programming 1 for the first time at my school this semester, and the final assignment we had to make is write a snake clone. After weeks of extensive studying, and of trial and error, and tossing many attempts to the trash, I've cranked out a snake program. Thing is, i dont know why for some reason when it compiles it doesnt print anything on screen. Could someone please have a look at the code and let me know what the problem with it is? Im desperate, i tried asking my friends students but they dont know either. The code is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <math.h>
#define LEVELWIDTH 28
#define LEVELHEIGHT 30

 // define the level with a 2d array.  1s are walls, 0s are the void where the snake moves
int nivel[LEVELWIDTH][LEVELHEIGHT] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
	{1,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,1,},
	{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,}, 
	{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,}, 
	{1,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,1,},
	{1,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,1,},
	{1,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,1,},
	{1,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,1,},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}
};

#define MAXLENGTH 30  //snake's max length
/*snake[0]['x'] //la cabeza de la snake
snake[x][0] = 0 // posicion x
snake[x][1] = 1 // posicion y   */
int snake[MAXLENGTH + 1][2];int snakelength = 0;int vX,vY; // direction where the snake moves



void resetsnake()
{
	snakelength = 0; // resets the snake to only its head

	//resets to head only at the begginning of each level
	snake[0][0] = LEVELWIDTH / 2;
	snake[0][1] = LEVELHEIGHT / 2;
}



void increasesnake(int i)
{
	if(snakelength+ i <= MAXLENGTH)
		snakelength+=i;
	else
		snakelength = MAXLENGTH;
}

void decreasesnake(int i)
{
	if(snakelength - i >= 0)
		snakelength -=i;
	else
		snakelength = 0;
}

void movesnake()
{
	int i;

	for(i = snakelength ; i > 1; i--)    //i < 0
	{
		snake[i][0] = snake[i - 1][0];
		snake[i][1] = snake[i - 1][1];
	}

	snake[0][0] += vX;
	snake[0][1] += vY;
}

int collisiondetect() // returns 1 if it detects collision with the wall or with itself, otherwise returns 0
{
	int i;
	int hit;

	hit = 0;

	//checks if it leaves the level
	if(snake[0][0] < 0 || snake[0][0] > LEVELWIDTH || snake[0][1] < 0 || snake[0][1] >LEVELHEIGHT) hit = 1;

	//checks if it reaches a wall
	if(nivel[snake[0][1]][snake[0][0]] == 1) hit = 1;

	//checks if it crashes with itself
	for(i = 1; i < snakelength; i++)
	{
		if(snake[0][0] == snake[i][0] && snake[0][1] == snake[i][1]) hit = 1;
	}

	return hit;
}


#define TILE_WALL		(1)
#define POWERUP_PILL     	(2) 
#define POWERUP_FOO		(3)

void moveup()
{
	vX = 0;
	vY = -1;
}

void movedown()
{
	vX = 0;
	vY = 1;
}

void moveleft()
{
	vX = -1;
	vY = 0;
}

void moveright()
{
	vX = 1;
	vY = 0;
}
//draws the snake onscreen



void draw()
{
	int x,y;
	printf("woot");
	for(y = 0; y < LEVELHEIGHT; y++)
	{
		for(x = 0; x < LEVELWIDTH; x++)
		{
			switch(nivel[y][x])
			{
				case 	TILE_WALL:
					printf("*",x,y); // ASCII character that makes up wall
                                        break;
				case 	POWERUP_PILL:
					printf("&",x,y); // ASCII character that makes up powerup
						break;
			}
			 
		}
	}

	for(x = 0; x < snakelength; x++)
	{
		printf("*",snake[x][0],snake[x][1]); // ASCII character that makes up the snake's body
	}
}



void main()
{ 
	resetsnake();
		
	while(1)
	{
		draw();
		
		movesnake();
		
  		if(collisiondetect() != 1)
		{
			
			movesnake();
			 char key;
                         key=getch();

			//checks which key the user presses to move the snake in that direction

			if(tecla=='H') moveup();
			if(tecla=='P') movedown();

			if(tecla=='K') moveleft();
			if(tecla=='M') moveright();
		}
		else
		{
			printf("You lose!");
		}
		
	}


}
If you have any questions regarding what any line does let me know. Please, ill appreciate any help i can get

Thanks

frankie

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
1) I would recommend moving your #defines to the top of the code so they're easy to find.
2) most of nivel is set to 0, which doesn't have a case associated with it (perhaps printf(" ")?)
3) You have to print the snake's body at the same time you print the rest of the grid.
4) You never print a \n, so all output will be on a single line.

I haven't attempted to compile/run/debug this, these are just my immediate observations while looking at the draw() function. Your program will also stall waiting for input from the user in main()
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
greaterfrankie

greaterfrankie

    Newbie

  • Members
  • Pip
  • 5 posts
Many thanks for your reply!

1)OK, done
2) So where do i put the printf(" ") line ?
3) How do i do that? Print the snake's body at the same time you print the rest of the grid? With another draw() function?

Probably theres a syntax error in this line :

printf("*",snake[x][0],snake[x][1]); // change to a character you like.  

Right? It should have a %d probably?

4) So where do i printf the newline character?

thanks again

#4
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
2) probably in the default clause
3) I would update the nivel with the snake's location PRIOR to printing the grid.
4) at the end of each grid row.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#5
greaterfrankie

greaterfrankie

    Newbie

  • Members
  • Pip
  • 5 posts

WingedPanther said:

2) probably in the default clause
3) I would update the nivel with the snake's location PRIOR to printing the grid.
4) at the end of each grid row.

Ok, but, could you please put here some code snippets for your suggestions? I dont think i understand exactly how to add them in the program.

Thanks!

#6
greaterfrankie

greaterfrankie

    Newbie

  • Members
  • Pip
  • 5 posts
Ok, so i added an extra DEFINE called SPACE, set it at 0, and added a case that prints " ". So now there are a few spaces in the asterisks. So now it's better, thanks. But what aout the other problems? And i've realized, like you mentioned earlier, the program just prints out the lines of asterisks, and stays there, when i press any key the program exits. How do i make it like, loop indefinitely and take key inputs for moving the snake?

Thanks

#7
greaterfrankie

greaterfrankie

    Newbie

  • Members
  • Pip
  • 5 posts
So this is so far what ive managed to modify:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <math.h>
#define LEVELWIDTH 30
#define LEVELHEIGHT 30
#define TILE_WALL		(1)
#define POWERUP_PILL     	(2) 
#define POWERUP_FOO		(3)
#define SPACE                    0

 // define the level with a 2d array.  1s are walls, 0s are the void where the snake moves
int nivel[LEVELWIDTH][LEVELHEIGHT] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{'\n1',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,1},
	{'\n1',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,1},
	{'\n1',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,1},
	{'\n1',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,1},
	{'\n1',0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
	{'\n1',1,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,1},
	{'\n1',1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1},
	{'\n1',1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,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,1},
	{'\n1',1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};

#define MAXLENGTH 30  //snake's max length
/*snake[0]['x'] //la cabeza de la snake
snake[x][0] = 0 // posicion x
snake[x][1] = 1 // posicion y   */
int snake[MAXLENGTH + 1][2];int snakelength = 0;int vX,vY; // direction where the snake moves



void resetsnake()
{
	snakelength = 0; // resets the snake to only its head

	//resets to head only at the begginning of each level
	snake[0][0] = LEVELWIDTH / 2;
	snake[0][1] = LEVELHEIGHT / 2;
}



void increasesnake(int i)
{
	if(snakelength+ i <= MAXLENGTH)
		snakelength+=i;
	else
		snakelength = MAXLENGTH;
}

void decreasesnake(int i)
{
	if(snakelength - i >= 0)
		snakelength -=i;
	else
		snakelength = 0;
}

void movesnake()
{
	int i;

	for(i = snakelength ; i > 1; i--)    //i < 0
	{
		snake[i][0] = snake[i - 1][0];
		snake[i][1] = snake[i - 1][1];
	}

	snake[0][0] += vX;
	snake[0][1] += vY;
}

int collisiondetect() // returns 1 if it detects collision with the wall or with itself, otherwise returns 0
{
	int i;
	int hit;

	hit = 0;

	//checks if it leaves the level
	if(snake[0][0] < 0 || snake[0][0] > LEVELWIDTH || snake[0][1] < 0 || snake[0][1] >LEVELHEIGHT) hit = 1;

	//checks if it reaches a wall
	if(nivel[snake[0][1]][snake[0][0]] == 1) hit = 1;

	//checks if it crashes with itself
	for(i = 1; i < snakelength; i++)
	{
		if(snake[0][0] == snake[i][0] && snake[0][1] == snake[i][1]) hit = 1;
	}

	return hit;
}


void moveup()
{
	vX = 0;
	vY = -1;
}

void movedown()
{
	vX = 0;
	vY = 1;
}

void moveleft()
{
	vX = -1;
	vY = 0;
}

void moveright()
{
	vX = 1;
	vY = 0;
}
//draws the snake onscreen



void draw()
{
	int x,y;
	printf("woot");
	for(y = 0; y < LEVELHEIGHT; y++)
	{
		for(x = 0; x < LEVELWIDTH; x++)
		{
			switch(nivel[y][x])
			{
				case 	TILE_WALL:
					printf("*",x,y); // ASCII character that makes up wall
                                        break;
				case 	POWERUP_PILL:
					printf("&",x,y); // ASCII character that makes up powerup
						break;
                                case    SPACE:
                                printf(" ",x,y); // ASCII character that makes up powerup
						break;
			}
			 
		}
	}

	for(x = 0; x < snakelength; x++)
	{
		printf("*",snake[x][0],snake[x][1]); // ASCII character that makes up the snake's body
	}
}



int main()
{ 
	resetsnake();
		
	while(1)
	{
		draw();
		
		movesnake();
		
  		if(collisiondetect() != 1)
		{
			
			movesnake();
			 char key;
                         key=getch();

			//checks which key the user presses to move the snake in that direction

			if(key=='H') moveup();
			if(key=='P') movedown();

			if(key=='K') moveleft();
			if(key=='M') moveright();
		}
		else

			printf("You lose!");

		                return 0;
		
	}



}

Is this correct? It's giving me multicharacter warnings now.

#8
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
In main(), you need to have the else clause surround in {}. Otherwise, you always return 0 after the first run through.

Can you explain how you are storing the snake? It will determine the best way to make it display.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#9
dcs

dcs

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 775 posts

greaterfrankie said:

It's giving me multicharacter warnings now.
Don't spell the newline character '\n' as '\n1'.

#10
LukeyJ

LukeyJ

    Learning Programmer

  • Members
  • PipPipPip
  • 93 posts
I would suggest doing the \n characters as part of a display function or loop than storing them in an int array. I wasn't aware that was possible and probably a reason for it complaining about multiple characters.

Another problem could be that, with your code, your snake will not move until you press a key, giving the user ultimate control and therefore taking the fun out of it. If you made it move via a timer and you check direction and direction can be changed via keyboard input. How you would display the game, I do not know. Can console code be updated or do you have to output the screen again?

#11
Aereshaa

Aereshaa

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 790 posts
So, as someone who has made a few(read: exactly 7) working games, I have a few suggestions:
1. If you're making an asynchronous game like snakes, you should use an asynchronous library for displaying output and receiving user control. If you're doing it in the console on windows, use conio.h. If you're using text on unix, you need ncurses. Either way, the normal console only permits line-by-line i/o, which is almost never what you need for a game.
2. That huge, multiline initialiser for a level is incredibly bad style. I would recommend you read levels out of a file, or possibly generate them as needed (though the latter is pretty advanced).
That's all I've got from a quick scan of your code. I'll take a good look at it later and check your game logic.
Watches: Nanoha, Haruhi, AzuDai. Listens to: E-Type, Dj Melodie, Nightcore.
"When people are wrong they need to be corrected. And then when they can't accept it, an argument ensues." - MeTh0Dz