T E T R I S.hwp

Source.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "head.h"
#pragma warning (disable:4996)


int STATUS_Y_GOAL; //GOAL 정보표시위치Y 좌표 저장 
int STATUS_Y_LEVEL; //LEVEL 정보표시위치Y 좌표 저장
int STATUS_Y_SCORE; //SCORE 정보표시위치Y 좌표 저장
typedef enum { NOCURSOR, SOLIDCURSOR, NORMALCURSOR } CURSOR_TYPE; //커서숨기는 함수에 사용되는 열거형 

int new_block_on;
int main_cpy[MAP_Y][MAP_X];
int main_org[MAP_Y][MAP_X];
int b_x = (MAP_X / 2) - 1; //블럭의 x좌표
int b_y = 0; //블럭의 y좌표
int temp[4][4];
int key = 0;
int crash_num = 0;
int game_speed = 1000;
int level=0; 
int re_line = 0;
int old_score=0;
int now_score=0;
int best_score=0;
int map_check = 0;
int block_high = 0;
int hard_down = 0;

void check_crash(int x, int y);
void key_ent();
void move_block(int key);
void map_reset();
void gotoxy(int x, int y);
void map();
char start();
void new_block();
void block_turn(int block[4][4]);
void setcursortype(CURSOR_TYPE c);
void auto_down_blcok(void *p);
void line_check();
void game_over();
void score_map();
void drop_block(void);

void main() {
	char choice;
	setcursortype(NOCURSOR);
	choice = start();
	if (choice == '1') {
		map_reset();
		_beginthread(auto_down_blcok, 0, 0);
		score_map();
		while (1) {
			key_ent();
		}
	}
	else {
		exit(1);
	}
	return;
}

//자동으로 내려가는 부분
void auto_down_blcok(void *p) {
	Sleep(1000);
	while (1) {
		if (map_check != 1 && hard_down == 0) {
			check_crash(b_x, b_y + 1);
			if (crash_num == 0) {
				move_block(DOWN);
				map();
			}
			else {
				for (int i = 0; i < 4; i++)
					for (int j = 0; j < 4; j++)
						if (main_org[b_y + i][b_x +j] == ACTIVE_BLOCK) main_org[b_y + i][b_x+j] = INACTIVE_BLOCK;
				new_block();
			}
			Sleep(game_speed);
		}
		game_over();
	}
}

//커서 없애는 함수
void setcursortype(CURSOR_TYPE c) { //커서숨기는 함수 
	CONSOLE_CURSOR_INFO CurInfo;

	switch (c) {
	case NOCURSOR:
		CurInfo.dwSize = 1;
		CurInfo.bVisible = FALSE;
		break;
	case SOLIDCURSOR:
		CurInfo.dwSize = 100;
		CurInfo.bVisible = TRUE;
		break;
	case NORMALCURSOR:
		CurInfo.dwSize = 20;
		CurInfo.bVisible = TRUE;
		break;
	}
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &CurInfo);
}

//키 입력받는 함수
void key_ent() {
	key = 0;
	if (kbhit()) {

		key = getch();

		if (key == 224) {

			do {
				key = getch();
			} while (key == 244);

			switch (key)
			{
			case DOWN: {
				check_crash(b_x, b_y + 1);
				if (crash_num == 0) move_block(DOWN);
				map();
				break;
			}
			case RIGHT: {
				check_crash(b_x + 1, b_y);
				if (crash_num == 0) move_block(RIGHT);
				map();
				break;
			}
			case LEFT: {
				check_crash(b_x - 1, b_y);
				if (crash_num == 0) move_block(LEFT);
				map();
				break;
			}
			case UP: {
				block_turn(temp);
				map();
				break;
			}
			default:
				break;
			}
		}
		else {
			switch (key)
			{
			case SPACE: {
				move_block(SPACE);
				map();
				break;
			}
			default:
				break;
			}

		}
		fflush(stdin);
	}
}

//초기화면
char start() {
	printf("                                                                           \n\n\n"); Sleep(50);
	printf("                                                ■■■                         \n"); Sleep(50);
	printf("       ■■■■■                ■■■■■    ■    ■             ■■       \n"); Sleep(50);
	printf("           ■      ■■■■          ■        ■■■      ■     ■    ■     \n"); Sleep(50);
	printf("           ■      ■                ■        ■■        ■    ■            \n"); Sleep(50);
	printf("           ■      ■■■■          ■        ■  ■      ■     ■           \n"); Sleep(50);
	printf("           ■      ■                ■        ■    ■    ■       ■■       \n"); Sleep(50);
	printf("                   ■■■■          ■        ■      ■  ■           ■     \n"); Sleep(50);
	printf("                                                           ■            ■    \n"); Sleep(50);
	printf("                                                                  ■    ■     \n"); Sleep(50);
	printf("                                                                    ■■       \n"); Sleep(50);
	printf("                             1. START                                          \n"); Sleep(50);
	printf("                             2. EXIT                                           \n"); Sleep(50);
	printf("                                                                               \n");
	char num = getch();
	system("cls");
	return num;
}

