작성자:홍석준 작성일:2003-05-22 ~ 25
1. main.cpp
#ifndef __MAIN_CPP__
#define __MAIN_CPP__
#define WIN32_LEAN_AND_MEAN
#include "Main.H"
#include "resource.H"
LRESULT CALLBACK AccessGame(HWND,UINT,WPARAM,LPARAM);
HINSTANCE TasInst;
int WINAPI WinMain
(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpszArgs,
int nCmdShow
)
{
WNDCLASS wc;
wc.style=0;
wc.lpfnWndProc=AccessGame;
wc.lpszClassName=dszClassName;
wc.lpszMenuName=MAKEINTRESOURCE(TASMENU);
wc.hbrBackground=GetStockObject(BLACK_BRUSH);
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(TASICON_WPION));
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.cbClsExtra=0;
wc.cbWndExtra=0;
if(!RegisterClass(&wc)) return 0;
HWND hWnd=CreateWindow
(
dszClassName,
dszTitle,
WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX,
50,
50,
500,385, // 윈도우의 크기
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
TasInst=hInstance;
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
#endif
2. start.cpp
/* 윈도우 프로시져 함수 AccessGame()
게임 메인함수 자체를 프로시져 함수로 등록해서
그냥 쓰기편하게 했으며,메뉴의 제어와 마우스 제어를 담당
합니다.
-SJ,Hong 홍 석준-
*/
#ifndef __START__CPP__
#define __START__CPP__
#include <windows.h>
#include "start.h"
#include "resource.h"
#include "main.h"
char *TempStr=""; // 임시로 문자열을 담기 위함..
int Click=0; // 마우스 클릭상태의 여부
char Temp=0; // 임시로 그냥 여러군데 사용?
int ClickX=0,ClickY=0,Nowmx=0,Nowmy=0;
// 변수설명
// ClickX,ClickY = 이동할 것의 클릭된곳의 ChessBoard상의 배열좌표
// Nowmx=이동할 영역의 클릭된곳의 ChessBoard상의 배열좌표
char ChessBoard[8][8]= // 체스판
{
{12,10,9,7,8,9,10,12},
{11,11,11,11,11,11,11,11},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{5,5,5,5,5,5,5,5},
{6,4,3,2,1,3,4,6}
};
int ChkMove(int sx, int sy, int ex, int ey, int unit); // 함수등록
char Soonser=0; // 천사족의 차례인가 악마족의 차례?
LRESULT CALLBACK AccessGame(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int i,j,Cl;
HDC hDC; // 메인 디바이스 컨텍스트
HDC hMemDC; // 메모리 DC
HBITMAP hBmp; // 메모리 DC의 이미지를 담고있는 비트맵
hDC=GetDC(hWnd);
hMemDC=CreateCompatibleDC(hDC);
hBmp=CreateCompatibleBitmap(hDC,500,380);
SelectObject(hMemDC,hBmp);
SetBkMode(hDC,TRANSPARENT); // 글자배경 넣지 않기
HICON Icon;
if(msg==NULL)return 0; // 메세지가 없으면 종료
SelectObject(hMemDC,GetStockObject(DKGRAY_BRUSH));
SelectObject(hMemDC,GetStockObject(BLACK_PEN));
Rectangle(hMemDC,0,0,499,384); // 메모리 DC를 깨끗하게 지운다.
// 게임 제어 //
for(i=0;i<8;i++)
{
if((i%2)==0)Cl=0; // Cl은 체스판 색을 지그재그로 하기위해서
else Cl=1;
for(j=0;j<8;j++) // 이 for문에서 체스판그리기, 말그리기를 함.
{
if(Cl) SelectObject(hMemDC,GetStockObject(GRAY_BRUSH));
else SelectObject(hMemDC,GetStockObject(WHITE_BRUSH));
if(i==ClickY && j==ClickX && Click==1)
SelectObject(hMemDC,GetStockObject(LTGRAY_BRUSH));
SelectObject(hMemDC,GetStockObject(BLACK_PEN));
Rectangle(hMemDC,40*j+10,40*i+10,40*j+10+40,40*i+10+40);
Cl=1-Cl;
switch(ChessBoard[i][j])
{
case W_KING:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_WKING));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case B_KING:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_BKING));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case W_QUEEN:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_WQUEEN));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case B_QUEEN:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_BQUEEN));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case W_BISHOP:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_WBISHIP));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case B_BISHOP:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_BBISHOP));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case W_KNIGHT:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_WKNIGHT));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case B_KNIGHT:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_BKNIGHT));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case W_PION:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_WPION));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case B_PION:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_BPION));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case W_ROCK:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_WROCK));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
case B_ROCK:
Icon=LoadIcon(TasInst,MAKEINTRESOURCE(TASICON_BROCK));
DrawIcon(hMemDC,40*j+10+4,40*i+10+4,Icon);
break;
}
}
}
SelectObject(hMemDC,GetStockObject(BLACK_BRUSH));
Rectangle(hMemDC,340,10,484,330);
SetBkMode(hMemDC,TRANSPARENT);
if(Soonser==1)
{
wsprintf(TempStr,"악마족 차례");
SetTextColor(hMemDC,RGB(255,255,0));
TextOut(hMemDC,350,20,TempStr,strlen(TempStr));
wsprintf(TempStr,"천사족");
SetTextColor(hMemDC,RGB(255,255,255));
TextOut(hMemDC,350,40,TempStr,strlen(TempStr));
}
else
{
wsprintf(TempStr,"악마족");
SetTextColor(hMemDC,RGB(255,255,255));
TextOut(hMemDC,350,20,TempStr,strlen(TempStr));
wsprintf(TempStr,"천사족 차례");
SetTextColor(hMemDC,RGB(255,255,0));
TextOut(hMemDC,350,40,TempStr,strlen(TempStr));
}
SetTextColor(hMemDC,RGB(168,168,168));
TextOut(hMemDC,350, 80,"안녕하세요..",12);
TextOut(hMemDC,350,100,"korea213(홍석준)입..",16);
TextOut(hMemDC,350,120,"니다.. 도움말을",14);
TextOut(hMemDC,350,140,"꼭~ 참고하세요.",15);
TextOut(hMemDC,350,190,"2003일 5월말을 코앞에 두고",26);
TextOut(hMemDC,350,210,"다가올 여름 방학을",18);
TextOut(hMemDC,350,230,"기둘리며..",10);
BitBlt(hDC,0,0,500,385,hMemDC,0,0,SRCCOPY);
DeleteDC(hMemDC);
DeleteObject(hBmp);
ReleaseDC(hWnd,hDC);
// 메세지처리 //
switch(msg)
{
case WM_LBUTTONDOWN:
Nowmx=LOWORD(lParam);
Nowmy=HIWORD(lParam);
if(Nowmx<10 || Nowmx>330 || Nowmy<10 || Nowmy>330) break;
if(Click==1)
{
if(ChkMove(ClickX, ClickY,(Nowmx-10-((Nowmx-10)%40))/40,(Nowmy-10-((Nowmy-10)%40))/40,
ChessBoard[ClickY][ClickX])==2)
{
Click=0;
break;
}
if(ChkMove(ClickX, ClickY,(Nowmx-10-((Nowmx-10)%40))/40,(Nowmy-10-((Nowmy-10)%40))/40,
ChessBoard[ClickY][ClickX])==0)
{
wsprintf(TempStr,"이동할 수 없습니다.");
MessageBox(hWnd,TempStr,"소식",MB_OK);
Click=0;
break;
}
if(ChessBoard[(Nowmy-10-((Nowmy-10)%40))/40][(Nowmx-10-((Nowmx-10)%40))/40]==B_KING)
{
wsprintf(TempStr,"천사족의 승리!!!");
PlaySound("HELP.WAV",NULL,SND_FILENAME|SND_ASYNC);
MessageBox(hWnd,TempStr,"승리~~~",MB_OK);
goto Next;
}
if(ChessBoard[(Nowmy-10-((Nowmy-10)%40))/40][(Nowmx-10-((Nowmx-10)%40))/40]==W_KING)
{
wsprintf(TempStr,"악마족의 승리!!!");
PlaySound("HELP.WAV",NULL,SND_FILENAME|SND_ASYNC);
MessageBox(hWnd,TempStr,"승리~~~",MB_OK);
goto Next;
}
ChessBoard[ClickY][ClickX]=0;
ClickX=(Nowmx-10-((Nowmx-10)%40))/40;
ClickY=(Nowmy-10-((Nowmy-10)%40))/40;
ChessBoard[ClickY][ClickX]=Temp;
Click=0;
Soonser=1-Soonser;
PlaySound("MOVE.WAV",NULL,SND_FILENAME|SND_ASYNC);
}
else
{
ClickX=(Nowmx-10-((Nowmx-10)%40))/40;
ClickY=(Nowmy-10-((Nowmy-10)%40))/40;
if((Soonser!=0 &&ChessBoard[ClickY][ClickX]>=1 &&
ChessBoard[ClickY][ClickX]<=6) ||
(Soonser!=1 &&ChessBoard[ClickY][ClickX]>=7 &&
ChessBoard[ClickY][ClickX]<=12))
{
MessageBox(hWnd,"당신의 차례가 아닙니다.","흥!!",MB_OK);
break;
}
if(ChessBoard[ClickY][ClickX]==0)break;
Temp=ChessBoard[ClickY][ClickX];
Click=1;
PlaySound("SELECT.WAV",NULL,SND_FILENAME|SND_ASYNC);
}
break;
case WM_COMMAND:
switch(wParam)
{
case TASMENU_NEW:
wsprintf(TempStr,"새 게임을 시작합니다.\nPress 'OK' Button.");
MessageBox(hWnd,TempStr,"START",MB_OK);
Next:
for(ClickY=0;ClickY<8;ClickY++)
for(ClickX=0;ClickX<8;ClickX++) // ClickX와 Y를 쓴 이유는
ChessBoard[ClickY][ClickX]=0; // 변수명을 줄이기 위해서입니다.
for(ClickX=0;ClickX<8;ClickX++) // 이것 역시..
{
ChessBoard[1][ClickX]=B_PION;
ChessBoard[6][ClickX]=W_PION;
}
ChessBoard[0][0]=ChessBoard[0][7]=B_ROCK;
ChessBoard[7][0]=ChessBoard[7][7]=W_ROCK;
ChessBoard[0][1]=ChessBoard[0][6]=B_KNIGHT;
ChessBoard[7][1]=ChessBoard[7][6]=W_KNIGHT;
ChessBoard[0][2]=ChessBoard[0][5]=B_BISHOP;
ChessBoard[7][2]=ChessBoard[7][5]=W_BISHOP;
ChessBoard[0][3]=B_KING;
ChessBoard[0][4]=B_QUEEN;
ChessBoard[7][3]=W_QUEEN;
ChessBoard[7][4]=W_KING;
PlaySound("NEW.WAV",NULL,SND_FILENAME|SND_ASYNC);
break;
case TASMENU_EXIT:
PostQuitMessage(0);
break;
case TASMENU_INFO:
PlaySound("HELP.WAV",NULL,SND_FILENAME|SND_ASYNC);
wsprintf(TempStr,"*** 길 알아보기 ***\n\n");
strcat(TempStr,"폰(졸병) : 오로지 앞으로만 가며, 먹을땐 대각선 앞.\n");
strcat(TempStr,"비숍(성직자) : 대각선으로 가며 뛰어넘을 수 없음.\n");
strcat(TempStr,"나이트(기사) : 직선으로 한칸, 대각으로 한칸.\n");
strcat(TempStr,"록(성벽) : 직선으로 어디든 간다. 뛰어넘을 수 없다.\n");
strcat(TempStr,"퀸(여왕) : 비숍 + 록과 같다. 직선과 대각선.\n");
strcat(TempStr,"킹(왕) : 상하좌우 대각선 1칸씩 갈 수 있다.\n\n");
strcat(TempStr,"== 게임의 목표 : 검은 악마들을 퇴치하라~ -_-; ==\n\n");
strcat(TempStr,"*** 설명 끝이예요. ^^ - korea213(홍석준) -***");
MessageBox(hWnd,TempStr,"HELP",MB_OK);
break;
case TASMENU_HELP:
PlaySound("HELP.WAV",NULL,SND_FILENAME|SND_ASYNC);
wsprintf(TempStr,"안녕하세요?\n\n");
strcat(TempStr,"이 게임의 제작자 홍석준입니다.\n");
strcat(TempStr,"윈도우 API 프로그래밍 공부하면서\n");
strcat(TempStr,"틈틈히 만들어본겁니다.\n\n");
strcat(TempStr,"아직 캐슬링과 변신 등 기타\n");
strcat(TempStr,"복잡한 규칙 적용을 못했습니다.\n");
strcat(TempStr,"하지만 다음버젼 기대해주시고..^^\n");
strcat(TempStr,"재미있게 즐겨주세요. :D\n\n");
strcat(TempStr,"Language : Visual C++ 5.0");
MessageBox(hWnd,TempStr,"HELP",MB_OK);
break;
case TASMENU_MOONJE:
PlaySound("HELP.WAV",NULL,SND_FILENAME|SND_ASYNC);
wsprintf(TempStr,"*** 버젼 0.2의 문제점 리스트 ***\n");
strcat(TempStr,"1. 가장중요!! -> 컴퓨터와 대결이 안된다 -_-;\n");
strcat(TempStr," 오로지 사람과 1:1이거나\n");
strcat(TempStr," 혼자서만 할 수 있다.-_-\n\n");
strcat(TempStr,"2. 캐슬링 규칙이 안된다.\n");
strcat(TempStr," -> 킹과 록의 위치를 그 사이로 바꿔주는\n");
strcat(TempStr," 캐슬링의 규칙을 활용할 수 없다.\n\n");
strcat(TempStr,"3. 변신이 안된다!!\n");
strcat(TempStr," -> 폰이 상대방진영 끝으로 갔을때 \n");
strcat(TempStr," 현재 죽어있는것들과 바꿀수 없다.\n\n");
strcat(TempStr,"*** 끝이랍니다. 버그문의는 하이텔 : 태사다 ***\n");
MessageBox(hWnd,TempStr,"HELP",MB_OK);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
// 여기까지 메세지처리 //
return 1;
}
#endif
3. chkmove.cpp
/* Check Move
이동가능 체크여부 함수
이동 가능 체크는 노가다로 했으며 -_-;
이동 가능할경우 1을, 아닐경우 2를,
제자리일경우 2를 리턴합니다.
-SJ,Hong 홍 석준-
*/
#ifndef __CHKmOVE__
#define __CHKmOVE__
#include "start.h"
#define abs(a) ((a<0) ? a*(-1) : a)
int ChkMove(int sx, int sy, int ex, int ey, int unit)
{
int i,j;
switch(unit)
{
case W_PION:
if(sx==ex && sy==ey) return 2;
if(sy<ey) return 0;
if(sx>ex)if(sx-ex>=2) return 0;
if(sx<ex)if(ex-sx>=2) return 0;
if(sy-ey>2) return 0;
if(sx!=ex && ((sy-ey)!=1 || ChessBoard[ey][ex]==0)) return 0;
if((sy-ey)>=2 && (sy!=6)) return 0;
if(sx==ex && ChessBoard[ey][ex]!=0) return 0;
if(sx!=ex && (ChessBoard[ey][ex]>=1 && ChessBoard[ey][ex]<=6)) return 0;
break;
case B_PION:
if(sx==ex && sy==ey) return 2;
if(sy>ey) return 0;
if(sx>ex)if(sx-ex>=2) return 0;
if(sx<ex)if(ex-sx>=2) return 0;
if(ey-sy>2) return 0;
if(sx!=ex && ((ey-sy)!=1 || ChessBoard[ey][ex]==0)) return 0;
if((ey-sy)>=2 && (sy!=1)) return 0;
if(sx==ex && ChessBoard[ey][ex]!=0) return 0;
if(sx!=ex && (ChessBoard[ey][ex]>=7 && ChessBoard[ey][ex]<=12)) return 0;
break;
case B_ROCK:
case W_ROCK:
if(sx==ex && sy==ey) return 2;
if(sx!=ex && sy!=ey) return 0;
if(unit==W_ROCK)
{
if(ChessBoard[ey][ex]>=1 &&
ChessBoard[ey][ex]<=6) return 0;
}
else
{
if(ChessBoard[ey][ex]>=7 &&
ChessBoard[ey][ex]<=12) return 0;
}
if(sx>ex) // 왼쪽으로 갔을때
for(i=sx;i>ex;i--)
if(ChessBoard[sy][i]!=0 && i!=sx && i!=ex) return 0;
if(sx<ex) // 오른쪽으로 갔을때
for(i=sx;i<ex;i++)
if(ChessBoard[sy][i]!=0 && i!=sx && i!=ex) return 0;
if(sy>ey) // 위쪽으로 갔을때
for(i=sy;i>ey;i--)
if(ChessBoard[i][sx]!=0 && i!=sy && i!=ey) return 0;
if(sy<ey) // 아래쪽으로 갔을때
for(i=sy;i<ey;i++)
if(ChessBoard[i][sx]!=0 && i!=sy && i!=ey) return 0;
break;
case W_KNIGHT:
case B_KNIGHT:
if(sx==ex && sy==ey) return 2;
if(unit==W_KNIGHT)
{
if(ChessBoard[ey][ex]>=1 &&
ChessBoard[ey][ex]<=6) return 0;
}
else
{
if(ChessBoard[ey][ex]>=7 &&
ChessBoard[ey][ex]<=12) return 0;
}
if(sx>ex)if(sx-ex>2) return 0;
else if(ex-sx>2) return 0;
if(sy>ey)if(sy-ey>2) return 0;
else if(ey-sy>2) return 0;
if(sx>ex)j=sx-ex;
else j=ex-sx;
if(sy>ey)i=sy-ey;
else i=ey-sy;
if(j+i!=3) return 0;
break;
case W_BISHOP:
case B_BISHOP:
if(sx==ex && sy==ey) return 2;
if(sx>ex)j=sx-ex;
else j=ex-sx;
if(sy>ey)i=sy-ey;
else i=ey-sy;
if(i!=j) return 0;
if(unit==W_BISHOP)
{
if(ChessBoard[ey][ex]>=1 &&
ChessBoard[ey][ex]<=6) return 0;
}
else
{
if(ChessBoard[ey][ex]>=7 &&
ChessBoard[ey][ex]<=12) return 0;
}
if(sx>ex) // 왼쪽
{
if(sy>ey) // 위
{
j=sx;
for(i=sy;i>ey;i--)
{
if(ChessBoard[i][j--]!=0 && i!=sy && i!=ey) return 0;
}
}
else // 아래
{
j=sx;
for(i=sy;i<ey;i++)
{
if(ChessBoard[i][j--]!=0 && i!=sy && i!=ey) return 0;
}
}
}
else // 오른쪽
{
if(sy>ey) // 위
{
j=sx;
for(i=sy;i>ey;i--)
{
if(ChessBoard[i][j++]!=0 && i!=sy && i!=ey) return 0;
}
}
else // 아래
{
j=sx;
for(i=sy;i<ey;i++)
{
if(ChessBoard[i][j++]!=0 && i!=sy && i!=ey) return 0;
}
}
}
break;
case W_QUEEN:
case B_QUEEN:
if(sx==ex && sy==ey) return 2;
if(unit==W_QUEEN)
{
if(ChessBoard[ey][ex]>=1 &&
ChessBoard[ey][ex]<=6) return 0;
}
else
{
if(ChessBoard[ey][ex]>=7 &&
ChessBoard[ey][ex]<=12) return 0;
}
if(sx>ex)j=sx-ex;
else j=ex-sx;
if(sy>ey)i=sy-ey;
else i=ey-sy;
if((sx!=ex && sy!=ey) && i!=j) return 0;
// 직선이동이 아닐경우 대각선이 아니면 못간다.
if(sx>ex && sy==ey) // 왼쪽으로 갔을때
for(i=sx;i>ex;i--)
if(ChessBoard[sy][i]!=0 && i!=sx && i!=ex) return 0;
if(sx<ex && sy==ey) // 오른쪽으로 갔을때
for(i=sx;i<ex;i++)
if(ChessBoard[sy][i]!=0 && i!=sx && i!=ex) return 0;
if(sy>ey && sx==ex) // 위쪽으로 갔을때
for(i=sy;i>ey;i--)
if(ChessBoard[i][sx]!=0 && i!=sy && i!=ey) return 0;
if(sy<ey && sx==ex) // 아래쪽으로 갔을때
for(i=sy;i<ey;i++)
if(ChessBoard[i][sx]!=0 && i!=sy && i!=ey) return 0;
if(sx>ex && sy>ey) // 왼쪽 위
{
j=sx;
for(i=sy;i>ey;i--)
{
if(ChessBoard[i][j--]!=0 && i!=sy && i!=ey) return 0;
}
}
if(sx>ex && sy<ey) // 왼쪽 아래
{
j=sx;
for(i=sy;i<ey;i++)
{
if(ChessBoard[i][j--]!=0 && i!=sy && i!=ey) return 0;
}
}
if(sx<ex && sy>ey) // 오른쪽 위
{
j=sx;
for(i=sy;i>ey;i--)
{
if(ChessBoard[i][j++]!=0 && i!=sy && i!=ey) return 0;
}
}
if(sx<ex && sy<ey) // 오른쪽 아래
{
j=sx;
for(i=sy;i<ey;i++)
{
if(ChessBoard[i][j++]!=0 && i!=sy && i!=ey) return 0;
}
}
break;
case W_KING:
case B_KING:
if(sx==ex && sy==ey) return 2;
if(unit==W_KING)
{
if(ChessBoard[ey][ex]>=1 &&
ChessBoard[ey][ex]<=6) return 0;
}
else
{
if(ChessBoard[ey][ex]>=7 &&
ChessBoard[ey][ex]<=12) return 0;
}
if(sx>ex)j=sx-ex;
else j=ex-sx;
if(sy>ey)i=sy-ey;
else i=ey-sy;
if(i>=2 || j>=2) return 0;
break;
}
return 1;
}
#endif