I'm trying to make a snake game in which if the snake eats the first fruit and in 2 seconds eats the second fruit then it's score multiplied by 2. If the snake eats the second fruit in 1 second then the score is multiplied by 3. If the snake eats the second fruit in 3 seconds then the score is increased just by 1 and so on ... But after the snake eats about 5-6 fruits the 7th fruit respawns outside of the boundaries. This the "drawing" function
void make_stage() {
score = 0;
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
for (int i = 1; i <= 17; i++) {
gotoxy(i, 1);
printf("#");
gotoxy(1, i);
printf("#");
gotoxy(17, i);
printf("#");
gotoxy(i, 17);
printf("#");
}
srand(time(NULL));
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(fruitx, fruity);
printf("#");
}
And this is the logic function:
void snake_move() {
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
while (1) {
srand(time(NULL));
if (x == fruitx && y == fruity) {
fruitx = rand() % 17;
fruity = rand() % 17;
score += 1;
gotoxy(fruitx, fruity);
printf("#");
}
input = _getch();
if ((dir == 'w' && input != 's') || (dir == 'a' && input != 'd') || (dir == 's' && input != 'w') || (dir == 'd' && input != 'a')) {
if (input == 'w') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y - 1;
if (y == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'w';
}
if (input == 'a') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x - 1;
if (x == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'a';
}
if (input == 's') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y + 1;
if (y == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 's';
}
if (input == 'd') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x + 1;
if (x == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'd';
}
}
if (input == 'p') {
gameover();
break;
}
}
}
and this is the entire source code just in case!
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<process.h>
int height = 17, width = 17;
typedef struct RECORD {
char name[100];
int score;
int minute;
int sec;
}record; //이름, 점수, 시간을 저장할 구조체
int score;
int fruitx, fruity;
record nowrec;
int over = 0;
void gotoxy(int x, int y); //Input location
void make_stage(); //stage
int getCommand(); // Keyboard input
void gameover(); //Gameover screen
void startscr(); //Start screen
void snake_move(); //Snake movements
void rank_call(); //Displaying rank
void rankrecord(); //personal records
void cursor(int i); //
void stopwatch(); //stop watch
int main(void) {
startscr();
return 0;
}
void gotoxy(int x, int y) {
COORD pos = { 30 + x * 2, 10 + y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void make_stage() {
score = 0;
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
for (int i = 1; i <= 17; i++) {
gotoxy(i, 1);
printf("#");
gotoxy(1, i);
printf("#");
gotoxy(17, i);
printf("#");
gotoxy(i, 17);
printf("#");
}
srand(time(NULL));
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(fruitx, fruity);
printf("#");
}
int getCommand() {
if (_kbhit()) {
return _getch();
}
return -1;
}
void cursor(int i) {
CONSOLE_CURSOR_INFO cursorInfo = { 0, };
cursorInfo.dwSize = 1;
cursorInfo.bVisible = i;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
void rank_call() {
FILE* rank;
char reading[100];
if (fopen_s(&rank, "rank.txt", "r") != 0) printf("no record\n");
else {
printf("\n");
while ((fgets(reading, 100, rank) != NULL)) printf("%s", reading);
fclose(rank);
printf("\n");
}
}
void rankrecord() {
printf("\npress enter to proceed...\n");
while (getchar() != '\n');
printf("\n\n\n\n\n\npress r to record your ranking...\n");
char input = _getch();
if (input == 'r') {
FILE* rank;
fopen_s(&rank, "rank.txt", "a");
rerun:
printf("enter your name: ");
gets_s(nowrec.name, sizeof(nowrec.name));
if (strlen(nowrec.name) < 3) {
printf("name must be at least 3 words...\n\n");
goto rerun;
}
while (1) {
printf("your name is %s.\nyour score is %d.\nyour clear time is %d : %d.\n\n", nowrec.name, nowrec.score, nowrec.minute, nowrec.sec);
printf("if your name is incorrect, press n to correct\nif not, press y to continue...\n\n");
input = _getch();
if (input == 'n') goto rerun;
else if (input == 'y') break;
else printf("wrong input\n\n");
}
fprintf(rank, "%s %d %d : %d\n", nowrec.name, nowrec.score, nowrec.minute, nowrec.sec);
fclose(rank);
printf("saved!\n");
}
}
void startscr()
{
system("mode con cols=100 lines=40");
start:
system("cls");
printf(" ****** ** * * * * ****** ****** * ** ** ****** \n");
printf(" * * * * * * * * * * * * * * * * * \n");
printf(" ****** * * * ***** **** ****** * *** ***** * * * * ****** \n");
printf(" * * * * * * * * * * * * * * ** * * \n");
printf(" ****** * ** * * * * ****** ****** * * * ** * ****** \n");
printf("\npress s to start game\n");
printf("press r to see ranking\n");
printf("press x to exit\n:");
char input = _getch();
if (input == 's') {
system("cls");
cursor(0);
make_stage();
HANDLE thread1 = _beginthreadex(NULL, 0, (_beginthreadex_proc_type)stopwatch, NULL, 0, NULL);
Sleep(1);
HANDLE thread2 = _beginthreadex(NULL, 0, (_beginthreadex_proc_type)snake_move, NULL, 0, NULL);
WaitForSingleObject(thread2, INFINITE);
}
else if (input == 'r') {
rank_call();
printf("press enter to continue...");
while (getchar() != '\n');
goto start;
}
else if (input == 'x') exit(0);
else {
printf("wrong input\n");
printf("press enter to continue...");
while (getchar() != '\n');
goto start;
}
}
void gameover() {
over = 1;
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n");
printf(" ****** * ** ** ****** **** * * ****** ***** \n");
printf(" * * * * * * * * * * * * * * * \n");
printf(" * *** ***** * * * * ****** * * * * ****** ***** \n");
printf(" * * * * * ** * * * * * * * * * \n");
printf(" ****** * * * ** * ****** **** * ****** * * \n");
cursor(1);
rankrecord();
printf("press any key to back to title...");
_getch();
startscr();
}
void snake_move() {
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
while (1) {
srand(time(NULL));
if (x == fruitx && y == fruity) {
fruitx = rand() % 17;
fruity = rand() % 17;
score += 1;
gotoxy(fruitx, fruity);
printf("#");
}
input = _getch();
if ((dir == 'w' && input != 's') || (dir == 'a' && input != 'd') || (dir == 's' && input != 'w') || (dir == 'd' && input != 'a')) {
if (input == 'w') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y - 1;
if (y == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'w';
}
if (input == 'a') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x - 1;
if (x == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'a';
}
if (input == 's') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y + 1;
if (y == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 's';
}
if (input == 'd') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x + 1;
if (x == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'd';
}
}
if (input == 'p') {
gameover();
break;
}
}
}
void stopwatch() {
clock_t s, n;
s = clock();
while (1) {
n = clock();
cursor(0);
gotoxy(14, 0);
printf(" %d : %d", ((n - s) / 1000) / 60, ((n - s) / 1000) % 60);
if (over == 1) {
break;
}
Sleep(1000);
}
gotoxy(14, 0);
printf(" **** ");
nowrec.minute = ((n - s) / 1000) / 60;
nowrec.sec = ((n - s) / 1000) % 60;
return;
}
Remember that
rand() % x
will give you values in the range [0, x-1].
With this in mind, let's look at
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(fruitx, fruity);
printf("#");
When you feed rand() % 17 into gotoxy() like this, you can expect that goto(0, 0) is possible.
I modified the above code to look like this
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(0, 0);
printf("#");
to see what would happen, and the fruit turned up outside the field in the top left.
void gotoxy(int x, int y) {
COORD pos = { 30 + x * 2, 10 + y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
The problem is that your definition of gotoxy() is such that feeding it (0, 0) as coordinates puts the cursor outside the boundary to begin with. Furthermore, passing (1, 1) puts it in the corner, making it apart of the wall, which is also illegal I'm guessing.
To fix this, you either need to adjust your mathematics in gotoxy() or make a new function that transforms your field coordinates into global coordinates. This way, (0, 0) would correspond to the actual upper left (just inside the boundary) and so on.
The easiest fix is just to modify it like so
fruitx = 2 + rand() % 15;
fruity = 2 + rand() % 15;
gotoxy(fruitx, fruity);
printf("#");
This should happen everywhere you're spawning fruit.
Related
I'm having trouble with adding power ups. I don't know where to put it. I'm a first year college; can somebody help?
This is what I did. I want to add power ups in this game where whenever I destroy enemy, it drops power ups like firing speed and double shooting.
I don't know what to put inside to have the enemy drop some power up.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.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*/
printf("\n \n Welcome soldier! \n \n \n \n");
Sleep(1000);
printf(" Brave the COMMAND PROMPT INVADERS and come back a hero. \n \n \n \n");
Sleep(2500);
printf(" Your operating system is depending upon you. \n \n \n \n");
Sleep(2500);
printf(" Good luck.");
Sleep(1000);
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';
char keyPress;
int currentEnemies = totalEnemies;
while(currentEnemies > 0 && victory) {
int drop = 0;
int enemySpeed = 1 + 10 * currentEnemies / totalEnemies;
laserReady ++;
/*display world*/
system("cls");
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*/
if(kbhit()){
keyPress = getch();
}
else {
keyPress = ' ';
}
if (keyPress == '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 (keyPress == '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 (keyPress == '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 ++;
Sleep(50);
}
system("cls");
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");
}
Sleep(1000);
system("cls");
if (victory != 0) {
printf("\n \n \n \n \n \n CONGRATULATIONS! \n \n \n \n \n");
Sleep(1000);
printf("\n \n Score: %d", score);
Sleep(1000);
int bonus = totalEnemies*20 - i;
printf("\n \n Bonus: %d", bonus);
Sleep(1000);
printf("\n \n Total Score: %d", score + bonus);
printf("\n \n \n \n Well done");
Sleep(1000);
printf(", Hero.");
Sleep(1000);
getch();
}
else {
printf("\n \n \n \n \n \n You have failed.");
Sleep(1000);
printf("\n \n \n \n \n \n Windows is doomed.");
Sleep(1000);
printf("\n \n Final Score: %d", score);
getch();
}
}
#include <stdio.h>
char matrix[8][8];
struct coordinate {
int a;
int b;
};
void ReadFile() {
printf("\n\n\n START MAZE ");
int x, y;
FILE * file1;
file1 = fopen("NEWmaze.txt", "r");
for (x = 0; x < 8; x++) {
for (y = 0; y < 8; y++) {
fscanf(file1, " %c", & matrix[x][y]);
}
printf("\n");
}
}
void PrintMaze() {
int x, y;
for (x = 0; x < 8; x++) {
printf(" ");
for (y = 0; y < 8; y++) {
printf(" %c ", matrix[x][y]);
}
printf("\n");
}
printf("\n\n\n\n");
}
struct coordinate DFS(int x, int y) {
struct coordinate retval = {
x,
y
};
printf("%c", matrix[x - 1][y]); //saw the target but could not stop
if (matrix[x][y - 1] == '-') //WEST
{
printf("WEST");
// printf("%d %d",x,y-1); step by step
matrix[x][y - 1] = '.';
PrintMaze(); //step by step
DFS(x, y - 1);
struct coordinate retval = {
x,
y - 1
};
}
if (matrix[x][y - 2] == 'g' && matrix[x + 1][y - 2] != '#') {
// printf("%d %d ",x,y-2); step by step
return retval;
}
if (matrix[x - 1][y] == '-') //NORTH
{
// printf("%d %d",x-1,y); step by step
matrix[x - 1][y] = '.';
PrintMaze(); //step by step
DFS(x - 1, y);
struct coordinate retval = {
x - 1,
y
};
}
if (matrix[x - 2][y] == 'g' && matrix[x - 3][y] != '#') {
struct coordinate retval = {
0,
0
};
return retval;
}
if (matrix[x][y + 1] == '-') //SOUTH
{
//printf("%d %d",x,y+1); step by step
matrix[x][y + 1] = '.';
PrintMaze();
DFS(x, y + 1);
struct coordinate retval = {
x,
y + 1
};
}
if (matrix[x + 1][y + 1] == 'g' && matrix[x + 2][y + 1] != '#') {
struct coordinate retval = {
0,
0
};
return retval;
}
if (matrix[x + 1][y] == '-') { // EAST
// printf("%d %d",x+1,y);
matrix[x + 1][y] = '.';
//PrintMaze();
DFS(x + 1, y);
struct coordinate retval = {
x + 1,
y
};
}
if (matrix[x + 1][y + 1] == 'g' && matrix[x + 1][y + 2] != '#') {
struct coordinate retval = {
0,
0
};
return retval;
}
return retval;
}
void StartSearch() {
printf(" STEP BY STEP");
int x, y;
for (x = 0; x < 8; x++) {
for (y = 0; y < 8; y++) {
if (matrix[x][y] == 's') //START
{
struct coordinate coord = DFS(x, y);
}
}
printf("\n");
}
}
int main() {
ReadFile();
PrintMaze();
StartSearch();
PrintMaze();
return 0;
}
newMaze.txt file (# wall, . step, - empty , s start,g goal)
# # # # # # # #
# g - - # - - #
# - - - - - # #
# - - # - - - #
# - - # - - # #
# - - - - - - #
# - # - - - s #
# # # # # # # #
I print the steps and i can see it reaches the goal.The only problem is it doesn't stop when i reach the goal('g').When I use while break it can't get out of infinite loops. How do I make it stop when it reaches the goal('g')?
This is a follow up to ->
Maze solver with DFS (
here i tried using struct as x and y are not returning at the same time
)
UPDATE
#include <stdio.h>
char matrix[8][8];
struct coordinate {
int x, y;
};
void ReadFile()
{
printf("\n\n\n START MAZE ");
int x,y;
FILE *file1;
file1=fopen("NEWmaze.txt","r");
for(x=0; x<8; x++){
for(y=0;y<8;y++)
{
fscanf (file1, " %c", &matrix[x][y]);
}
printf("\n");
}
}
void PrintMaze()
{
int x,y;
for(x=0;x<8;x++)
{
printf(" ");
for(y=0;y<8;y++)
{
printf(" %c ",matrix[x][y]);
}
printf("\n");
}
printf("\n\n\n\n");
}
struct coordinate DFS(int x, int y)
{
struct coordinate retval = { -1, -1 };
if (matrix[x][y] == 'g')
{
retval.x = x;
retval.y = y;
}
else if (matrix[x][y] == '-' )
{
matrix[x][y] = 'o';// West North South East
PrintMaze();
retval = DFS(x, y-1); if (retval.x != -1) return retval;
retval = DFS(x-1, y ); if (retval.x != -1) return retval;
retval = DFS(x , y+1); if (retval.x != -1) return retval;
retval = DFS(x + 1, y); matrix[x][y] = '.';
}
return retval;
}
void StartSearch()
{
printf(" STEP BY STEP");
int x,y;
for(x=0;x<8;x++)
{
for(y=0;y<8;y++)
{
if(matrix[x][y] == 's')//START
{
if(matrix[x][y-1] == '-')
{
DFS(x,y-1);
}
if(matrix[x-1][y] == '-')
{
DFS(x-1,y);
}
if(matrix[x][y+1] == '-')
{
DFS(x,y+1);
}
if(matrix[x+1][y] == '-')
{
DFS(x+1,y);
}
}
}
printf("\n");
}
}
int main()
{
ReadFile();
PrintMaze();
StartSearch();
PrintMaze();
return 0;
}
UPDATE OUPUT
I wrote in order of priority and it works.
You're going about the return value in a weird way. Instead of constructing it after the recursive call, simply make it so that a valid co-ordinate is returned if the current position is the goal. Otherwise, return something invalid (e.g. {-1,-1}, or even {0,0} in your case if that will always be a wall).
Now all you need to do is store the return value of each recursive call and check if it's valid. If it is, then return it immediately. Otherwise continue processing (i.e. test other directions).
Put in terms of code, something like this:
struct coordinate {
int x, y;
};
struct coordinate DFS(int x, int y)
{
struct coordinate retval = { -1, -1 };
if (matrix[x][y] == 'g')
{
retval.x = x;
retval.y = y;
}
else if (matrix[x][y] == '-' || matrix[x][y] == 's')
{
matrix[x][y] = '.';
retval = DFS(x - 1, y); if (retval.x != -1) return retval;
retval = DFS(x, y - 1); if (retval.x != -1) return retval;
retval = DFS(x + 1, y); if (retval.x != -1) return retval;
retval = DFS(x, y + 1);
}
return retval;
}
Provided your maze always has a wall around the perimeter, you don't need to do any bounds-testing on the co-ordinates because you will never perform recursion when on the edge.
You can even slightly reorder this to draw the actual path used when you first reached the goal. It might not be the optimal path, but that requires a more advanced algorithm. Below, we use 'o' to denote a cell on the path to the goal.
struct coordinate DFS(int x, int y)
{
struct coordinate retval = { -1, -1 };
if (matrix[x][y] == 'g')
{
retval.x = x;
retval.y = y;
}
else if (matrix[x][y] == '-' || matrix[x][y] == 's')
{
matrix[x][y] = '.';
retval = DFS(x - 1, y);
if (retval.x == -1) retval = DFS(x, y - 1);
if (retval.x == -1) retval = DFS(x + 1, y);
if (retval.x == -1) retval = DFS(x, y + 1);
if (retval.x != -1) matrix[x][y] = 'o';
}
return retval;
}
And with a small tweak to the search function:
void StartSearch()
{
int x, y;
for (x = 0; x < 8; x++) {
for (y = 0; y < 8; y++) {
if (matrix[x][y] == 's')
{
DFS(x, y);
matrix[x][y] = 's';
}
}
}
}
You get this output:
# # # # # # # #
# g o o # . . #
# - - o o o # #
# - - # - o - #
# - - # - o # #
# - - - - o o #
# - # - - - s #
# # # # # # # #
I got an exersise where I would like to draw a line with Bressenham algorithm.
The thing is that it's working perfectly for lines who goes down and on the right, but when the line goes up or backward, it doesn't work anymore ...
Does anybody can help me on that ?
void draw_line(t_data img, int xStart, int yStart, int xEnd, int yEnd)
{
int dx;
int dy;
int pk;
int x;
int y;
dx = xEnd - xStart;
dy = yEnd - yStart;
x = xStart;
y = yStart;
while(x <= xEnd)
{
if(pk >= 0)
{
printf("in if ");
my_mlx_pixel_put(&img, x, y, 0x00FF0000);
y = y + 1;
pk = pk + 2 * dy - 2 * dx;
}
else
{
my_mlx_pixel_put(&img, x, y, 0x00FF0000);
pk = pk + 2 * dy;
}
x = x + 1;
count ++;
}
}
Its working for this
draw_line(img, 300, 300, 400, 360);
But not for this
draw_line(img, 300, 300, 200, 260);
Thanks for your help !!
You are working in the first octant. If you want to draw lines in all direction you have to check the 8 octant.
here is my implentation of bresenham for the 8 octant:
void bresenham(int x1, int y1, int x2, int y2) {
int dx = x2 - x1;
int dy = y2 - y1;
int error;
/** first quarter */
if(dx >= 0 && dy >= 0) {
/** 1st octant */
if (dx >= dy) {
error = -dx;
int y = y1;
for(int x = x1; x < x2; x++) {
draw_pixel(x, y);
error = error + 2 * dy;
if (error >= 0) {
y++;
error = error - 2 * dx;
}
}
}
/** 2nd octant */
else {
error = -dy;
int x = x1;
for(int y = y1; y < y2; y++) {
draw_pixel(x, y);
error = error + 2 * dx;
if (error >= 0) {
x++;
error = error - 2 * dy ;
}
}
}
}
/** second quarter */
else if (dx <= 0 && dy >= 0) {
/** 4th octant */
if(dx < -dy) {
error = dx;
int y = y1;
for(int x = x1; x > x2; x--) {
draw_pixel(x, y);
error = error + 2 * dy;
if (error >= 0) {
y++;
error = error + 2 * dx;
}
}
}
/** 3rd octant */
else {
error = -dy;
int x = x1;
for(int y = y1; y < y2; y++) {
draw_pixel(x, y);
error = error - 2 * dx;
if (error >= 0) {
x--;
error = error - 2 * dy;
}
}
}
}
/** 3rd quarter */
else if (dx <= 0 && dy <= 0) {
/** 5th octant */
if(dx <= dy) {
error = 2 * dx;
int y = y1;
for(int x = x1; x > x2; x--) {
draw_pixel(x, y);
error = error - 2 * dy;
if (error >= 0) {
y--;
error = error + 2 * dx;
}
}
}
/** 6th octant */
else {
error = 2 * dy;
int x = x1;
for(int y = y1; y > y2; y--) {
draw_pixel(x, y);
error = error - 2 * dx;
if (error >= 0) {
x--;
error = error + 2 * dy ;
}
}
}
}
/* 4th quarter */
else if(dx >= 0 && dy <= 0) {
/** 7th octant */
if(dx < -dy) {
error = 2 * dy;
int x = x1;
for(int y = y1; y > y2; y--) {
draw_pixel(x, y);
error = error + 2 * dx;
if (error >= 0) {
x++;
error = error + 2 * dy ;
}
}
}
/** 8th octant */
else {
error = -dx;
int y = y1;
for(int x = x1; x < x2; x++) {
draw_pixel(x, y);
error = error - 2 * dy;
if (error >= 0) {
y--;
error = error - 2 * dx;
}
}
}
}
}
I'm trying to make a snake game in which if the snake eats the first fruit and in 2 seconds eats the second fruit then it's score multiplied by 2. If the snake eats the second fruit in 1 second then the score is multiplied by 3. If the snake eats the second fruit in 3 seconds then the score is increased just by 1 and so on ... But i can't display the fruit. I declared the fruit in this function
void make_stage() {
for (int i = 1; i <= 17; i++) {
gotoxy(i, 1);
printf("#");
gotoxy(1, i);
printf("#");
gotoxy(17, i);
printf("#");
gotoxy(i, 17);
printf("#");
}
x = height / 2;
y = width / 2;
label1:
fruitx = rand() % 20;
if (fruitx == 0)
goto label1;
label2:
fruity = rand() % 20;
if (fruity == 0)
goto label2;
score = 0;
if (i == fruitx)
printf("*");
}
Does anybody know why the fruit is not visible? Thanks!
This is my whole code:
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
int i, j, height = 17, width = 17;
int score;
int x, y, fruitx, fruity, flag;
typedef struct RECORD {
char name[100];
int score;
int time;
}record; //Name, Points,Time
record nowrec;
void gotoxy(int x, int y); //Input location
void make_stage(); //stage
int getCommand(); // Keyboard input
void gameover(); //Gameover screen
void startscr(); //Start screen
void snake_move(); //Snake movements
void rank_call(); //Displaying rank
void rankrecord(); //personal records
void cursor(int i); //커서 상태 변경
void time_show();
int main(void) {
startscr();
return 0;
}
void gotoxy(int x, int y) {
COORD pos = { 30 + x * 2, 10 + y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void make_stage() {
for (int i = 1; i <= 17; i++) {
gotoxy(i, 1);
printf("#");
gotoxy(1, i);
printf("#");
gotoxy(17, i);
printf("#");
gotoxy(i, 17);
printf("#");
}
x = height / 2;
y = width / 2;
label1:
fruitx = rand() % 20;
if (fruitx == 0)
goto label1;
label2:
fruity = rand() % 20;
if (fruity == 0)
goto label2;
score = 0;
if (i == fruitx)
printf("*");
}
int getCommand() {
if (_kbhit()) {
return _getch();
}
return -1;
}
void cursor(int i) {
CONSOLE_CURSOR_INFO cursorInfo = { 0, };
cursorInfo.dwSize = 1;
cursorInfo.bVisible = i;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
void rank_call() {
FILE* rank;
char reading[100];
if (fopen_s(&rank, "rank.txt", "r") != 0) printf("no record\n");
else {
printf("\n");
while ((fgets(reading, 100, rank) != NULL)) printf("%s", reading);
fclose(rank);
printf("\n");
}
}
void rankrecord() {
printf("\npress enter to proceed...\n");
while (getchar() != '\n');
printf("press r to record your ranking...");
char input = _getch();
if (input == 'r') {
FILE* rank;
fopen_s(&rank, "rank.txt", "a");
while (getchar() != '\n');
printf("enter your name: ");
gets_s(nowrec.name, sizeof(nowrec.name));
fprintf(rank, "%s %d %d\n", nowrec.name, nowrec.score, nowrec.time);
fclose(rank);
}
}
void startscr()
{
system("mode con cols=100 lines=40");
start:
system("cls");
printf(" ****** ** * * * * ****** ****** * ** ** ****** \n");
printf(" * * * * * * * * * * * * * * * * * \n");
printf(" ****** * * * ***** **** ****** * *** ***** * * * * ****** \n");
printf(" * * * * * * * * * * * * * * ** * * \n");
printf(" ****** * ** * * * * ****** ****** * * * ** * ****** \n");
printf("\npress s to start game\n");
printf("press r to see ranking\n");
printf("press x to exit\n:");
char input = _getch();
if (input == 's') {
system("cls");
cursor(0);
make_stage();
snake_move();
}
else if (input == 'r') {
rank_call();
printf("press enter to continue...");
while (getchar() != '\n');
goto start;
}
else if (input == 'x') exit(0);
else {
printf("wrong input\n");
printf("press enter to continue...");
while (getchar() != '\n');
goto start;
}
}
void gameover() {
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n");
printf(" ****** * ** ** ****** **** * * ****** ***** \n");
printf(" * * * * * * * * * * * * * * * \n");
printf(" * *** ***** * * * * ****** * * * * ****** ***** \n");
printf(" * * * * * ** * * * * * * * * * \n");
printf(" ****** * * * ** * ****** **** * ****** * * \n");
cursor(1);
rankrecord();
}
void snake_move() {
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
while (1) {
input = _getch();
if ((dir == 'w' && input != 's') || (dir == 'a' && input != 'd') || (dir == 's' && input != 'w') || (dir == 'd' && input != 'a')) {
if (input == 'w') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y - 1;
if (y == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'w';
}
if (input == 'a') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x - 1;
if (x == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'a';
}
if (input == 's') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y + 1;
if (y == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 's';
}
if (input == 'd') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x + 1;
if (x == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'd';
}
}
if (input == 'p') {
gameover();
break;
}
}
}
void time_show() { //아직 미완성(not completed)
clock_t s, n;
s = clock();
while (1) {
while (1) {
n = clock();
printf("\r"); //커서 왼쪽 끝으로 이동(스테이지의 위치에 따라 수정할 예정)
printf("Time-\t %d : %d : %d ", ((n - s) / 1000) / 60, ((n - s) / 1000) % 60, (n - s) % 1000);
if (_kbhit()) break; //키보드 입력이 들어오면 break;
}
if (_getch() == 'p') { //만약 그것이 p이면
printf("\rTime-\t %d : %d : %d ", ((n - s) / 1000) / 60, ((n - s) / 1000) % 60, (n - s) % 1000);
_getch();
}
else break;
s = s + (clock() - n);
}
printf("\rTime-\t %d : %d : %d ", ((n - s) / 1000) / 60, ((n - s) / 1000) % 60, (n - s) % 1000);
_getch(); _getch();
printf("\n\n\n");
return;
}
I do not get why you do the if statement to check if i == fruitx in your make_stage function. What do you expect i to be at this moment? I would also suggest to add a function call before printing the fruit:
//if (i == fruitx)
gotoxy(fruitx, fruity);
printf("f");
I'm trying to create a function to draw a straight line by reading two points from the user, (x1,y1) where the line begins and (x2,y2) where it ends.
here's my function:
void line(struct pixels* screen)
{
float X, Y;
int i, j, x1, y1, x2, y2, mX, mY;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if ((x1 >= 0 && x1 <= screen->width) && (y1 >= 0 && y1 <= screen->height) && (x2 >= 0 && x2 <= screen->width) && (y2 >= 0 && y2 <= screen->height))
{
X = (x2 - x1);
Y = (y2 - y1);
if (X < 0)
mX = X*(-1);
else
mX = X;
if (Y < 0)
mY = Y*(-1);
else
mY = Y;
if( mX>mY )
{
if (X > 0)
{
for (i = 0; i < X; i++)
{
j = (int)(((i*Y) / X) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
else
{
for (i = 0; i > X; i--)
{
j = (int)(((i*Y) / X) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
}
else
{
if (Y > 0)
{
for (j = 0; j < Y; j++)
{
i = (int)(((j*X) / Y) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
else
{
for (j = 0; j > Y; j--)
{
i = (int)(((j*X) / Y) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
}
}
else
printf("ERROR: coordinates exceed the screen limits\n");
}
the problem is : when the user enters for example line from (1,1) to (10,10) the code works perfectly, but when it's from (10,10) to (1,1) it doesn't work!
Google Bresenham’s Line Drawing Algorithm. There is a fantastic tutorial/explanation of how do to this kind of thing at How OpenGL works: software renderer in 500 lines of code. Your specific question is brought up in the article. Highly recommended.
Here is his C++ implementation:
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
bool steep = false;
if (std::abs(x0-x1)<std::abs(y0-y1)) {
std::swap(x0, y0);
std::swap(x1, y1);
steep = true;
}
if (x0>x1) {
std::swap(x0, x1);
std::swap(y0, y1);
}
int dx = x1-x0;
int dy = y1-y0;
float derror = std::abs(dy/float(dx));
float error = 0;
int y = y0;
for (int x=x0; x<=x1; x++) {
if (steep) {
image.set(y, x, color);
} else {
image.set(x, y, color);
}
error += derror;
if (error>.5) {
y += (y1>y0?1:-1);
error -= 1.;
}
}
}