online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
// Emilio Espada and Kameron Dear // CS 355 - Systems Programming Course Project - Spring 2024 // Implement a classic snake game // Final deliverable 05/02/2024 #include <curses.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> // struct to define position for game objects (snake,body,trophy,direction) -Emilio struct position { int x; int y; }; // Delcaration of global variables to be used throughout program and functions -Emilio int length = 2; // Length of snake's body, increases when a trophy is touched int max_y, max_x; // max height and width of screen int halfPerimter; // half perimeter of screen int alive = 1; // Control if game is over or not int win = 0; // determines if game won message prints at end // Functions declarations, used in the main function void initializeGame(); // Run required curses function calls, get screen size, and set rand seed -Emilio void drawSnakePit(int max_y, int max_x); // Snake Pit -Kameron void changeDirection(struct position *direction); // Change snake's moving direction -Emilio void updateSnakePosition(struct position *body, struct position *head, struct position direction); // Update posistions -Emilio int collision(struct position a, struct position b); // Collision detection -Emilio void checkWinLoss(struct position head, struct position *body); // Check win/loss -Emilio void trophyPlacement(struct position* body, struct position head, struct position* trophy); // Trophy placement -Emilio void drawScreen(struct position *body, struct position head, struct position trophy); // Draw updated positions -Emilio int main() { initializeGame(); // Function call to initalize curses, get screen size, set rand seed // struct position declarations for game objects -Emilio struct position head = {max_x/4, max_y/2}; // position for snake's head, start around center of the screen struct position direction = {1, 0}; // position for snake's moving direction, snake starts off moving right struct position body[halfPerimter+10]; // position for snake's body, declared as an array struct position trophy; // position for trophy, randomly position within snakepit borders trophyPlacement(body, head, &trophy); // Function call to place trophy at a valid spot // Game loop that runs until user presses ctrl+c, gameover, or victory -Emilio while(alive){ drawSnakePit(max_y, max_x); // Function call to draw the border changeDirection(&direction); // Function call to change direction of snake based on arrow key presses updateSnakePosition(body, &head, direction); // Function call to update positions checkWinLoss(head, body); // Function call to check for win and loss conditions // If snake is on same space as trophy, increase snake's length and change position of trophy - Emilio if (head.x == trophy.x && head.y == trophy.y){ length += 1; trophyPlacement(body, head, &trophy); // Function call to place trophy at valid spot } erase(); // Clear screen drawScreen(body, head, trophy); // Function call to draw updated game object positions usleep(110000-(length*1000)); // Speed of game is modified by snake's length } endwin(); // Restore terminal to normal and print results of game printf("*** GAME OVER ***\n"); if (win) printf("*** YOU WON! ***\n"); else printf("*** YOU LOST! ***\n"); return 0; } // Function to initialize required curses function calls, get screen size, and set rand seed -Emilio void initializeGame() { initscr(); // Initalizes screen using curses keypad(stdscr, TRUE); // Enable the use of keypad for the snake direction logic below nodelay(stdscr, TRUE); // Allow program to run continously without waiting for user input curs_set(0); // Hide cursor from being shown noecho(); // Hide user input from showing if they press a non-arrowkey getmaxyx(stdscr, max_y, max_x); // Get the dimensions of the terminal window -Kameron halfPerimter = max_x + (max_y - 2); // Used for victory condition and max snake length srand(length * halfPerimter); // change random seed without including time.h } // Function to draw the snake pit border -Kameron void drawSnakePit(int max_y, int max_x) { // Draw snake pit border across the top of the window for (int i = 0; i < max_x; i++) { mvaddch(0, i, '-'); } // Draw snake pit border across the bottom of the window for (int i = 0; i < max_x; i++) { mvaddch(max_y - 1, i, '-'); } // Draw snake pit border across the left and right sides of the window for (int i = 1; i < max_y - 1; i++) { mvaddch(i, 0, '|'); mvaddch(i, max_x - 1, '|'); } } // Function to change direction of snake based on arrow key presses -Emilio void changeDirection(struct position *direction) { int ch = getch(); switch (ch) { case KEY_UP: if (direction->y == 1) // Kills snake if you attempt to reverse direction alive = 0; direction->x = 0; direction->y = -1; break; case KEY_DOWN: if (direction->y == -1) alive = 0; direction->x = 0; direction->y = 1; break; case KEY_LEFT: if (direction->x == 1) alive = 0; direction->x = -1; direction->y = 0; break; case KEY_RIGHT: if (direction->x == -1) alive = 0; direction->x = 1; direction->y = 0; break; } } // Function to determine position for snake head, body, and direction -Emilio void updateSnakePosition(struct position *body, struct position *head, struct position direction) { for (int i = length; i > 0; i--) { body[i] = body[i - 1]; } body[0] = *head; head->x += direction.x; head->y += direction.y; } // Look at the position of a compared to b (ie. snake to it's body, or snake to wall) -Emilio int collision(struct position a, struct position b) { if (a.x == b.x && a.y == b.y) { return 1; // If a's and b's x and y positiona are the same return 1; } return 0; // otherwise, return 0 no collision } // Check if snake's position or length leads to a gameover or victory -Emilio void checkWinLoss(struct position head, struct position *body) { // Check if the snake hits the border if (head.x == 0 || head.x == max_x / 2 || head.y == 0 || head.y == max_y - 1) alive = 0; // Check if the snake runs into itself for (int i = 0; i < length; i++) if (collision(head, body[i])) alive = 0; // Check if the player wins the game if (length >= halfPerimter) { win = 1; alive = 0; } } // Function to generate a random position for the trophy that doesn't overlap with the snake -Emilio void trophyPlacement(struct position* body, struct position head, struct position* trophy) { do { // Set the x and y position of trophy to a random number trophy->x = rand() % (max_x/2 - 1) + 1; trophy->y = rand() % (max_y - 2) + 1; // Check if the trophy overlaps with the snake's head if (collision(*trophy, head)) { continue; // If it does, start the do loop again from the beginning } // Check if the trophy overlaps with any part of the snake's body for (int i = 0; i < length; i++) { if (collision(*trophy, body[i])) { continue; } } // If no overlap is found, break out of the loop break; } while (1); // Loops continues until a valid trophy position is found } // Function to draw the updated position of game objects -Emilio void drawScreen(struct position *body, struct position head, struct position trophy) { mvaddch(trophy.y, trophy.x * 2, '@'); // Draw trophy at its position, x*2 to stay consistent with snake for (int i = 0; i < length; i++) // Draw snake's body mvaddch(body[i].y, body[i].x * 2, 'o'); //mult by 2 so horizontal speed = vertical mvaddch(head.y, head.x * 2, 'O'); //head.x is mult by 2 so horizontal speed = vertical }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue