반응형
// WinStudy_20200407_4.cpp : 애플리케이션에 대한 진입점을 정의합니다.
//
#include "framework.h"
#include "WinStudy_20200407.h"
#define MAX_LOADSTRING 100
// 전역 변수:
HINSTANCE hInst; // 현재 인스턴스입니다.
WCHAR szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트입니다.
WCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.
// 이 코드 모듈에 포함된 함수의 선언을 전달합니다:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 여기에 코드를 입력합니다.
// 전역 문자열을 초기화합니다.
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINSTUDY20200407, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 애플리케이션 초기화를 수행합니다:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINSTUDY20200407));
MSG msg;
// 기본 메시지 루프입니다:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
//
// 함수: MyRegisterClass()
//
// 용도: 창 클래스를 등록합니다.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINSTUDY20200407));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(70, 140, 255)); //(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINSTUDY20200407);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
class Stone
{
public:
int Type = 0;//0이면 빈자리 1이면 흑돌 2이면 백돌
int XX = 0;
int YY = 0;
};
Stone S_List[18][18];
HBRUSH Pan = NULL;
HPEN Line = NULL;
HBRUSH White = NULL;
HBRUSH Black = NULL;
HFONT MyFont = NULL;
int sx = 0, sy = 0;
int count = 0;
int b = 0, w = 0;
bool BlackTurn = false;
bool GameOver = false;
int BlackWin = 0;
int WiteWin = 0;
void InitGame()
{
Pan = (HBRUSH)CreateSolidBrush(RGB(220, 179, 92));
Line = (HPEN)CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
White = (HBRUSH)CreateSolidBrush(RGB(255, 255, 255));
Black = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
MyFont = CreateFont(30, 0, 0, 0, 0, 0, 0, 0, HANGEUL_CHARSET,
0, 0, 0, VARIABLE_PITCH | FF_ROMAN, _T("굴림"));
for (int i = 0; i < 19; i++)//초기화
{
for (int j = 0; j < 19; j++)
{
S_List[i][j].Type = 0;
S_List[i][j].XX = 80 + i * 40;
S_List[i][j].YY = 80 + j * 40;
}
}
}
void EndGame()
{
if (Pan != NULL)
{
DeleteObject(Pan);
Pan = NULL;
}
if (Line != NULL)
{
DeleteObject(Line);
Line = NULL;
}
if (White != NULL)
{
DeleteObject(White);
White = NULL;
}
if (Black != NULL)
{
DeleteObject(Black);
Black = NULL;
}
if (MyFont != NULL)
{
DeleteObject(MyFont);
MyFont = NULL;
}
}
void Win()
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
//흑돌 가로
if (S_List[i][j].Type == 1 &&
S_List[i + 1][j].Type == 1 &&
S_List[i + 2][j].Type == 1 &&
S_List[i + 3][j].Type == 1 &&
S_List[i + 4][j].Type == 1)
{
GameOver = true;
}
//백돌 가로
if (S_List[i][j].Type == 2 &&
S_List[i + 1][j].Type == 2 &&
S_List[i + 2][j].Type == 2 &&
S_List[i + 3][j].Type == 2 &&
S_List[i + 4][j].Type == 2)
{
GameOver = true;
}
//흑돌 세로
if (S_List[i][j].Type == 1 &&
S_List[i][j + 1].Type == 1 &&
S_List[i][j + 2].Type == 1 &&
S_List[i][j + 3].Type == 1 &&
S_List[i][j + 4].Type == 1)
{
GameOver = true;
}
//백돌 세로
if (S_List[i][j].Type == 2 &&
S_List[i][j + 1].Type == 2 &&
S_List[i][j + 2].Type == 2 &&
S_List[i][j + 3].Type == 2 &&
S_List[i][j + 4].Type == 2)
{
GameOver = true;
}
//흑돌 왼->오 대각선
if (S_List[i][j].Type == 1 &&
S_List[i + 1][j + 1].Type == 1 &&
S_List[i + 2][j + 2].Type == 1 &&
S_List[i + 3][j + 3].Type == 1 &&
S_List[i + 4][j + 4].Type == 1)
{
GameOver = true;
}
//백돌 왼->오 대각선
if (S_List[i][j].Type == 1 &&
S_List[i + 1][j + 1].Type == 1 &&
S_List[i + 2][j + 2].Type == 1 &&
S_List[i + 3][j + 3].Type == 1 &&
S_List[i + 4][j + 4].Type == 1)
{
GameOver = true;
}
//흑돌 오->왼 대각선
if (S_List[i + 4][j].Type == 1 &&
S_List[i + 3][j + 1].Type == 1 &&
S_List[i + 2][j + 2].Type == 1 &&
S_List[i + 1][j + 3].Type == 1 &&
S_List[i][j + 4].Type == 1)
{
GameOver = true;
}
//백돌 오->왼 대각선
if (S_List[i + 4][j].Type == 1 &&
S_List[i + 3][j + 1].Type == 1 &&
S_List[i + 2][j + 2].Type == 1 &&
S_List[i + 1][j + 3].Type == 1 &&
S_List[i][j + 4].Type == 1)
{
GameOver = true;
}
}
}
}
void Clear()
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
S_List[i][j].Type = 0;
}
}
}
//
// 함수: InitInstance(HINSTANCE, int)
//
// 용도: 인스턴스 핸들을 저장하고 주 창을 만듭니다.
//
// 주석:
//
// 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고
// 주 프로그램 창을 만든 다음 표시합니다.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
100, 100, 900, 900, nullptr, nullptr, hInstance, nullptr);
(윈도우 크기)
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 용도: 주 창의 메시지를 처리합니다.
//
// WM_COMMAND - 애플리케이션 메뉴를 처리합니다.
// WM_PAINT - 주 창을 그립니다.
// WM_DESTROY - 종료 메시지를 게시하고 반환합니다.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
InitGame();
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 메뉴 선택을 구문 분석합니다:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_LBUTTONDOWN:
{
sx = LOWORD(lParam);
sy = HIWORD(lParam); //마우스 왼쪽 버튼 클릭시 마우스 좌표를 얻어오는 방법
if (sx > 30 && sx < 30 + 19 * 40)//게임판 안을 클릭했을때만 발생
{
if (sy > 30 && sy < 30 + 19 * 40)
{
for (int i = 0; i < 19; i++)
{
int X = (sx - 50) / 40; //첫번째 선의 위치 = 50, 선마다 간격 = 40
int Y = (sy - 50) / 40;
if (S_List[X][Y].Type == 0)
{
if (BlackTurn == true)
S_List[X][Y].Type = 1;
else
S_List[X][Y].Type = 2;
}
}
}
}
InvalidateRect(hWnd, NULL, TRUE);//강제로 WM_PAINT 메시지를 발생시켜주는 함수
count++;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다...
HPEN OldPen = (HPEN)SelectObject(hdc, Line);
HBRUSH OldBrush = (HBRUSH)SelectObject(hdc, Pan);
HFONT OldFont = (HFONT)SelectObject(hdc, MyFont);
SelectObject(hdc, OldPen);
Rectangle(hdc, 50, 50, 50 + 740, 50 + 740);//판그리기
SelectObject(hdc, OldBrush);
RECT Rect;
GetClientRect(hWnd, &Rect);
OldPen = (HPEN)SelectObject(hdc, Line);
//가로줄
for (int i = 40; i < 750; i = i + 40)
{
MoveToEx(hdc, 40 + 40, 40 + i, NULL);
LineTo(hdc, 40 + 750 - 30, 40 + i);
}
//세로줄
for (int i = 40; i < 750; i = i + 40)
{
MoveToEx(hdc, 40 + i, 40 + 40, NULL);
LineTo(hdc, 40 + i, 40 + 750 - 30);
}
SetBkMode(hdc, TRANSPARENT); //<--글씨 배경을 빼는 방법
TCHAR a_TempStr[128];
if (BlackTurn == false)
{
SetTextColor(hdc, RGB(0, 0, 0)); //<--글씨색 바꾸기
_stprintf_s(a_TempStr, _T("흑돌차례입니다."));
TextOut(hdc, 50, 5, a_TempStr, _tcslen(a_TempStr));
}
else
{
SetTextColor(hdc, RGB(255, 255, 255)); //<--글씨색 바꾸기
_stprintf_s(a_TempStr, _T("백돌차례입니다."));
TextOut(hdc, 50, 5, a_TempStr, _tcslen(a_TempStr));
}
//점수판
TCHAR Score[128];
SetTextColor(hdc, RGB(255, 255, 0)); //<--글씨색 바꾸기
_stprintf_s(Score, _T("흑돌(%d : %d)백돌"), BlackWin, WiteWin);
TextOut(hdc, 400, 5, Score, _tcslen(Score));
SelectObject(hdc, OldPen);
SelectObject(hdc, OldFont);
if (count % 2 == 1)
BlackTurn = false;
else
BlackTurn = true;
//돌그리기
if (count >= 1)
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (S_List[i][j].Type <= 0)
continue;
else if (S_List[i][j].Type == 1)//흑돌
SelectObject(hdc, Black);
else if (S_List[i][j].Type == 2)//백돌
SelectObject(hdc, White);
Ellipse(hdc, S_List[i][j].XX - 15, S_List[i][j].YY - 15, S_List[i][j].XX + 15, S_List[i][j].YY + 15);
}
}
}
Win();//승리체크
if (GameOver == true)
{
if (BlackTurn == true)
{
TCHAR winner[15];
_stprintf_s(winner, _T("백돌이 승리하였습니다."));
MessageBoxW(hWnd, winner, _T("승리"), MB_OK);
WiteWin++;
}
else
{
TCHAR winner[15];
_stprintf_s(winner, _T("흑돌이 승리하였습니다."));
MessageBoxW(hWnd, winner, _T("승리"), MB_OK);
BlackWin++;
}
GameOver = false;
Clear();
InvalidateRect(hWnd, NULL, TRUE);//강제로 WM_PAINT 메시지를 발생시켜주는 함수
count++;
}
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
EndGame();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// 정보 대화 상자의 메시지 처리기입니다.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
반응형
'WinAPI' 카테고리의 다른 글
[Win API] bmp파일로드 + 움직이기(드래그) (0) | 2020.04.09 |
---|