//점수출력
void score_map() {
	int y = 3;
	gotoxy(STATUS_X_ADJ, STATUS_Y_LEVEL = y); printf(" LEVEL : %5d", level);
	gotoxy(STATUS_X_ADJ, STATUS_Y_GOAL = y + 1); printf(" GOAL  : %5d", 10 - re_line);
	gotoxy(STATUS_X_ADJ, y + 2); printf("+-  N E X T  -+ ");
	gotoxy(STATUS_X_ADJ, y + 3); printf("|             | ");
	gotoxy(STATUS_X_ADJ, y + 4); printf("|             | "); //수정
	gotoxy(STATUS_X_ADJ, y + 5); printf("|             | ");
	gotoxy(STATUS_X_ADJ, y + 6); printf("|             | ");
	gotoxy(STATUS_X_ADJ, y + 7); printf("+-- -  -  - --+ ");
	gotoxy(STATUS_X_ADJ, y + 8); printf(" YOUR SCORE :");
	gotoxy(STATUS_X_ADJ, STATUS_Y_SCORE = y + 9); printf("        %6d", now_score);
	gotoxy(STATUS_X_ADJ, y + 10); printf(" LAST SCORE :");
	gotoxy(STATUS_X_ADJ, y + 11); printf("        %6d", old_score);
	gotoxy(STATUS_X_ADJ, y + 12); printf(" BEST SCORE :");
	gotoxy(STATUS_X_ADJ, y + 13); printf("        %6d", best_score);
	gotoxy(STATUS_X_ADJ, y + 15); printf("http://jmy0904.tistory.com");
}

//맵을 그려주는 함수
void map() {
	map_check = 1;
	for (int j = 1; j0) { 
				temp_++;
			}
		}
	}
	if (temp_ != 0) crash_num = 1;
	else { crash_num = 0; }
	line_check();
}

//블럭 이동함수
void move_block(int key) {
	
	switch (key)
	{
	case DOWN: { //아래
 		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2) {
					main_org[b_y + i][b_x + j] = EMPTY;
				}
			}
		}
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2)
					main_org[b_y + i + 1][b_x + j] = ACTIVE_BLOCK; //함수로 줄이기
			}
		}
		b_y++;
		break;
	}
	case RIGHT: { //오른쪽
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2 && temp[i][j] != WALL) {
					main_org[b_y + i][b_x + j] = EMPTY;
				}
			}
		}
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2)
					main_org[b_y + i][b_x + j + 1] = ACTIVE_BLOCK;
			}
		}
		b_x++;
		break;
	}
	case LEFT: { //왼쪽
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2) {
					main_org[b_y + i][b_x + j] = EMPTY;
				}
			}
		}
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2)
					main_org[b_y + i][b_x + j - 1] = ACTIVE_BLOCK;
			}
		}
		b_x--;
		break;
	}
	case UP: { //턴
		block_turn(temp);
		break;
	}
	/*case SPACE: {
		hard_down = 1;
		drop_block();
		
	}*/
	default:
		break;
	}
	game_over();
		
}

//블럭 회전 함수
void block_turn(int block[4][4]) {
	int arr[4][4];
	int n1, n2;
	n1 = 0;

	for (int i = 0; i < 4; i++) {
		n2 = 0;
		for (int j = 3; j > -1; j--) {
			arr[n1][n2] = block[j][i];
			n2++;
		}
		n1++;
	}
	//check_crash_turn(b_x+1, b_y+1, *arr);
	if (crash_num == 0) {
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2) {
					main_org[b_y + i][b_x + j] = EMPTY;
				}
			}
		}
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++)
				temp[i][j] = arr[i][j];
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (temp[i][j] == -2)
					main_org[b_y + i][b_x + j] = ACTIVE_BLOCK;
			}
		}
	}
}

//한줄이 다 채워졌는지를 체크후 제거
void line_check() {
	int block = 0;
	for (int i = MAP_Y - 2; i > 3;) {
		block = 0;
		for (int x = 1; x < MAP_X - 1; x++)
			if (main_org[i][x]>0) block++;
		if (block == MAP_X - 2) {
			for (int k = i; k > 1; k--) { //윗줄을 한칸씩 모두 내림(윗줄이 천장이 아닌 경우에만) 
				for (int l = 1; l < MAP_X - 1; l++) {
					if (main_org[k - 1][l] != CEILLING) main_org[k][l] = main_org[k - 1][l];
					if (main_org[k - 1][l] == CEILLING) main_org[k][l] = EMPTY;
				}
			}
			if (re_line == 10) {
				level++; 
				game_speed -= 100;
				re_line = 0;
			}
			now_score += 500;
			re_line++;
			gotoxy(STATUS_X_ADJ, STATUS_Y_LEVEL); printf(" LEVEL : %5d", level);
			gotoxy(STATUS_X_ADJ, STATUS_Y_GOAL); printf(" GOAL  : %5d", 10 - re_line);
			gotoxy(STATUS_X_ADJ, STATUS_Y_SCORE); printf("        %6d", now_score);
		}
		else i--;
	}
}

//게임오버 함수
void game_over() {
	for (int i = 1; i < MAP_X - 1;i++)
		if (main_org[3][i]==INACTIVE_BLOCK) {
			system("cls");
			printf("Game_Over\n");
			exit(1);
		}
}

/*void drop_block(void) {
	while (crash_num == 0) {
		check_crash(b_x, b_y + 1);
		move_block(DOWN);
	}
	hard_down = 0;
}*/

Head.h
#pragma once

#define RIGHT 77
#define LEFT 75
#define UP 72
#define DOWN 80
#define SPACE 32
#define MAP_X 11
#define MAP_Y 23
#define MAIN_X 3
#define MAIN_Y 1

#define ACTIVE_BLOCK -2 //현재 이동중인 블럭
#define CEILLING -1 //블럭이 이동할수 있는 위치는 0이나 음의 정수로 표현
#define EMPTY 0 
#define WALL 1     //블럭이 이동할수 없는 위치는 양의 정수로 표현
#define INACTIVE_BLOCK 2
#define STATUS_X_ADJ MAIN_X+MAP_X+1 //게임정보표시 위치조정 


+ Recent posts