Reputation: 527
I made an extermely simple labirinth game out of boredom, however there's a weird bug that i can't figure out why is happening.
When i try to move into the obstacle, the first row of my output shifts. Also, depending on where i try to move, it can shift just 1 or more than 1 characters to the right. This is pretty weird to me considering that my showFrame()
function clears the screen every time before outputting.
The 90th line is in action when you try to move into an obstacle. In case the new position is invalid, it will first revert the position, then invoke showFrame()
, and showFrame()
clears the console before outputting. So what causes the first row to shift? AND why does it shift differently depending on which key is pressed?
The code follows. If i understand correctly, you need to compile and run on linux, not windows, because of the ncurses thing and the getchar function? But i'm not sure. (not really a C programmer much)
Add the -lncurses
argument when compiling. If you don't have the ncurses library installed, it can be downloaded here:
http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.7.tar.gz
#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>
int positionX = 1,
positionY = 19,
oldPositionX,
oldPositionY,
sizeX,
sizeY;
char matrix[20][20] =
{'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '|',
'|', ' ', '|', ' ', ' ', ' ', '|', '-', '-', ' ', ' ', ' ', '-', '-', '|', ' ', ' ', ' ', ' ', '|',
'|', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
'-', '-', '-', '|', ' ', '|', ' ', ' ', '|', ' ', '|', ' ', ' ', ' ', '-', '-', ' ', '|', ' ', '|',
' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '-', '-', '|', ' ', ' ', '|', ' ', '|', ' ', '|',
' ', '|', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '|', '|', ' ', '|', ' ', '|',
' ', '|', ' ', ' ', ' ', '-', '-', '|', '|', ' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '|',
' ', '-', '-', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '|', ' ', '-', '-', '-', '|',
' ', ' ', ' ', '|', ' ', '|', ' ', '|', ' ', '|', '-', '-', '-', ' ', '|', ' ', '|', ' ', ' ', '|',
'-', '-', '-', '|', ' ', '|', ' ', '|', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '-', '|', ' ', '|',
'|', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', '-', '|', ' ', ' ', '|', ' ', '|',
'|', ' ', '|', '-', '-', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', ' ', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', ' ', ' ', ' ', ' ', ' ', ' ', '|',
'|', '-', '-', '-', '-', '-', ' ', '|', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', '-', '-', '-', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '-', '|', ' ', ' ', ' ', ' ', ' ', '|',
'|', ' ', '|', '-', '-', '-', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '|',
'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', '-', '-', '|', ' ', '|', ' ', ' ', ' ', ' '};
void main() {
char key;
int stty;
// Get the size of the matrix
sizeX = sizeof(matrix) / sizeof(matrix[0]);
sizeY = sizeof(matrix[0]);
while(1) {
// Output level
showFrame();
// Wait for user input to move player position
stty = system("stty raw");
key = getchar();
system("stty cooked");
// Store previou position and move player position accordingly
oldPositionX = positionX;
oldPositionY = positionY;
switch(key) {
case 'w': positionY--;
break;
case 'a': positionX--;
break;
case 's': positionY++;
break;
case 'd': positionX++;
break;
default: printf("\bThat's an invalid key, stupid!\nYou're supposed to play with WASD keys.\n");
exit(0);
}
// Check to see if new position is okay
if(positionY >= sizeY || positionY < 0 || positionX >= sizeX || positionX < 0) {
revertPosition();
}
// Check to see if level cleared!
if(positionX == 1 && positionY == 0) {
showFrame();
printf("You cleared the level, Sherlock.\nYou must be really proud of yourself\n");
return;
}
}
}
int showFrame() {
int i, j;
// Output the matrix
system("clear");
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
// Check if player's position is at the current block
if(i == positionY && j == positionX) {
// If the players position is in an invalid block, revert his position
if(matrix[i][j] != ' ') {
revertPosition();
showFrame();
printf("You can't go there, stupid!\n");
return 1;
} else {
printf("* ");
}
} else {
printf("%c ", matrix[i][j]);
}
}
printf("\n");
}
return 0;
}
void revertPosition() {
positionX = oldPositionX;
positionY = oldPositionY;
}
Upvotes: 0
Views: 106
Reputation: 9062
It seems there is a problem with clear.
To identify the problem, you should start finding what those characters that shift your first row come from. Adding:
system("clear");
printf('\n');
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
brings a little bit of light. It seems that if i want to go up, the characters there are the same as those from the upper line, to my position.
Now, you need to find why those characters are not deleted by system("clear");
, as it is supposed. After some trial and error, I managed to find that if you print a '\n' before clearing, it works as it is supposed.
As I have never used ncurses before, I can not explain you why is this happening. My assuption is that clear command clears the terminal line by line. And a line is ended with newline character. So, everything you need to do is to append newline after those trailing characters (I would suggest you printing it at the beginning of the showFrame function, to avoid simillar situations):
int showFrame() {
int i, j;
// Output the matrix
printf('\n');
system("clear");
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
// Check if player's position is at the current block
if(i == positionY && j == positionX) {
// If the players position is in an invalid block, revert his position
if(matrix[i][j] != ' ') {
revertPosition();
showFrame();
printf("You can't go there, stupid!\n");
return 1;
} else {
printf("* ");
}
} else {
printf("%c ", matrix[i][j]);
}
}
printf("\n");
}
return 0;
}
I hope this was useful for you. Also, let me make some remarks about your code:
Using global variables is strongly discouraged. About the main's return value, I would recommend you to read this. Also, your ethier declare your functions before main:
int showFrame();
void revertPosition();
either move their entire definitions before main. As it is, your code did not compile on my machine (gcc 4.8.1).
Upvotes: 1