void TicTacToeGame::PlayGame(int index, HWND hWnd, HDC hdc) { if (index != -1) { RECT rc; if ((arrayGameBoard[index] == 0) && GetCellRect(hWnd, index, &rc)) { //FillRect(hdc, &rc, (intPlayerTurn == 1) ? hbPlayerOne : hbPlayerTwo); DrawIconCentered(hdc, &rc, (intPlayerTurn == 1) ? hiPlayerOne : hiPlayerTwo); arrayGameBoard[index] = intPlayerTurn; winner = GetWinner(wins); if (winner == 1 || winner == 2) { ShowWinner(hWnd, hdc); MessageBox(hWnd, (winner == 1) ? L"Player 1 is the winner" : L"Player 2 is the winner", L"You Win", MB_OK | MB_ICONINFORMATION); intPlayerTurn = 0; } else if (winner == 3) { MessageBox(hWnd, L"it's a draw", L"Draw", MB_OK | MB_ICONINFORMATION); intPlayerTurn = 0; } else { intPlayerTurn = (intPlayerTurn == 1) ? 2 : 1; } ShowTurn(hWnd, hdc); } } }
BOOL TicTacToeGame::StartNewGame(HWND hWnd) { int id = MessageBox(hWnd, L"Are you sure to start new game?", L"New Game?", MB_YESNO); if (id == IDYES) { intPlayerTurn = winner == 3 ? 1 : winner; ZeroMemory(arrayGameBoard, sizeof(arrayGameBoard)); ZeroMemory(wins, sizeof(wins)); winner = 0; ShowTurn(hWnd, GetDC(hWnd)); InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); return TRUE; } return FALSE; }
void TicTacToeGame::DrawGame(HDC hdc, RECT rc, HWND hWnd) { for (int i = 0; i < 4; i++) { DrawLine(hdc, rc.left + TicTacToeGame::CELL_SIZE * i, rc.top, rc.left + TicTacToeGame::CELL_SIZE * i, rc.bottom); DrawLine(hdc, rc.left, rc.top + TicTacToeGame::CELL_SIZE * i, rc.right, rc.top + TicTacToeGame::CELL_SIZE * i); } RECT rcCell; for (int i = 0; i < ARRAYSIZE(arrayGameBoard); i++) { if ((arrayGameBoard[i] != 0) && GetCellRect(hWnd, i, &rcCell)) { DrawIconCentered(hdc, &rcCell, (arrayGameBoard[i] == 1) ? hiPlayerOne : hiPlayerTwo); } } if (winner != 0 && winner != 3) { ShowWinner(hWnd, hdc); } ShowTurn(hWnd, hdc); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { hbr1 = CreateSolidBrush(RGB(255, 0, 0)); hbr2 = CreateSolidBrush(RGB(0, 0, 255)); hIcon1 = LoadIcon(hInst, MAKEINTRESOURCE(ID_PLAYER1)); hIcon2 = LoadIcon(hInst, MAKEINTRESOURCE(ID_PLAYER2)); } break; case WM_COMMAND: { int wmId = LOWORD(wParam); // Parse the menu selections: switch (wmId) { case ID_FILE_NEWGAME: { int ret = MessageBox(hWnd, L"Are you sure you want to start a new game?", L"New Game", MB_YESNO | MB_ICONQUESTION); if (IDYES == ret) { //Reset and start a new game playerTurn = 1; winner = 0; ZeroMemory(gameBoard, sizeof(gameBoard)); InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); } } break; 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: { int xPos = GET_X_LPARAM(lParam); int yPos = GET_Y_LPARAM(lParam); if (0 == playerTurn) break; int index = GetCellNumberFromPoint(hWnd, xPos, yPos); HDC hdc = GetDC(hWnd); if (NULL != hdc) { // WCHAR temp[100]; //wsprintf(temp, L"Index = %d", index); // TextOut(hdc, xPos, yPos, temp, lstrlen(temp)); if (index != -1) { RECT rcCell; if ((0 == gameBoard[index]) && GetCellRect(hWnd, index, &rcCell)) { gameBoard[index] = playerTurn; //FillRect(hdc, &rcCell, (playerTurn==1) ? hbr1 : hbr2); DrawIconCentered(hdc, &rcCell, (playerTurn == 1) ? hIcon1 : hIcon2); winner = GetWinner(wins); if (winner == 1 || winner == 2) { MessageBox(hWnd, (winner == 1) ? L"Player 1 wins" : L"Player 2 wins", L"You win!",MB_OK | MB_ICONINFORMATION); playerTurn = 0; } else if (3==winner) { MessageBox(hWnd, L"No one wins!", L"It's a draw", MB_OK | MB_ICONEXCLAMATION); playerTurn = 0; } else if (winner == 0) { playerTurn = (playerTurn == 1) ? 2 : 1; } ShowTurn(hWnd, hdc); } } ReleaseDC(hWnd, hdc); } } break; case WM_GETMINMAXINFO: { MINMAXINFO * pMinMax = (MINMAXINFO*)lParam; pMinMax->ptMinTrackSize.x = CELL_SIZE * 5; pMinMax->ptMinTrackSize.y = CELL_SIZE * 5; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); RECT rc; if (GetGameBoardRect(hWnd, &rc)) { RECT rcClient; if (GetClientRect(hWnd, &rcClient)) { const WCHAR szPlayer1 [] = L"Player 1"; const WCHAR szPlayer2 []= L"Player 2"; SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(255, 255, 0)); TextOut(hdc, 16, 16, szPlayer1, 8); SetTextColor(hdc, RGB(0, 0, 255)); TextOut(hdc, rcClient.right-72, 16, szPlayer2, 8); ShowTurn(hWnd, hdc); } FillRect(hdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); //Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } for (int i = 0; i < 4; i++) { DrawLine(hdc, rc.left+CELL_SIZE*i , rc.top, rc.left + CELL_SIZE*i, rc.bottom); DrawLine(hdc, rc.left, rc.top + CELL_SIZE*i, rc.right, rc.top+CELL_SIZE*i); } RECT rcCell; for (int i = 0; i < 9; i++) { if ((0!=gameBoard[i]) && GetCellRect(hWnd, i, &rcCell)) { //FillRect(hdc, &rcCell, (gameBoard[i]==2) ? hbr2 : hbr1); DrawIconCentered(hdc, &rcCell, (gameBoard[i] == 1) ? hIcon1 : hIcon2); } } EndPaint(hWnd, &ps); } break; case WM_DESTROY: DeleteObject(hbr1); DeleteObject(hbr2); DestroyIcon(hIcon1); DestroyIcon(hIcon2); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { hBrushP1 = CreateSolidBrush(colorPlayer1Bg); hBrushP2 = CreateSolidBrush(colorPlayer2Bg); hBrushPWin = CreateSolidBrush(RGB(200, 200, 0)); // neutral Yellow hIconP1 = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_P1), IMAGE_ICON, SIGN_SIZE, SIGN_SIZE, LR_DEFAULTCOLOR); hIconP2 = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_P2), IMAGE_ICON, SIGN_SIZE, SIGN_SIZE, LR_DEFAULTCOLOR); } break; case WM_COMMAND: { int wmId = LOWORD(wParam); // Parse the menu selections: switch (wmId) { case ID_FILE_NEWGAME: { if (IDYES == MessageBox(hWnd, L"Are you sure you want to start a new game?", L"New Game", MB_YESNO | MB_ICONQUESTION)) { // Reset and start new game; playerTurn = 1; winner = 0; std::fill(gameBoard, std::end(gameBoard), 0); // Force rePaint message InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); } } break; 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_GETMINMAXINFO: { MINMAXINFO *pMinMax = (MINMAXINFO*)lParam; pMinMax->ptMinTrackSize.x = CELL_SIZE * 4 - 25; pMinMax->ptMinTrackSize.y = CELL_SIZE * 4; } break; case WM_LBUTTONDOWN: { int xPos = GET_X_LPARAM(lParam); int yPos = GET_Y_LPARAM(lParam); if (playerTurn <= 0) break; int index = GetCellNumberFromPoint(hWnd, xPos, yPos); if (HDC hdc = GetDC(hWnd)) { //WCHAR temp[20]; //wsprintf(temp, L"Index = %d", index); //TextOut(hdc, xPos, yPos, temp, lstrlen(temp)); //Get cell dimension from Index if (index != -1) { RECT rcCell; if (!gameBoard[index] && GetCellRect(hWnd, index, &rcCell)) { gameBoard[index] = playerTurn; // set gameBoard status // draw gameBoard cells FillRect(hdc, &rcCell, playerTurn == 1 ? hBrushP1 : hBrushP2); DrawIconEx(hdc, rcCell.left + (CELL_SIZE - SIGN_SIZE)/2, rcCell.top + (CELL_SIZE - SIGN_SIZE) / 2, playerTurn == 1 ? hIconP1 : hIconP2, SIGN_SIZE, SIGN_SIZE, 0, nullptr, DI_NORMAL); winner = GetWinner(wins); // check for game winner if (winner > 0) { //We have a winner!!! ShowTurn(hWnd, hdc); // Display turn for (int winIndex : wins) { // draw winning gameBoard cells GetCellRect(hWnd, winIndex, &rcCell); FillRect(hdc, &rcCell, hBrushPWin); DrawIconEx(hdc, rcCell.left + (CELL_SIZE - SIGN_SIZE) / 2, rcCell.top + (CELL_SIZE - SIGN_SIZE) / 2, playerTurn == 1 ? hIconP1 : hIconP2, SIGN_SIZE, SIGN_SIZE, 0, nullptr, DI_NORMAL); } MessageBox( hWnd, winner == 1 ? L"Player 1 is the Winner!!!" : L"Player 2 is the Winner!!!", L"!!!Win!!!", MB_OK | MB_ICONINFORMATION); playerTurn = 0; } else if (winner == -1) { // It's a Tie!!! ShowTurn(hWnd, hdc); // Display turn MessageBox( hWnd, L"It's a Tie!!!", L"!!!Tie!!!", MB_OK | MB_ICONEXCLAMATION); playerTurn = 0; } else { playerTurn = playerTurn == 1 ? 2 : 1; ShowTurn(hWnd, hdc); // Display turn } } } ReleaseDC(hWnd, hdc); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); RECT rcClient; if (GetClientRect(hWnd, &rcClient)) { // Draw Player 1 and Player 2 text static const WCHAR player1Text[] = L"Player 1"; static const WCHAR player2Text[] = L"Player 2"; SetBkMode(hdc, TRANSPARENT); // transparent text background SetTextColor(hdc, colorPlayer1Text); // set text color to red for Player 1 TextOut(hdc, 16, 16, player1Text, std::size(player1Text)); SetTextColor(hdc, colorPlayer2Text); // set text color to blue for Player 2 TextOut(hdc, rcClient.right - 80, 16, player2Text, std::size(player2Text)); ShowTurn(hWnd, hdc); } RECT rc; if (GetGameBoardRect(hWnd, &rc)) { // Draw game board FillRect(hdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); for (unsigned int i = 0; i < 4; ++i) { // Draw vertical lines DrawLine(hdc, rc.left + CELL_SIZE * i, rc.top, rc.left + CELL_SIZE * i, rc.bottom); // Draw horizontal lines DrawLine(hdc, rc.left, rc.top + CELL_SIZE * i, rc.right, rc.top + CELL_SIZE * i); } RECT rcCell; for (unsigned int i = 0; i < std::size(gameBoard); ++i) // redraw gameBoard cells { if (gameBoard[i] && GetCellRect(hWnd, i, &rcCell)) { FillRect(hdc, &rcCell, gameBoard[i] == 1 ? hBrushP1 : hBrushP2); DrawIconEx(hdc, rcCell.left + (CELL_SIZE - SIGN_SIZE) / 2, rcCell.top + (CELL_SIZE - SIGN_SIZE) / 2, gameBoard[i] == 1 ? hIconP1 : hIconP2, SIGN_SIZE, SIGN_SIZE, 0, nullptr, DI_NORMAL); } } if (winner > 0) // redraw winning gameBoard cells { for (int winIndex : wins) { GetCellRect(hWnd, winIndex, &rcCell); FillRect(hdc, &rcCell, hBrushPWin); DrawIconEx(hdc, rcCell.left + (CELL_SIZE - SIGN_SIZE) / 2, rcCell.top + (CELL_SIZE - SIGN_SIZE) / 2, winner == 1 ? hIconP1 : hIconP2, SIGN_SIZE, SIGN_SIZE, 0, nullptr, DI_NORMAL); } } } EndPaint(hWnd, &ps); } break; case WM_DESTROY: DeleteObject(hBrushP1); DeleteObject(hBrushP2); //DeleteObject(hBrushPWin); DeleteObject(hIconP1); DeleteObject(hIconP1); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }