Deadline은 '마감 기한'이라는 의미로, 영어 단어를 맞추는 Hangman 게임을 각색하여 만든 게임이다.
기존 Hangman은 글자 수만큼 빈칸이나 밑줄을 그려서 26개 철자 중 하나를 대었을 때 단어 안에 그 글자가 있으면 단어의 해당하는 칸에 적고, 그렇지 않으면 기회를 잃게 된다.
Deadline은 사람을 매다는 방식으로 게임을 진행하지 않고, 철자가 틀릴 경우 마감 기한이 임박하는 방식으로 진행되며, 일주일이 넘기 전에 영어 단어를 맞추면 게임에서 승리한다.
▶ 게임 인트로
//DEADLINE 첫번째 인트로
void INTRO()
{
system("cls");
printf("\n\n\n");
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);
}
//DEADLINE 두번째 인트로
void INTRO2()
{
system("cls");
printf("\n");
printf(" .---. .--. .--. .---. .-. .-..-..-. .--. \n"); Sleep(50);
printf(" : . :: .--': .; :: . :: : : :: `: :: .--'\n"); Sleep(50);
printf(" : :: :: `; : :: :: :: : : :: .` :: `; \n"); Sleep(50);
printf(" : :; :: :__ : :: :: :; :: :__ : :: :. :: :__ \n"); Sleep(50);
printf(" :___.'`.__.':_;:_;:___.':___.':_;:_;:_;`.__.'\n"); Sleep(50);
}
▶ 게임 설명
//DEADLINE 정보를 메모장으로 출력
void INFORMATION()
{
FILE *fp;
//INFORMATION 메모장 불러오기
fp = fopen("INFORMATION.txt", "w");
fprintf(fp, "\n");
fprintf(fp, " ______ _______ _______ ______ ___ ___ __ _ _______ \n");
fprintf(fp, " | | | || _ || | | | | || | | || |\n");
fprintf(fp, " | _ || ___|| |_| || _ || | | || |_| || ___|\n");
fprintf(fp, " | | | || |___ | || | | || | | || || |___ \n");
fprintf(fp, " | |_| || ___|| || |_| || |___ | || _ || ___|\n");
fprintf(fp, " | || |___ | _ || || || || | | || |___ \n");
fprintf(fp, " |______| |_______||__| |__||______| |_______||___||_| |__||_______|\n");
fprintf(fp, "\n");
fprintf(fp, "\n");
fprintf(fp, " 〉프로그램 배경설명〈\n");
fprintf(fp, "\n");
fprintf(fp, " 이름 : DEADLINE 제작 / 기획 : 이승원\n");
fprintf(fp, " 설명 : 행맨 게임을 각색하여 디미고에 맞춘 영어 학습 게임입니다\n");
fprintf(fp, " 배경 : 디미고의 수행평가 제출기한 안에 문제를 맞춰야 합니다\n");
fprintf(fp, " \n");
fprintf(fp, " \n");
fprintf(fp, " 〉프로그램 사용방법〈\n");
fprintf(fp, "\n");
fprintf(fp, " ①GAME START : 게임의 시작\n");
fprintf(fp, " ②INFORMATION : 게임의 설명\n");
fprintf(fp, " ③GAME QUIT : 게임의 종료\n");
fprintf(fp, " ③VOCA MOD : 보카 단어들로 플레이\n");
fprintf(fp, " ③DIMI MOD : 학생 이름으로 플레이\n");
fprintf(fp, " ③ANY MOD : 아무 단어로나 플레이\n");
fprintf(fp, " \n");
fprintf(fp, " \n");
fprintf(fp, " 〉프로그램 추가정보〈\n");
fprintf(fp, "\n");
fprintf(fp, " 처음 시작할 때의 비밀번호는 1234입니다 후에 반드시 바꿔주세요\n");
fprintf(fp, " └비밀번호를 변경하고 싶다면 4를 입력해주세요\n");
fprintf(fp, " 오프닝 화면에서 5를 입력하면 누적한 점수를 초기화할 수 있습니다\n");
fclose(fp);
}
▶ 디렉토리 설정
게임과 deadline 폴더를 연결하여 행맨 단어와 비밀번호, 누적 점수를 저장할 수 있도록 했다.
FMOD 라이브러리를 사용하여 게임을 실행하면 자동으로 노래가 나오며, 입력할 때마다 효과음이 출력된다.
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#include <fmod.h>
//노래 채널 설정
FMOD_SYSTEM *g_System;
FMOD_SOUND *g_Sound[2];
FMOD_CHANNEL *g_Channel[2];
//노래 실행 목록
void Init(int ch1)
{
FMOD_System_Create(&g_System);
FMOD_System_Init(g_System,10,FMOD_INIT_NORMAL,NULL);
//배경음악
if(ch1==0)
{
FMOD_System_CreateSound(g_System,"BGM_TITLE.mp3",FMOD_LOOP_NORMAL,0,&g_Sound[0]);
FMOD_System_PlaySound(g_System,FMOD_CHANNEL_FREE,g_Sound[0],0,&g_Channel[0]);
}
//입력 효과음
if(ch1==1)
{
FMOD_System_CreateSound(g_System,"BGM_CLICK.mp3",FMOD_LOOP_NORMAL,0,&g_Sound[1]);
FMOD_System_PlaySound(g_System,FMOD_CHANNEL_FREE,g_Sound[1],0,&g_Channel[1]); Sleep(290);
FMOD_Channel_Stop(g_Channel[1]);
}
}
//stdio헤더파일 사용
#include "stdio.h"
//디렉토리 설정을 위한 상수 선언
#ifndef _MAX_PATH
#define _MAX_PATH 260
#endif
#define MAX_COLS 32768/
int mkdir(const char *dirname);
int chdir(const char *dirname2);
▶ 비밀번호 입력
①GAME START를 선택하면 개인 사용자 비밀번호를 입력해야 한다.
비밀번호는 exe 확장자 게임 파일의 같은 폴더 내에 암호화되어 저장되어 있으며, 프로그램 내에서 복호화하여 비밀번호를 인식한다.
저장된 비밀번호와 점수는 코드 내에서 부여한 암호화 / 복호화 키로 인해 위와 같이 외부에서 알 수 없고, 프로그램 내에서 수정하는 경우가 아니라면 적용되지 않는다.
//사용자의 비밀번호 불러오기
int loadpassword()
{
int v;
//파일을 읽기 바이너리 모드로 불러옴
FILE *file = fopen("user.txt", "rb");
if(file == NULL)
{
return 0;
}
fread((void*)&v, sizeof(int), 1, file);
v ^= # 복호화 키; //암호 해독
fclose(file);
return v;
}
//사용자 비밀번호 저장
void savepassword(int password)
{
//파일을 쓰기 바이너리 모드로 불러옴
FILE *file = fopen("user.txt", "wb");
if(file == NULL)
{
return;
}
password^= # 암호화 키; //패스워드 암호화
fwrite((void*)&password, sizeof(int), 1, file);
fclose(file);
}
//사용자 누적점수 불러오기
int loadscore()
{
int v;
//파일을 읽기 바이너리 모드로 불러옴
FILE *file = fopen("score.txt", "rb");
if(file == NULL)
{
return 0;
}
fread((void*)&v, sizeof(int), 1, file);
v ^= # 복호화 키; //암호 해독
fclose(file);
return v;
}
//사용자 누적점수 저장
void savescore(int score)
{
//파일을 쓰기 바이너리 모드로 불러움
FILE *file = fopen("score.txt", "wb");
if(file == NULL)
{
return;
}
score^= # 암호화 키; //스코어 암호화
fwrite((void*)&score, sizeof(int), 1, file);
fclose(file);
}
▶ 게임 진행
getch 함수로 아스키코드를 입력받아 ENTER 키를 누르지 않아도 자동으로 입력되도록 설정했다.
또한, 주어진 선택지 중에 입력하지 못했더라도 while문을 사용하여 재입력할 수 있다.
영어 단어는 사용자가 선택한 모드에 따라 메모장이 선택되며, 난이도에 따라 해당 메모장에 저장된 단어들 중에 랜덤으로 출제된다. 만약 사용자가 원한다면 직접 메모장에 단어를 추가해 게임을 진행할 수 있다.
정답을 맞춘 만큼 점수를 부여하고, 게임을 끄더라도 저장되므로 점수를 올리는 재미가 있다.
//프로그램 시작
int main()
{
//BGM 출력을 위한 선언
int ch1; //노래 선택
//for사용을 위한선언
int i; //중요 for 사용을 위해 선언
int j; //일반 for 사용을 위해 선언
int l; //이중 for 사용을 위해 선언
//게임 환경설정 저장
int mod; //voca_dimi_any 선택
int dif; //easy_nomal_hard 선택
//설정을 위한 플레이어의 입력
int input; //getch 사용
int password; //비교할 번호
int enterpass; //입력할 번호
int score=0; //누적 점수
//DEADLINE 저장
char voca[2000][50]; //voca 문제 저장
char dimi[100][50]; //dimi 문제 저장
char any[6000][50]; //any 문제 저장
//DEADLINE 게임 설정
char question[50]; //문제 저장
char wrong[10]; //오답 저장
char answer[50]; //정답 저장
int count[3]; //문제 개수 저장
char output[50]; //출력할 문자 저장
char hint[10]; //출력할 힌트 저장
//기타 등등
int ques; //출력할 문제의 번호를 저장
int size=0; //문제의 문자열 크기를 저장
int result=0; //입력한 문자가 문제중에 있는지 비교
int end=0; //프로그램이 끝났는지 비교
int health=0; //게임의 기회
//디렉토리 생성과 디렉토리 위치 설정
char strFolderPath[]={"deadline"};
char strBuffer[_MAX_PATH]={0,};
char strChangeDir[_MAX_PATH]={"deadline"};
FILE *fp; //메모장 사용을 위한 선언
mkdir(strFolderPath); //디렉토리 생성
chdir(strChangeDir); //디렉토리 변경
//프로그램 자체 설정
system("mode con:lines=20 cols=80"); //프로그램 크기 변경
system("title "); //프로그램 제목 변경
//프로그램 오프닝
printf("\n\n\n\n\n\n\n\n\n");
printf(" PRESS ANY KEY TO START");
getch();
password=loadpassword(); //비밀번호 불러오기
score=loadscore(); //누적점수 불러오기
//변수 초기화
for(l=0; l<=2; l++)
{
count[l]=0;
}
//voca 단어 불러오기
fp = fopen("VOCA.txt", "r");
while(!feof(fp))
{
count[0]++;
fgets(voca[count[0]], 100, fp);
}
fclose(fp);
//dimi 단어 불러오기
fp = fopen("DIMI.txt", "r");
while(!feof(fp))
{
count[1]++;
fgets(dimi[count[1]], 100, fp);
}
fclose(fp);
//any 단어 불러오기
fp = fopen("ANY.txt", "r");
while(!feof(fp))
{
count[2]++;
fgets(any[count[2]], 1000, fp);
}
fclose(fp);
//실행할 때 마다 랜덤하도록 설정
srand(time(NULL));
ch1=0; Init(ch1); //배경음악 출력
INFORMATION();
//게임 시작 루프
while(1)
{
//프로그램 설정 루프
while(1)
{
//오프닝 루프
while(1)
{
INTRO(); //첫번째 INTRO 호출
//선택지 출력과 입력 (게임시작, 게임정보, 게임나가기)
printf("\n");
printf(" ①GAME START ②INFORMATION ③GAME QUIT");
input=getch(); //선택지 입력
fflush(stdin); //enter 입력을 삭제
ch1=1; Init(ch1); //효과음 출력
//1을 입력했을 경우
if(input==49)
{
printf("\n\n");
printf(" 개인 사용자 비밀번호 코드를 입력해 주세요\n"); Sleep(75);
printf(" CODE INPUT : "); Sleep(75);
scanf("%d", &enterpass); //번호를 입력해 사용자 확인
fflush(stdin); //enter 입력을 삭제
ch1=1; Init(ch1); //효과음 출력
//저장번호와 입력번호가 같을 경우
if(password==enterpass)
{
printf("\n");
printf(" Allow Access"); //접근 허용
break;
}
//저장번호와 입력번호가 다를 경우
else
{
printf("\n");
printf(" Disallow Access"); //접근 불가
}
getchar();
}
//2를 입력했을 경우
if(input==50)
{
score=loadscore(); //누적 점수 불러오기
//프로그램 설명 출력
printf("\n\n");
printf(" 이름 : 데드라인 제작 / 기획 : 이승원\n"); Sleep(75);
printf(" 설명 : 행맨 게임을 각색하여 디미고에 맞춘 영어 학습 게임입니다\n"); Sleep(75);
printf(" 플레이어 포인트 : %d\n", score); Sleep(75);
printf("\n");
printf(" information.txt를 참고해주세요 PRESS ENTER TO PREVIUS PAGE >"); Sleep(75);
getchar();
}
//3을 입력했을 경우
if(input==51)
{
printf("\n\n ");
exit(0); //프로그램 종료
}
//4를 입력했을 경우
if(input==52)
{
printf("\n\n");
printf(" 개인 사용자 비밀번호 코드를 입력해 주세요\n"); Sleep(75);
printf(" CODE INPUT : "); Sleep(75);
fflush(stdin); //enter 입력을 삭제
scanf("%d", &enterpass); //비밀번호를 입력해 사용자 확인
//저장번호와 입력번호가 같을 경우
if(password==enterpass)
{
printf("\n");
printf(" Allow Access"); //접근 허용
}
//저장번호와 입력번호가 다를 경우
else
{
printf("\n");
printf(" Disallow Access"); //접근 불가
break;
}
getchar();
getchar();
INTRO(); //첫번째 INTRO 호출
printf("\n\n");
printf(" 새로운 사용자 비밀번호 코드를 입력해 주세요\n"); Sleep(75);
printf(" CODE INPUT : "); Sleep(75);
fflush(stdin); //enter 입력을 삭제
scanf("%d", &password); //새로운 비밀번호 입력
savepassword(password); //비밀번호 저장
}
//5를 입력했을 경우
if(input==53)
{
printf("\n\n");
printf(" 플레이어 포인트가 초기화되었습니다"); Sleep(75);
fflush(stdin); //enter 입력을 삭제
score=0; //점수를 초기화
savescore(score); //점수를 영구 저장
getchar();
}
}
//접근이 허용되었을 경우
while(1)
{
INTRO2(); //두번째 INTRO 실행
//선택지 출력과 입력 (보카모드, 디미모드, 아무거나)
printf("\n");
printf(" ①VOCA MOD ②DIMI MOD ③ANYTHING");
input=getch(); //선택지 입력
fflush(stdin); //enter 입력을 삭제
ch1=1; Init(ch1); //효과음 출력
printf("\n\n");
//1을 입력했을 경우
if(input==49)
{
printf(" VOCA MOD를 선택하셨습니다\n");
mod=1;
}
//2를 입력했을 경우
if(input==50)
{
printf(" DIMI MOD를 선택하셨습니다\n");
mod=2;
}
//3을 입력했을 경우
if(input==51)
{
printf(" ANYTHING을 선택하셨습니다\n");
mod=3;
}
//1부터 3중에 하나를 입력했을 경우
if(input>=49 && input<=51)
{
while(1)
{
printf("\n");
printf(" 난이도를 선택해 주세요\n");
printf(" ①EASY(2) ②NORMAL(1) ③HARD(0)");
input=getch(); //선택지 입력
fflush(stdin); //enter 입력을 삭제
ch1=1; Init(ch1); //효과음 출력
//1을 입력했을 경우
if(input==49)
{
printf("\n\n");
printf(" EASY(2)를 선택하셨습니다\n");
dif=1;
}
//2를 입력했을 경우
if(input==50)
{
printf("\n\n");
printf(" NORMAL(1)를 선택하셨습니다\n");
dif=2;
}
//3을 입력했을 경우
if(input==51)
{
printf("\n\n");
printf(" HARD(0)를 선택하셨습니다\n");
dif=3;
}
//1부터 3중에 하나를 입력했을 경우
if(input>=49 && input<=51)
{
printf("\n");
printf(" 게임 설정이 완료되었습니다!\n");
printf(" PRESS ENTER TO GAME START >");
getchar();
ch1=1; Init(ch1); //효과음 출력
break; //게임 설정 완료
}
//잘못 입력했을 경우
else
{
break; //게임 재설정
}
}
}
//게임 설정이 완료되었을 경우
if(input>=49 && input<=51)
{
break; //오프닝 루프에서 나가기
}
}
//게임 설정이 완료되었을 경우
if(input>=49 && input<=51)
{
break; //프로그램 설정 루프에서 나가기
}
}
system("cls"); //화면 초기화
i=0; //입력 횟수 초기화
health=0; //기회 초기화
for(j=0; j<30; j++)
{
output[j]=0; //틀린 문자 개수 초기화
wrong[j]=0; //틀린 입력 초기화
}
//mod가 voca일 경우
if(mod==1)
{
ques=rand()%((count[0]+1)-1)+1; //문제를 voca 배열 크기 안에서 출제
}
//mod가 dimi일 경우
if(mod==2)
{
ques=rand()%((count[1]+1)-1)+1; //문제를 dimi 배열 크기 안에서 출제
}
//mod가 any일 경우
if(mod==3)
{
ques=rand()%((count[2]+1)-1)+1; //문제를 any 배열 크기 안에서 출제
}
//선정된 문제를 문자열에 저장
for(j=0; j<30; j++)
{
//문자열 안이 비었을 경우
if(j+1==NULL)
{
break; //for 나가기
}
//mod가 voca일 경우
if(mod==1)
{
question[j]=voca[ques][j]; //question에 voca문제를 저장
}
//mod가 dimi일 경우
if(mod==2)
{
question[j]=dimi[ques][j]; //question에 dimi문제를 저장
}
//mod가 any일 경우
if(mod==3)
{
question[j]=any[ques][j]; //question에 any문제를 저장
}
}
//size에 문제 문자열의 크기를 저장
size=strlen(question)-1;
//easy, normal에 사용된 힌트를 랜덤지정
hint[0]=rand()%((size+0)-1)+0;
hint[1]=rand()%((size+0)-1)+0;
//본 게임 시작 루프
while(1)
{
for(j=0; j<30; j++)
{
//문자열 안이 비었을 경우
if(j+1==NULL)
{
break; //for 나가기
}
for(l=0; l<30; l++)
{
//문제와 입력한 것 중 같은 게 있을 경우
if(question[j]==answer[i-1])
{
result=0; //문자중에 같은게 있다는 것을 증명
output[j]=1; //문자열 위치에 같은게 있음을 저장
break; //for 나가기
}
}
}
//문제와 입력한 것 중에 같은게 없을 경우
if(result==1)
{
wrong[health]=answer[i-1]; //틀린 문자열에 입력한 문자를 저장
health++; //기회를 하나 소진
}
system("cls"); //화면 초기화
INTRO2(); //두번째 인트로 실행
//게임 현황 출력
printf("\n\n");
printf(" ┌───┬───┬───┬───┬───┬───┬───┐\n");
printf(" │MON TUE WED THU FRI SAT SUN│\n");
printf(" ├───┴───┴───┴───┴───┴───┴───┤\n");
printf(" ├───┬───┬───┬───┬───┬───┬───┤\n");
printf(" │ %c %c %c %c %c %c %c │\n", wrong[0], wrong[1], wrong[2], wrong[3], wrong[4], wrong[5], wrong[6]);
printf(" └───┴───┴───┴───┴───┴───┴───┘\n");
printf("\n");
printf(" QUESTION : ");
end=1; //게임을 끝나도록 함
result=1; //문제와 입력한 것 중 같은게 없게 함
//문제 출력
for(j=0; j<size; j++)
{
//easy 난이도일 경우
if(dif==1)
{
//문제의 해당 위치의 문자를 입력한 적이 있거나 hint 1이 있거나 hint 2가 있을 경우
if(output[j]==1 || question[hint[0]]==question[j] || question[hint[1]]==question[j])
{
printf("%c ", question[j]); //해당 위치의 문자를 출력
}
//문제의 해당 위치의 문자를 입력한 적이 없을 경우
else
{
end=0; //게임을 끝나지 못하게 함
printf("_ ");
}
}
//normal 난이도일 경우
if(dif==2)
{
//문제의 해당 위치의 문자를 입력한 적이 있거나 hint 1이 있을 경우
if(output[j]==1 || question[hint[0]]==question[j])
{
printf("%c ", question[j]);
}
//문제의 해당 위치의 문자를 입력한 적이 없을 경우
else
{
end=0; //게임을 끝나지 못하게 함
printf("_ ");
}
}
//hard 난이도일 경우
if(dif==3)
{
//문제의 해당 위치의 문자를 입력한 적이 있을 경우
if(output[j]==1)
{
printf("%c ", question[j]);
}
//문제의 해당 위치의 문자를 입력한 적이 없을 경우
else
{
end=0; //게임을 끝나지 못하게 함
printf("_ ");
}
}
}
//게임이 끝났을 경우
if(end==1)
{
score=score+size; //점수에 문제 문자열의 크기만큼 누적 저장
savescore(score); //점수를 영구 저장
printf("\n");
printf(" ORIGINAL WORD : %s", question); //문제 출력
printf(" YOUR POINT : %3d\n", score); //점수 출력
printf(" PRESS ENTER TO TITLE SCREEN >");
getchar();
ch1=1; Init(ch1); //효과음 출력
break; //프로그램의 처음으로 루프
}
//기회를 모두 소진했을 경우
if(health>=8)
{
printf("\n");
printf(" ORIGINAL WORD : %s", question); //문제 출력
printf(" YOUR POINT : %3d\n", score); //점수 출력
printf(" PRESS ENTER TO TITLE SCREEN >");
getchar();
ch1=1; Init(ch1); //효과음 출력
break; //프로그램의 처음으로 루프
}
printf("\n\n");
printf(" INPUT : ");
scanf("%c", &answer[i]); //스펠링 입력
fflush(stdin); //enter 입력을 삭제
ch1=1; Init(ch1); //효과음 출력
i++; //입력할 기회 소진
}
}
return 0; //프로그램 종료
}
▶ 게임 파일
▶ 순서도