#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>

#define WIDTH 30
#define HEIGHT 20
#define MAX_SNAKE_LEN 100

#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77

void Difficulty_Level(void);
void gotoxy(int x, int y);
void setColor(int color);
void hide_cursor(void);
void initGame();
void drawMap();
void generateFood();
void handleInput();
void update();

int level;

typedef struct{
	int x;
	int y;
} Point;

Point snake[MAX_SNAKE_LEN];
int snakeLen = 3;
Point food;
int dirX = 1, dirY = 0;
int score = 0;
int isGameOver = 0;

int main(void){
    Difficulty_Level();
    initGame();
    
    while(!isGameOver){
        handleInput();
        update();
        
        gotoxy(0, HEIGHT + 3);
        printf("Score: %d   ", score);
        
        Sleep(100 / level);
	}
}

void Difficulty_Level(void){
    int result;

    system("cls");

    printf("================================\n");
    printf("        SNAKE GAME\n");
    printf("================================\n\n");

    printf("난이도를 설정해 주세요.\n");
    printf("숫자가 클수록 게임이 빨라집니다.\n");
    printf("자연수만 입력해 주세요.\n\n");

    while(1) {
        printf("난이도 : ");

        result = scanf("%d", &level);
        
        if(result != 1) {
            int c;

            while((c = getchar()) != '\n' && c != EOF);

            printf("잘못된 입력입니다. 자연수를 입력하세요.\n\n");
            continue;
        }

        if(level > 0) {
            break;
        }

        printf("1 이상의 숫자를 입력하세요.\n\n");
    }

    printf("\n아무 키나 누르면 시작합니다...");
    _getch();
}

void gotoxy(int x, int y){
	COORD pos = {x, y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void setColor(int color){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
	//ex) setColor(14);
}

void hide_cursor(void){
	CONSOLE_CURSOR_INFO cursorInfo;
	cursorInfo.dwSize = 1;
	cursorInfo.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}

void initGame(void)
{
    system("cls");
    hide_cursor();

    snakeLen = 3;
    score = 0;
    isGameOver = 0;

    dirX = 1;
    dirY = 0;

    drawMap();

    int startX = WIDTH / 2;
    int startY = HEIGHT / 2;

    for(int i=0; i<snakeLen; i++){
        snake[i].x = startX - i;
        snake[i].y = startY;
    }

    srand((unsigned int)time(NULL));

    for(int i=0; i<snakeLen; i++){
        gotoxy(snake[i].x, snake[i].y);

        if(i == 0)
            printf("O");
        else
            printf("o");
    }

    generateFood();
}

void drawMap(){
	for(int i=0; i<WIDTH+2; i++) printf("#");
	printf("\n");
	
	for(int i=0; i<HEIGHT; i++){
		printf("#");
		for(int j=0; j<WIDTH; j++){
			printf(" ");
		}
		printf("#\n");
	}
	for(int i=0; i<WIDTH+2; i++) printf("#");
	printf("\n");
}

void generateFood(){
	while(1){
		int valid = 1;
		food.x = (rand() % WIDTH) + 1;
		food.y = (rand() % HEIGHT) + 1;
		
		for(int i=0; i<snakeLen; i++){
			if(snake[i].x == food.x && snake[i].y == food.y){
				valid = 0;
				break;
			}
		}
		if(valid) break;
	}
	gotoxy(food.x, food.y);
	printf("*");
}

void handleInput(){
	if(_kbhit()){
		int key = _getch();
		if(key == 224){
			key = _getch();
			switch(key){
				case UP:
					if(dirY != 1) {dirX = 0; dirY = -1;}
					break;
				case DOWN:
					if(dirY != -1) {dirX = 0; dirY = 1;}
					break;
				case LEFT:
					if(dirX != 1) {dirX = -1; dirY = 0;}
					break;
				case RIGHT:
					if(dirX != -1) {dirX = 1; dirY = 0;}
					break;
			}
		}
	}
}

void update(void){
    Point newHead;
    int ateFood = 0;

    newHead = snake[0];

    newHead.x += dirX;
    newHead.y += dirY;

    if(newHead.x <= 0 ||
    	newHead.x >= WIDTH + 1 ||
        newHead.y <= 0 ||
        newHead.y >= HEIGHT + 1) {

        isGameOver = 1;
        return;
    }

    if(newHead.x == food.x &&
        newHead.y == food.y) {

        ateFood = 1;
    }

    int checkLength = snakeLen;

    if(!ateFood && checkLength > 0) {
        checkLength--;
    }

    for(int i=0; i<checkLength; i++) {
        if (newHead.x == snake[i].x &&
            newHead.y == snake[i].y) {

            isGameOver = 1;
            return;
        }
    }

    if(!ateFood) {
        gotoxy(
            snake[snakeLen - 1].x,
            snake[snakeLen - 1].y
        );

        printf(" ");
    }

    if(ateFood) {

        if(snakeLen < MAX_SNAKE_LEN) {
            snakeLen++;
        }

        for (int i=snakeLen-1; i>0; i--) {
            snake[i] = snake[i - 1];
        }

    }
    else {

        for(int i=snakeLen-1; i>0; i--) {
            snake[i] = snake[i - 1];
        }
    }

    snake[0] = newHead;

    if(ateFood) {
        score += 10;

        generateFood();
    }

    for(int i=0; i<snakeLen; i++) {

        gotoxy(
            snake[i].x,
            snake[i].y
        );

        if (i == 0) {
            printf("O");
        }
        else {
            printf("o");
        }
    }
}

//void update(){
//	gotoxy(snake[snakeLen - 1].x, snake[snakeLen - 1].y);
//	printf(" ");
//	
//	for(int i=snakeLen-1; i>0; i--){
//		snake[i] = snake[i-1];
//	}
//	
//	snake[0].x += dirX;
//	snake[0].y += dirY;
//	
//	if(snake[0].x <= 0 || snake[0].x >= WIDTH + 1 ||
//	   snake[0].y <= 0 || snake[0].y >= HEIGHT + 1){
//	   	isGameOver = 1;
//	   	return;
//	}
//	
//	for(int i=0; i<snakeLen; i++){
//		if(snake[0].x == snake[i].x && snake[0].y == snake[i].y){
//			isGameOver = 1;
//			return;
//		}
//	}
//	
//	if(snake[0].x == food.x && snake[0].y == food.y){
//		if(snakeLen < MAX_SNAKE_LEN){
//			snakeLen++;
//		}
//		score += 10;
//		generateFood();
//	}
//	
//	for(int i=0; i<snakeLen; i++){
//		gotoxy(snake[i].x, snake[i].y);
//		if(i == 0) printf("O");
//		else printf("o");
//	}
//}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: