Advertisement
alien_fx_fiend

GPT4o Improved Features Implentation (WORK WITH THIS !)

Jul 23rd, 2024
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.63 KB | None | 0 0
  1. #include <windows.h>
  2. #include <vector>
  3. #include <cmath>
  4. #include <ctime>
  5.  
  6. #define ID_TIMER 1
  7. #define BALL_RADIUS 10
  8. #define TABLE_WIDTH 800
  9. #define TABLE_HEIGHT 400
  10.  
  11. HINSTANCE hInst;
  12. HWND hwnd;
  13. HDC hdcMem, hdcBall;
  14. HBITMAP hbmMem, hbmOld;
  15. HPEN hPen;
  16. HBRUSH hBrush;
  17. RECT table = { 50, 50, 850, 450 };
  18. POINT cueStart, cueEnd;
  19. bool isDragging = false;
  20. float power = 0.0f;
  21. bool isCueBallFreeMove = false;
  22.  
  23. struct Ball {
  24.     float x, y;
  25.     float vx, vy;
  26.     COLORREF color;
  27.     bool isPocketed;
  28.     bool isStriped;
  29. };
  30.  
  31. std::vector<Ball> balls;
  32. Ball cueBall;
  33. bool playerTurn = true;
  34. bool gameOver = false;
  35. bool isSolids = false;
  36. bool player1Solids = false;
  37. bool firstShot = true;
  38.  
  39. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  40. void InitBalls();
  41. void DrawTable(HDC);
  42. void DrawBalls(HDC);
  43. void DrawCue(HDC);
  44. void DrawPowerMeter(HDC);
  45. void UpdateBalls();
  46. void CheckCollisions();
  47. void CheckPockets();
  48. void AIMove();
  49. void ApplyEnglish(Ball&, float, float);
  50. bool CheckGameOver();
  51. void CheckFoul(Ball&);
  52. void PocketBall(Ball&);
  53. void DrawPockets(HDC);
  54. void DrawPlayerTurn(HDC);
  55.  
  56. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow) {
  57.     hInst = hInstance;
  58.     WNDCLASS wc = {};
  59.     wc.lpfnWndProc = WndProc;
  60.     wc.hInstance = hInstance;
  61.     wc.lpszClassName = L"8BallPool";
  62.     RegisterClass(&wc);
  63.  
  64.     hwnd = CreateWindowEx(0, L"8BallPool", L"8-Ball Pool", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 900, 600, nullptr, nullptr, hInstance, nullptr);
  65.     ShowWindow(hwnd, nCmdShow);
  66.  
  67.     MSG msg = {};
  68.     while (GetMessage(&msg, nullptr, 0, 0)) {
  69.         TranslateMessage(&msg);
  70.         DispatchMessage(&msg);
  71.     }
  72.     return (int)msg.wParam;
  73. }
  74.  
  75. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  76.     switch (message) {
  77.     case WM_CREATE:
  78.         srand((unsigned int)time(NULL));
  79.         InitBalls();
  80.         SetTimer(hwnd, ID_TIMER, 16, NULL);
  81.         break;
  82.     case WM_PAINT: {
  83.         PAINTSTRUCT ps;
  84.         HDC hdc = BeginPaint(hwnd, &ps);
  85.         if (!hdcMem) {
  86.             hdcMem = CreateCompatibleDC(hdc);
  87.             hbmMem = CreateCompatibleBitmap(hdc, 900, 600);
  88.             hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
  89.         }
  90.         FillRect(hdcMem, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
  91.         DrawTable(hdcMem);
  92.         DrawBalls(hdcMem);
  93.         DrawPockets(hdcMem);
  94.         DrawPlayerTurn(hdcMem);
  95.         if (!gameOver && playerTurn && !isCueBallFreeMove) {
  96.             DrawCue(hdcMem);
  97.             DrawPowerMeter(hdcMem);
  98.         }
  99.         BitBlt(hdc, 0, 0, 900, 600, hdcMem, 0, 0, SRCCOPY);
  100.         EndPaint(hwnd, &ps);
  101.         break;
  102.     }
  103.     case WM_LBUTTONDOWN:
  104.         if (gameOver) break;
  105.         if (isCueBallFreeMove) {
  106.             cueBall.x = LOWORD(lParam);
  107.             cueBall.y = HIWORD(lParam);
  108.             isCueBallFreeMove = false;
  109.             InvalidateRect(hwnd, NULL, FALSE);
  110.         } else if (playerTurn) {
  111.             cueStart.x = LOWORD(lParam);
  112.             cueStart.y = HIWORD(lParam);
  113.             isDragging = true;
  114.         }
  115.         break;
  116.     case WM_MOUSEMOVE:
  117.         if (isDragging) {
  118.             cueEnd.x = LOWORD(lParam);
  119.             cueEnd.y = HIWORD(lParam);
  120.             power = min(sqrt(pow(cueEnd.x - cueStart.x, 2) + pow(cueEnd.y - cueStart.y, 2)) / 100.0f, 1.0f);
  121.             InvalidateRect(hwnd, NULL, FALSE);
  122.         }
  123.         break;
  124.     case WM_LBUTTONUP:
  125.         if (isDragging) {
  126.             isDragging = false;
  127.             float dx = cueEnd.x - cueStart.x;
  128.             float dy = cueEnd.y - cueStart.y;
  129.             cueBall.vx = dx * power * 0.5f;
  130.             cueBall.vy = dy * power * 0.5f;
  131.             ApplyEnglish(cueBall, dx * power * 0.1f, dy * power * 0.1f);
  132.             playerTurn = false;
  133.             InvalidateRect(hwnd, NULL, FALSE);
  134.         }
  135.         break;
  136.     case WM_TIMER:
  137.         if (!gameOver) {
  138.             UpdateBalls();
  139.             CheckCollisions();
  140.             CheckPockets();
  141.             if (!playerTurn) AIMove();
  142.             if (CheckGameOver()) {
  143.                 gameOver = true;
  144.                 MessageBox(hwnd, L"Game Over! All balls are pocketed.", L"Game Over", MB_OK);
  145.             }
  146.             InvalidateRect(hwnd, NULL, FALSE);
  147.         }
  148.         break;
  149.     case WM_DESTROY:
  150.         KillTimer(hwnd, ID_TIMER);
  151.         SelectObject(hdcMem, hbmOld);
  152.         DeleteObject(hbmMem);
  153.         DeleteDC(hdcMem);
  154.         PostQuitMessage(0);
  155.         break;
  156.     default:
  157.         return DefWindowProc(hwnd, message, wParam, lParam);
  158.     }
  159.     return 0;
  160. }
  161.  
  162. void InitBalls() {
  163.     balls.clear();
  164.     cueBall = { 250.0f, 250.0f, 0.0f, 0.0f, RGB(255, 255, 255), false, false };
  165.     balls.push_back(cueBall);
  166.  
  167.     // Triangular rack setup
  168.     int colors[] = { RGB(255, 255, 0), RGB(255, 0, 0) };
  169.     bool striped[] = { false, true };
  170.     int colorIndex = 0;
  171.     int ballIndex = 0;
  172.  
  173.     for (int row = 0; row < 5; ++row) {
  174.         for (int col = 0; col <= row; ++col) {
  175.             float x = 600.0f + col * 22.0f - row * 11.0f;
  176.             float y = 250.0f + row * 20.0f;
  177.             balls.push_back({ x, y, 0.0f, 0.0f, colors[colorIndex], false, striped[colorIndex] });
  178.             ballIndex++;
  179.             if (ballIndex == 7) {
  180.                 balls.push_back({ 600.0f, 250.0f + (row + 1) * 20.0f, 0.0f, 0.0f, RGB(0, 0, 0), false, false });
  181.             }
  182.             if (ballIndex >= 14) {
  183.                 break;
  184.             }
  185.             colorIndex = (colorIndex + 1) % 2;
  186.         }
  187.     }
  188. }
  189.  
  190. void DrawTable(HDC hdc) {
  191.     HBRUSH hBrush = CreateSolidBrush(RGB(0, 128, 0));
  192.     FillRect(hdc, &table, hBrush);
  193.     DeleteObject(hBrush);
  194.  
  195.     HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
  196.     SelectObject(hdc, hPen);
  197.     for (int i = 0; i < 2; ++i) {
  198.         for (int j = 0; j < 3; ++j) {
  199.             Ellipse(hdc, table.left + j * TABLE_WIDTH / 2 - BALL_RADIUS * 2, table.top + i * TABLE_HEIGHT - BALL_RADIUS * 2, table.left + j * TABLE_WIDTH / 2 + BALL_RADIUS * 2, table.top + i * TABLE_HEIGHT + BALL_RADIUS * 2);
  200.         }
  201.     }
  202.     DeleteObject(hPen);
  203. }
  204.  
  205. void DrawBalls(HDC hdc) {
  206.     for (const auto& ball : balls) {
  207.         if (!ball.isPocketed) {
  208.             hBrush = CreateSolidBrush(ball.color);
  209.             SelectObject(hdc, hBrush);
  210.             Ellipse(hdc, (int)(ball.x - BALL_RADIUS), (int)(ball.y - BALL_RADIUS), (int)(ball.x + BALL_RADIUS), (int)(ball.y + BALL_RADIUS));
  211.             DeleteObject(hBrush);
  212.  
  213.             // Draw stripes/solids
  214.             if (ball.isStriped) {
  215.                 hBrush = CreateSolidBrush(RGB(255, 255, 255));
  216.                 SelectObject(hdc, hBrush);
  217.                 RECT stripe = { (int)(ball.x - BALL_RADIUS), (int)(ball.y - BALL_RADIUS / 3), (int)(ball.x + BALL_RADIUS), (int)(ball.y + BALL_RADIUS / 3) };
  218.                 FillRect(hdc, &stripe, hBrush);
  219.                 DeleteObject(hBrush);
  220.             } else {
  221.                 hBrush = CreateSolidBrush(RGB(255, 255, 255));
  222.                 SelectObject(hdc, hBrush);
  223.                 Ellipse(hdc, (int)(ball.x - BALL
  224.  
  225. _RADIUS / 4), (int)(ball.y - BALL_RADIUS / 4), (int)(ball.x + BALL_RADIUS / 4), (int)(ball.y + BALL_RADIUS / 4));
  226.                 DeleteObject(hBrush);
  227.             }
  228.         }
  229.     }
  230. }
  231.  
  232. void DrawCue(HDC hdc) {
  233.     HPEN hPen = CreatePen(PS_SOLID, 2, RGB(139, 69, 19));
  234.     SelectObject(hdc, hPen);
  235.     MoveToEx(hdc, (int)cueBall.x, (int)cueBall.y, NULL);
  236.     LineTo(hdc, (int)(cueBall.x - (cueEnd.x - cueStart.x)), (int)(cueBall.y - (cueEnd.y - cueStart.y)));
  237.     DeleteObject(hPen);
  238. }
  239.  
  240. void DrawPowerMeter(HDC hdc) {
  241.     HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
  242.     HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0));
  243.     SelectObject(hdc, hPen);
  244.     SelectObject(hdc, hBrush);
  245.  
  246.     RECT powerRect = { 50, 500, (int)(50 + power * 200), 520 };
  247.     FillRect(hdc, &powerRect, hBrush);
  248.     Rectangle(hdc, 50, 500, 250, 520);
  249.  
  250.     DeleteObject(hPen);
  251.     DeleteObject(hBrush);
  252. }
  253.  
  254. void UpdateBalls() {
  255.     for (auto& ball : balls) {
  256.         if (!ball.isPocketed) {
  257.             ball.x += ball.vx;
  258.             ball.y += ball.vy;
  259.             ball.vx *= 0.99f;
  260.             ball.vy *= 0.99f;
  261.  
  262.             if (ball.x - BALL_RADIUS < table.left || ball.x + BALL_RADIUS > table.right) {
  263.                 ball.vx = -ball.vx;
  264.             }
  265.             if (ball.y - BALL_RADIUS < table.top || ball.y + BALL_RADIUS > table.bottom) {
  266.                 ball.vy = -ball.vy;
  267.             }
  268.         }
  269.     }
  270. }
  271.  
  272. void CheckCollisions() {
  273.     for (size_t i = 0; i < balls.size(); ++i) {
  274.         for (size_t j = i + 1; j < balls.size(); ++j) {
  275.             Ball& ball1 = balls[i];
  276.             Ball& ball2 = balls[j];
  277.             float dx = ball2.x - ball1.x;
  278.             float dy = ball2.y - ball1.y;
  279.             float distance = sqrt(dx * dx + dy * dy);
  280.  
  281.             if (distance < BALL_RADIUS * 2 && !ball1.isPocketed && !ball2.isPocketed) {
  282.                 float nx = dx / distance;
  283.                 float ny = dy / distance;
  284.  
  285.                 float kx = ball1.vx - ball2.vx;
  286.                 float ky = ball1.vy - ball2.vy;
  287.                 float p = 2.0f * (nx * kx + ny * ky) / 2.0f;
  288.  
  289.                 ball1.vx -= p * nx;
  290.                 ball1.vy -= p * ny;
  291.                 ball2.vx += p * nx;
  292.                 ball2.vy += p * ny;
  293.             }
  294.         }
  295.     }
  296. }
  297.  
  298. void CheckPockets() {
  299.     for (auto& ball : balls) {
  300.         if (!ball.isPocketed) {
  301.             if (ball.x < table.left || ball.x > table.right || ball.y < table.top || ball.y > table.bottom) {
  302.                 PocketBall(ball);
  303.                 if (ball.color == RGB(0, 0, 0)) {
  304.                     gameOver = true;
  305.                 }
  306.                 if (firstShot) {
  307.                     isSolids = ball.isStriped ? false : true;
  308.                     player1Solids = isSolids;
  309.                     firstShot = false;
  310.                 }
  311.                 CheckFoul(ball);
  312.             }
  313.         }
  314.     }
  315. }
  316.  
  317. void AIMove() {
  318.     // Simplified AI move: just hit the ball towards a random direction
  319.     if (!playerTurn && !gameOver) {
  320.         cueBall.vx = (rand() % 100 - 50) / 10.0f;
  321.         cueBall.vy = (rand() % 100 - 50) / 10.0f;
  322.         playerTurn = true;
  323.     }
  324. }
  325.  
  326. void ApplyEnglish(Ball& ball, float spinX, float spinY) {
  327.     ball.vx += spinX;
  328.     ball.vy += spinY;
  329. }
  330.  
  331. bool CheckGameOver() {
  332.     for (const auto& ball : balls) {
  333.         if (!ball.isPocketed && ball.color != RGB(0, 0, 0)) {
  334.             return false;
  335.         }
  336.     }
  337.     return true;
  338. }
  339.  
  340. void CheckFoul(Ball& ball) {
  341.     if (ball.color == RGB(255, 255, 255)) {
  342.         isCueBallFreeMove = true;
  343.         playerTurn = !playerTurn;
  344.     }
  345. }
  346.  
  347. void PocketBall(Ball& ball) {
  348.     ball.isPocketed = true;
  349.     ball.vx = 0;
  350.     ball.vy = 0;
  351. }
  352.  
  353. void DrawPockets(HDC hdc) {
  354.     HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
  355.     SelectObject(hdc, hBrush);
  356.     for (int i = 0; i < 2; ++i) {
  357.         for (int j = 0; j < 3; ++j) {
  358.             Ellipse(hdc, table.left + j * TABLE_WIDTH / 2 - BALL_RADIUS * 2, table.top + i * TABLE_HEIGHT - BALL_RADIUS * 2, table.left + j * TABLE_WIDTH / 2 + BALL_RADIUS * 2, table.top + i * TABLE_HEIGHT + BALL_RADIUS * 2);
  359.         }
  360.     }
  361.     DeleteObject(hBrush);
  362. }
  363.  
  364. void DrawPlayerTurn(HDC hdc) {
  365.     const wchar_t* playerText = playerTurn ? L"Player 1's Turn" : L"Player 2's Turn";
  366.     SetBkMode(hdc, TRANSPARENT);
  367.     TextOut(hdc, 350, 20, playerText, lstrlen(playerText));
  368. }
  369.  
  370. // Additional helper function to reset the game
  371. void ResetGame() {
  372.     InitBalls();
  373.     playerTurn = true;
  374.     gameOver = false;
  375.     firstShot = true;
  376.     isSolids = false;
  377.     player1Solids = false;
  378.     isCueBallFreeMove = false;
  379.     InvalidateRect(hwnd, NULL, FALSE);
  380. }
  381.  
  382. // Main message processing function
  383. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  384.     switch (message) {
  385.     case WM_CREATE:
  386.         srand((unsigned int)time(NULL));
  387.         InitBalls();
  388.         SetTimer(hwnd, ID_TIMER, 16, NULL);
  389.         break;
  390.     case WM_PAINT: {
  391.         PAINTSTRUCT ps;
  392.         HDC hdc = BeginPaint(hwnd, &ps);
  393.         if (!hdcMem) {
  394.             hdcMem = CreateCompatibleDC(hdc);
  395.             hbmMem = CreateCompatibleBitmap(hdc, 900, 600);
  396.             hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
  397.         }
  398.         FillRect(hdcMem, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
  399.         DrawTable(hdcMem);
  400.         DrawBalls(hdcMem);
  401.         DrawPockets(hdcMem);
  402.         DrawPlayerTurn(hdcMem);
  403.         if (!gameOver && playerTurn && !isCueBallFreeMove) {
  404.             DrawCue(hdcMem);
  405.             DrawPowerMeter(hdcMem);
  406.         }
  407.         BitBlt(hdc, 0, 0, 900, 600, hdcMem, 0, 0, SRCCOPY);
  408.         EndPaint(hwnd, &ps);
  409.         break;
  410.     }
  411.     case WM_LBUTTONDOWN:
  412.         if (gameOver) break;
  413.         if (isCueBallFreeMove) {
  414.             cueBall.x = LOWORD(lParam);
  415.             cueBall.y = HIWORD(lParam);
  416.             isCueBallFreeMove = false;
  417.             InvalidateRect(hwnd, NULL, FALSE);
  418.         } else if (playerTurn) {
  419.             cueStart.x = LOWORD(lParam);
  420.             cueStart.y = HIWORD(lParam);
  421.             isDragging = true;
  422.         }
  423.         break;
  424.     case WM_MOUSEMOVE:
  425.         if (isDragging) {
  426.             cueEnd.x = LOWORD(lParam);
  427.             cueEnd.y = HIWORD(lParam);
  428.             power = min(sqrt(pow(cueEnd.x - cueStart.x, 2) + pow(cueEnd.y - cueStart.y, 2)) / 100.0f, 1.0f);
  429.             InvalidateRect(hwnd, NULL, FALSE);
  430.         }
  431.         break;
  432.     case WM_LBUTTONUP:
  433.         if (isDragging) {
  434.             isDragging = false;
  435.             float dx = cueEnd.x - cueStart.x;
  436.             float dy = cueEnd.y - cueStart.y;
  437.             cueBall.vx = dx * power * 0.5f;
  438.             cueBall.vy = dy * power * 0.5f;
  439.             ApplyEnglish(cueBall, dx * power * 0.1f, dy * power * 0.1f);
  440.             playerTurn = false;
  441.             InvalidateRect(hwnd, NULL, FALSE);
  442.         }
  443.         break;
  444.     case WM_TIMER:
  445.         if (!gameOver) {
  446.             UpdateBalls();
  447.             CheckCollisions();
  448.             CheckPockets();
  449.             if (!playerTurn) AIMove();
  450.             if (CheckGameOver()) {
  451.                 gameOver = true;
  452.                 MessageBox(hwnd, L"Game Over! All balls are pocketed.", L"Game Over", MB_OK);
  453.             }
  454.             InvalidateRect(hwnd, NULL, FALSE);
  455.         }
  456.         break;
  457.     case WM_DESTROY:
  458.         KillTimer(hwnd, ID_TIMER);
  459.         SelectObject(hdcMem, hbmOld);
  460.         DeleteObject(hbmMem);
  461.         DeleteDC(hdcMem);
  462.         PostQuitMessage(0);
  463.         break;
  464.     case WM_KEYDOWN:
  465.         if (wParam == 'R') {
  466.             ResetGame();
  467.         }
  468.         break;
  469.     default:
  470.         return DefWindowProc(hwnd, message, wParam, lParam);
  471.     }
  472.     return 0;
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement