diff --git a/windows/templates/sweepminer/info.template b/windows/templates/sweepminer/info.template index 1a942512..a78f41f2 100644 --- a/windows/templates/sweepminer/info.template +++ b/windows/templates/sweepminer/info.template @@ -18,5 +18,5 @@ UnitCount = 1 [Unit0] -C = main.c -CName = main.c +Cpp = main.cpp +CppName = main.cpp diff --git a/windows/templates/sweepminer/main.c b/windows/templates/sweepminer/main.c deleted file mode 100644 index e4e5495c..00000000 --- a/windows/templates/sweepminer/main.c +++ /dev/null @@ -1,324 +0,0 @@ -/******************************************************************************************* -* -* raylib - classic game: arkanoid -* -* Sample game developed by Marc Palau and Ramon Santamaria -* -* This game has been created using raylib v1.3 (www.raylib.com) -* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -* -* Copyright (c) 2015 Ramon Santamaria (@raysan5) -* -* Icon from https://www.flaticon.com/free-icon/arkanoid_2927802 -********************************************************************************************/ - -#include - -#include -#include -#include -#include - -#if defined(PLATFORM_WEB) -#include -#endif - -//---------------------------------------------------------------------------------- -// Some Defines -//---------------------------------------------------------------------------------- -#define PLAYER_MAX_LIFE 5 -#define LINES_OF_BRICKS 5 -#define BRICKS_PER_LINE 20 - -//---------------------------------------------------------------------------------- -// Types and Structures Definition -//---------------------------------------------------------------------------------- -typedef enum GameScreen { LOGO, TITLE, GAMEPLAY, ENDING } GameScreen; - -typedef struct Player { - Vector2 position; - Vector2 size; - int life; -} Player; - -typedef struct Ball { - Vector2 position; - Vector2 speed; - int radius; - bool active; -} Ball; - -typedef struct Brick { - Vector2 position; - bool active; -} Brick; - -//------------------------------------------------------------------------------------ -// Global Variables Declaration -//------------------------------------------------------------------------------------ -static const int screenWidth = 800; -static const int screenHeight = 450; - -static bool gameOver = false; -static bool pause = false; - -static Player player = { 0 }; -static Ball ball = { 0 }; -static Brick brick[LINES_OF_BRICKS][BRICKS_PER_LINE] = { 0 }; -static Vector2 brickSize = { 0 }; - -//------------------------------------------------------------------------------------ -// Module Functions Declaration (local) -//------------------------------------------------------------------------------------ -static void InitGame(void); // Initialize game -static void UpdateGame(void); // Update game (one frame) -static void DrawGame(void); // Draw game (one frame) -static void UnloadGame(void); // Unload game -static void UpdateDrawFrame(void); // Update and Draw (one frame) - -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ -int main(void) -{ - // Initialization (Note windowTitle is unused on Android) - //--------------------------------------------------------- - InitWindow(screenWidth, screenHeight, "classic game: arkanoid"); - - InitGame(); - -#if defined(PLATFORM_WEB) - emscripten_set_main_loop(UpdateDrawFrame, 60, 1); -#else - SetTargetFPS(60); - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update and Draw - //---------------------------------------------------------------------------------- - UpdateDrawFrame(); - //---------------------------------------------------------------------------------- - } -#endif - // De-Initialization - //-------------------------------------------------------------------------------------- - UnloadGame(); // Unload loaded data (textures, sounds, models...) - - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -} - -//------------------------------------------------------------------------------------ -// Module Functions Definitions (local) -//------------------------------------------------------------------------------------ - -// Initialize game variables -void InitGame(void) -{ - brickSize = (Vector2){ GetScreenWidth()/BRICKS_PER_LINE, 40 }; - - // Initialize player - player.position = (Vector2){ screenWidth/2, screenHeight*7/8 }; - player.size = (Vector2){ screenWidth/10, 20 }; - player.life = PLAYER_MAX_LIFE; - - // Initialize ball - ball.position = (Vector2){ screenWidth/2, screenHeight*7/8 - 30 }; - ball.speed = (Vector2){ 0, 0 }; - ball.radius = 7; - ball.active = false; - - // Initialize bricks - int initialDownPosition = 50; - - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - brick[i][j].position = (Vector2){ j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition }; - brick[i][j].active = true; - } - } -} - -// Update game (one frame) -void UpdateGame(void) -{ - if (!gameOver) - { - if (IsKeyPressed('P')) pause = !pause; - - if (!pause) - { - // Player movement logic - if (IsKeyDown(KEY_LEFT)) player.position.x -= 5; - if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2; - if (IsKeyDown(KEY_RIGHT)) player.position.x += 5; - if ((player.position.x + player.size.x/2) >= screenWidth) player.position.x = screenWidth - player.size.x/2; - - // Ball launching logic - if (!ball.active) - { - if (IsKeyPressed(KEY_SPACE)) - { - ball.active = true; - ball.speed = (Vector2){ 0, -5 }; - } - } - - // Ball movement logic - if (ball.active) - { - ball.position.x += ball.speed.x; - ball.position.y += ball.speed.y; - } - else - { - ball.position = (Vector2){ player.position.x, screenHeight*7/8 - 30 }; - } - - // Collision logic: ball vs walls - if (((ball.position.x + ball.radius) >= screenWidth) || ((ball.position.x - ball.radius) <= 0)) ball.speed.x *= -1; - if ((ball.position.y - ball.radius) <= 0) ball.speed.y *= -1; - if ((ball.position.y + ball.radius) >= screenHeight) - { - ball.speed = (Vector2){ 0, 0 }; - ball.active = false; - - player.life--; - } - - // Collision logic: ball vs player - if (CheckCollisionCircleRec(ball.position, ball.radius, - (Rectangle){ player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y})) - { - if (ball.speed.y > 0) - { - ball.speed.y *= -1; - ball.speed.x = (ball.position.x - player.position.x)/(player.size.x/2)*5; - } - } - - // Collision logic: ball vs bricks - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - if (brick[i][j].active) - { - // Hit below - if (((ball.position.y - ball.radius) <= (brick[i][j].position.y + brickSize.y/2)) && - ((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) && - ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y < 0)) - { - brick[i][j].active = false; - ball.speed.y *= -1; - } - // Hit above - else if (((ball.position.y + ball.radius) >= (brick[i][j].position.y - brickSize.y/2)) && - ((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) && - ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y > 0)) - { - brick[i][j].active = false; - ball.speed.y *= -1; - } - // Hit left - else if (((ball.position.x + ball.radius) >= (brick[i][j].position.x - brickSize.x/2)) && - ((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) && - ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x > 0)) - { - brick[i][j].active = false; - ball.speed.x *= -1; - } - // Hit right - else if (((ball.position.x - ball.radius) <= (brick[i][j].position.x + brickSize.x/2)) && - ((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) && - ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x < 0)) - { - brick[i][j].active = false; - ball.speed.x *= -1; - } - } - } - } - - // Game over logic - if (player.life <= 0) gameOver = true; - else - { - gameOver = true; - - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - if (brick[i][j].active) gameOver = false; - } - } - } - } - } - else - { - if (IsKeyPressed(KEY_ENTER)) - { - InitGame(); - gameOver = false; - } - } -} - -// Draw game (one frame) -void DrawGame(void) -{ - BeginDrawing(); - - ClearBackground(RAYWHITE); - - if (!gameOver) - { - // Draw player bar - DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK); - - // Draw player lives - for (int i = 0; i < player.life; i++) DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY); - - // Draw ball - DrawCircleV(ball.position, ball.radius, MAROON); - - // Draw bricks - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - if (brick[i][j].active) - { - if ((i + j) % 2 == 0) DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY); - else DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY); - } - } - } - - if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY); - } - else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY); - - EndDrawing(); -} - -// Unload game variables -void UnloadGame(void) -{ - // TODO: Unload all dynamic loaded data (textures, sounds, models...) -} - -// Update and Draw (one frame) -void UpdateDrawFrame(void) -{ - UpdateGame(); - DrawGame(); -} diff --git a/windows/templates/sweepminer/main.cpp b/windows/templates/sweepminer/main.cpp new file mode 100644 index 00000000..d711be88 --- /dev/null +++ b/windows/templates/sweepminer/main.cpp @@ -0,0 +1,437 @@ +/* + * Minesweeper by Matthew Zegar + * https://github.com/mzegar/Minesweeper-Cplusplus + * app icon from https://www.flaticon.com/free-icon/mine_486968 + */ + +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +#define ROWS 9 +#define COLUMNS 9 + +const int empty = -1; +const int mine = 0; + +class block { +public: + block(); + block(int x, int y, int btype); + + + // Mutators + setx(int x); + sety(int y); + setrevealed(bool reveal); + setmarked(bool mark); + settype(int btype); + formatblock(int x, int y); + + // Accessors + int getx(); + int gety(); + bool getrevealed(); + bool getmarked(); + int gettype(); + +private: + // Coordinates of block + int xcord; + int ycord; + + // States + bool revealed; + bool marked; + + // Type + int type; // Ranges from -1 to 8 + +}; + +// Create 2d array +block gameboard[ROWS][COLUMNS]; + + +// Generate random number +int randomnum() { + return rand() % 10; +} + +// Generate number blocks +void numbergeneration(int i, int j); + +// Update empty spots +void floodfill(int x, int y); + +// Game states +bool gameover = false; +bool gamewon = false; +void restartgame(); + +// Block counts +int totalblocks = 0; + + +int main() +{ + + // Initialization of window + //-------------------------------------------------------------------------------------- + int screenWidth = 450; + int screenHeight = 450; + InitWindow(screenWidth, screenHeight, "Minesweeper by Matthew Zegar"); + SetTargetFPS(60); + + restartgame(); + + // Mouse setup + //-------------------------------------------------------------------------------------- + Vector2 mouse; + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Mouse update + //---------------------------------------------------------------------------------- + mouse = GetMousePosition(); + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + // Mouse left click + //---------------------------------------------------------------------------------- + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { + if (!gameover && !gamewon) { + int y = floor(mouse.y/50); + int x = floor(mouse.x/50); + if (y >= 0 && y < ROWS + && x >=0 && x < COLUMNS ) { + if (gameboard[y][x].getmarked() == false) { + gameboard[y][x].setrevealed(true); + if (gameboard[y][x].gettype() == -1) { // CHECK IF 'EMPTY' + gameboard[y][x].setrevealed(false); + floodfill(y, x); + } + + if (gameboard[y][x].gettype() == 0) { + gameover = true; + } + } + } + } + } + + // Mouse right click + //---------------------------------------------------------------------------------- + if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) { + if (!gameover && !gamewon) { + int y = floor(mouse.y/50); + int x = floor(mouse.x/50); + if (y >= 0 && y < ROWS + && x >=0 && x < COLUMNS ) { + if (gameboard[y][x].getrevealed() == false) { + if (gameboard[y][x].getmarked() == false) { + gameboard[y][x].setmarked(true); + } else { + gameboard[y][x].setmarked(false); + } + } + } + } + } + + // Draw the blocks + //-------------------------------------------------------------------------------------- + for (int i = 0; i < ROWS; ++i) { + for (int j = 0; j < COLUMNS; ++j) { + if (gameboard[i][j].getrevealed() == false) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, LIGHTGRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + } else { + if (gameboard[i][j].gettype() == 0) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, RED); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + } else if (gameboard[i][j].gettype() == -1) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, GRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + } else if (gameboard[i][j].gettype() == 1) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, DARKGRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + DrawText(TextFormat("%i", gameboard[i][j].gettype()), gameboard[i][j].gety()*50+20, gameboard[i][j].getx()*50+15, 25, SKYBLUE); + } else if (gameboard[i][j].gettype() == 2) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, DARKGRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + DrawText(TextFormat("%i", gameboard[i][j].gettype()), gameboard[i][j].gety()*50+20, gameboard[i][j].getx()*50+15, 25, GREEN); + } else if (gameboard[i][j].gettype() == 3) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, DARKGRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + DrawText(TextFormat("%i", gameboard[i][j].gettype()), gameboard[i][j].gety()*50+20, gameboard[i][j].getx()*50+15, 25, RED); + } else if (gameboard[i][j].gettype() == 4) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, DARKGRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + DrawText(TextFormat("%i", gameboard[i][j].gettype()), gameboard[i][j].gety()*50+20, gameboard[i][j].getx()*50+15, 25, DARKBLUE); + } else if (gameboard[i][j].gettype() >= 5) { + DrawRectangle(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, DARKGRAY); + DrawRectangleLines(gameboard[i][j].gety()*50, gameboard[i][j].getx()*50, 50, 50, BLACK); + DrawText(TextFormat("%i", gameboard[i][j].gettype()), gameboard[i][j].gety()*50+20, gameboard[i][j].getx()*50+15, 25, MAROON); + } + } + } + } + + // Draw the marked blocks (flags) + //---------------------------------------------------------------------------------- + for (int i = 0; i < ROWS; ++i) { + for (int j = 0; j < COLUMNS; ++j) { + if (gameboard[i][j].getmarked() == true and gameboard[i][j].getrevealed() == false) { + DrawRectangle(gameboard[i][j].gety()*50+15, gameboard[i][j].getx()*50+10, 10, 10, RED); + DrawRectangle(gameboard[i][j].gety()*50+25, gameboard[i][j].getx()*50+10, 5, 25, BLACK); + DrawRectangle(gameboard[i][j].gety()*50+20, gameboard[i][j].getx()*50+35, 15, 5, BLACK); + } + } + } + + // Update variable to determine if won + //---------------------------------------------------------------------------------- + totalblocks = 0; + for (int i = 0; i < ROWS; ++i) { + for (int j = 0; j < COLUMNS; ++j) { + if (gameboard[i][j].gettype() >= 1 and gameboard[i][j].getrevealed() == false) { + totalblocks++; + } + } + } + + // Check for win + //---------------------------------------------------------------------------------- + if (totalblocks == 0) { + DrawText("Game won!", 103, 203, 50, BLACK); + DrawText("Game won!", 100, 200, 50, GREEN); + DrawText("right click to restart", 101, 251, 25, WHITE); + DrawText("right click to restart", 100, 250, 25, BLACK); + gamewon = true; + + for (int i = 0; i < ROWS; ++i) { + for (int j = 0; j < COLUMNS; ++j) { + gameboard[i][j].setrevealed(true); + } + } + + if ((IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))) { + restartgame(); + gamewon = false; + } + } + + // Check for gameover + //---------------------------------------------------------------------------------- + if (gameover == true) { + DrawText("Game Over", 103, 203, 50, BLACK); + DrawText("Game Over", 100, 200, 50, RED); + DrawText("right click to restart", 101, 251, 25, WHITE); + DrawText("right click to restart", 100, 250, 25, BLACK); + + + if ((IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))) { + restartgame(); + gameover = false; + } + } + + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +// Floodfill algorithm +void floodfill(int x, int y) { + if (x >= 0 and x = 0 and y < COLUMNS) { + if (gameboard[x][y].gettype() != -1) { + gameboard[x][y].setrevealed(true); + } else { + if (gameboard[x][y].getrevealed() == false) { + gameboard[x][y].setrevealed(true); + floodfill(x-1, y); + //floodfill(x-1, y-1); + floodfill(x, y-1); + //floodfill(x+1, y-1); + floodfill(x+1, y); + //floodfill(x+1, y+1); + floodfill(x, y+1); + //floodfill(x-1, y+1); + } + } + } +} + +// Restart the game +void restartgame() { + for (int i = 0; i < ROWS; ++i) { + for (int j = 0; j < COLUMNS; ++j) { + gameboard[i][j] = block(i,j,-1); + } + } + + // Generate mines + //-------------------------------------------------------------------------------------- + srand(time(NULL)); + for (int i = 0; i < ROWS; ++i) { + for (int j = 0; j < COLUMNS; ++j) { + if (randomnum() == 1) { + gameboard[i][j].settype(0); + } + } + } + + // Generate numbers + //-------------------------------------------------------------------------------------- + for (int i = 0; i < 9; ++i) { + for (int j = 0; j < 9; ++j) { + if (gameboard[i][j].gettype() != 0) { + numbergeneration(i,j); + } + } + } +} + +// Generates the numbered blocks based on mines +void numbergeneration(int i, int j) { + int count = 0; + + // Check left hand side + if ((j-1)>=0) { + if ((i-1) >= 0) { + if (gameboard[i-1][j-1].gettype() == 0) { + count++; + } + } + if (gameboard[i][j-1].gettype() == 0) { + count++; + } + if ((i+1) < ROWS) { + if (gameboard[i+1][j-1].gettype() == 0) { + count++; + } + } + } + + + // Check middle + if ((i-1) >= 0) { + if (gameboard[i-1][j].gettype() == 0) { + count++; + } + } + + if ((i+1) < ROWS) { + if (gameboard[i+1][j].gettype() == 0) { + count++; + } + } + + // Check right + if ((j+1)= 0) { + if (gameboard[i-1][j+1].gettype() == 0) { + count++; + } + } + if (gameboard[i][j+1].gettype() == 0) { + count++; + } + if ((i+1) <= ROWS) { + if (gameboard[i+1][j+1].gettype() == 0) { + count++; + } + } + } + + if (count>0) + gameboard[i][j].settype(count); + +} + +block::block() { + xcord = 0; + ycord = 0; + revealed = false; + marked = false; + type = 0; +} + +block::block(int x, int y, int btype) { + xcord = x; + ycord = y; + revealed = false; + marked = false; + type = btype; +} + +/////////////////////// +// Mutators +/////////////////////// + +block::setx(int x) { + xcord = x; +} + +block::sety(int y) { + ycord = y; +} + +block::setrevealed(bool reveal) { + revealed = reveal; +} + +block::setmarked(bool mark) { + marked = mark; +} + +block::settype(int btype) { + type = btype; +} + +block::formatblock(int x, int y) { +} + +/////////////////////// +// Accessors +/////////////////////// + +int block::getx() { + return xcord; +} + +int block::gety() { + return ycord; +} + +bool block::getrevealed() { + return revealed; +} + +bool block::getmarked() { + return marked; +} + +int block::gettype() { + return type; +} +