Below you will find a game I written in my spare time from college. Any and all critique welcome. I plan to expand this to a console RPG later, and eventually GUI. All in C++.

BTW, nice forums.

//============================================================================
// Name        : Monster Shot.cpp
// Author      : Dave T
// Description : Monster Shot is an array based game in which the user
// makes guesses in the form of inputing numbers in order to hit monsters hiding
// in the array.
// Additional Notes: I wrote this with a friend to help understand C++ basics
//============================================================================


/** PREPROCESSOR DIRECTIVES **/
#include <iostream>


/** CONSTANTS **/

    // WORLD SIZE Determines the playable space of the game
#define EASY_WORLD_SIZE 6
#define NORMAL_WORLD_SIZE 10
#define HARD_WORLD_SIZE 25

    // The number of shots the user has
#define EASY_AMMO 3
#define NORMAL_AMMO 7
#define HARD_AMMO 12

    // Gives + to ammo
#define POWERUP_AMMO -1
#define POWERUP_X2 -2

using namespace std;

/** GLOBAL VARIABLES **/
int easyBoard[EASY_WORLD_SIZE] = {-1,1,0,1,1,0}; // Easy Game Board
int normalBoard[NORMAL_WORLD_SIZE] = {1,1,0,0,10,1,0,1,-1,10}; // Normal(Default) Game Board
int hardBoard[HARD_WORLD_SIZE] = {0,-2,1,10,0,1,0,1,1,10,1,1,0,-2,0,1,0,0,1,1,10,1,1,0,-1}; // Hard Game Board

int * pBoard; // Points at board that the user selects
int worldSize; // holds worldSize value
int gameAmmo; // holds ammo


/** MESSAGE HANDLER **/
char msgHowtoPlay[] = "HOW TO PLAY : \n"
                    "Enter a number\n"
                    "and it will either result in a hit or \n"
                    "miss for a monster.\n\n";

char msgChooseDifficulty[] = "CHOOSE DIFFICULTY SETTING\n"
                            "Enter: 'e'\t'n'\t'h'\n"
                            "\nEasy: 5 space board\n"

                            "Normal: 10 space board\n"

                            "Hard: 25 space board\n\n";


char msgGameOver[] = "\nOut of ammo!\n\n"
                    "A shadow of fear washes over you\n"
                    "as the monsters approach...\n\n"
                    "GAME OVER\n\n";

char msgYouWin[] = "All monsters slain.\n"
                    "YOU WIN!\n\n";

char msgMonsterHit[] = "You hit a monster \n";

char msgWheretoAim[] = "\nWhere will you aim? (Enter # between 1 - ";

char msgInvalid[] = "invalid input, try again\n";

char msgMissed[] = "Hey man, you missed \n";

/** FUNCTION DEFINITIONS **/
void intro()
{
    cout << msgHowtoPlay;
}

// Difficulty Setting Handler
void chooseDifficulty()
{
    char diffChoice;
    cout << msgChooseDifficulty;

    cin >> diffChoice;
    if(diffChoice == 'e')
    {

        pBoard = easyBoard;
        gameAmmo = EASY_AMMO;
        worldSize = EASY_WORLD_SIZE;
        cout << "You have selected [easy].\n";
    }

    else if(diffChoice == 'n')
    {
        pBoard = normalBoard;
        gameAmmo = NORMAL_AMMO;
        worldSize = NORMAL_WORLD_SIZE;
        cout << "You have selected [normal].\n";
    }

    else if(diffChoice == 'h')
    {
        pBoard = hardBoard;
        gameAmmo = HARD_AMMO;
        worldSize = HARD_WORLD_SIZE;
        cout << "You have selected [hard].\n";
    }

    else
    {
        pBoard = normalBoard;
        gameAmmo = NORMAL_AMMO;
        worldSize = NORMAL_WORLD_SIZE;
        cout << "Default selection: [normal].\n";
    }
    cout << "You have "<< gameAmmo << " Shots\n";
}

// CHecks for 0 Ammo
bool gameOver()
{
    if(gameAmmo == 0)
    {
        cout << msgGameOver;
        return true;
    }else
        return false;
}

// Checks for clear board
bool checkWin()
{
    for(int i=0;i<worldSize; i++)
    {

        if(pBoard[i] > 0)
        {
            return false;
        }
    }
    return true;
}

/****************************************************************/
int main()
{
    int shot; // the user's shot
    int i; // holds decremented shot as index for board
    int score = 0;

    // GAME RULES & DIFFICULTY HANDLING
    intro();
    chooseDifficulty();

    // GAME
    while(true)
    {
        cout << msgWheretoAim << worldSize << ") ";
        cin >> shot;
        if(shot < 1 || shot > worldSize)
        {
            cout << msgInvalid;
            continue;
        }

        // converts user's shot to index
        i = shot-1;
        gameAmmo--;

        // Check for monster Hit
        if(pBoard[i] > 0)
        {
            // You got one!
            cout << msgMonsterHit;

            score+=pBoard[i];
            if(pBoard[i] == 10)
            {
                cout << "+ 10 points!\n";
            }

            // Clear the space and check for a win
            pBoard[i] = 0;
        // Checks for
        }else if(pBoard[i] == POWERUP_AMMO)
        {
            gameAmmo+=2;
            cout << "BONUS! + 2 to ammo!\n";
            cout << gameAmmo << " shots remaining \n\n";
        }else if(pBoard[i] == POWERUP_X2)
        {
            gameAmmo+=3;
            cout << "BONUS! + 3 to ammo!\n";
            cout << gameAmmo << " shots remaining \n\n";
        }else
        {
            cout << msgMissed;
            cout << gameAmmo << " shots remaining \n";
            if(gameOver() == true)
            {
                break;
            }
        }

        if(checkWin() == true)
        {
            cout << msgYouWin;
            break;
        }
    }
    cout << "Final Score: " << score << endl;
    return 0;
}

Dani AI

Generated

Brief expert commentary on 's "Monster Shot" sample and the replies that follow. The program is a solid beginner exercise: the gameplay loop, scoring and difficulty choices are all clear. Several responders (notably and ) pointed toward refactoring and extensibility—those are the highest‑value improvements when the same toy will become a console RPG or a GUI later.

Design and data model: replace raw ints-and-sentinels with a small domain model. Represent each board cell as a typed value (empty / monster / powerup) and a payload (hit‑points or points). Store the board in a container like std::vector, not a raw C array, and use an enum (or enum class) to name tile kinds rather than negative magic numbers. Encapsulate the game state and rules in a Game class that exposes operations like shoot(index) and loadLevel(path). That makes expanding to file‑based levels or a GUI trivial because the core logic will not depend on cin/cout.

Safety, clarity and modern C++: avoid #define for numeric constants—use constexpr or const. Prefer size_t for sizes/indices, check ranges with container.size(), and parse input by reading a line then validating (don’t rely entirely on >>). Keep input/output out of the core game logic so unit tests can exercise gameplay without terminal IO. Use small, well‑named functions and assertions for invariants (e.g., board size matches data), which helps catch regressions quickly.

Practical next steps and quick checklist (applies to , and the OP):

  • Encapsulate state into a Game class and remove globals.
  • Replace magic ints with typed enums/structs for clarity.
  • Make levels loadable from simple text files to support authored or randomized maps.
  • Decouple IO to ease later GUI porting and to allow automated tests.
  • If Dev‑C++ fails to build, capture the compiler errors and try compiling with a modern toolchain (or enable a newer C++ standard); ’s request for the exact errors is the right troubleshooting move.

These changes reduce bugs, improve readability, and make the project ready for the console/RPG/GUI milestones mentioned earlier.

Recommended Answers

All 11 Replies

Since usually the main constraint in C++ is performance, your code is wasting a lot of resources! Try to improve it! Get rid of unused variables and unecessary constants; declare only what you need and where you need. Try to avoid global declarations; Optimize you control structures: consider using 'switch' instead of 'if... else' and 'do... while' instead of 'while'... right now, just looking at it, I know that you could improve the performance, readability and the size by reducing something like 75 lines or more!

Make a more generic game.
Instead of built in levels , use a class ( or just a function if you dont know classes yet)
that will read from a file.
Even better is to build another class that will randomly make the levels
it will recieve the difficulty and will make the map according to it ( size / monsters / shots ..)

By using those classes you will also save a few lines from the main funcs making it more readable
and much shorter.

and ofcourse as KaeLL said , switch is a much better option in my opinion aswel .

good luck

Since usually the main constraint in C++ is performance

This is not true, it is compiled language and still this is not normally the case even in interpreted language like Python I am mostly using. The main constraint is overcomplicating things, hard coding, making unreadable or too long winded code, like comments adding no value as in

// Checks for clear board
bool checkWin()

instead of

// checkWin is used to determine exit from main while loop
bool checkWin

Performance is last to consider provided you select proper data structures and algorithms. So rest of your advice (from "Try...") is sound.

Well guys, it's been four months sine the initial OP post. I don't know if he's looking into this program anymore.
KaeLL I know that you're new on our website, but a read through our rules wouldn't have hurt you.
Perhaps getting rid of unnecessary variables and declarations would clear up your code a bit, keeping it simple and clear.

Hello guys. Thanks a TON for replying. I still have this program but it has been updated, I decided to write it using classes, but got bogged down with stuff going on in my life to continue it. I will carefully examine your advice, apply it, and post the new code here as well.

Member Avatar for Member #46692

This game is terrible, I didn't enjoy playing it.

Yeah you're right, I'm working on it now, can't believe I posted this 4 months ago. It's atrocious.

Here's the function void chooseDifficulty() with a switch statement rather than

void chooseDifficulty()
{
    char diffChoice;
    cout << msgChooseDifficulty;
    cin >> diffChoice;

    switch(diffChoice)
    {
       case 'e':
            pBoard = easyBoard;
            gameAmmo = EASY_AMMO;
            worldSize = EASY_WORLD_SIZE;
            cout << "You have selected [easy].\n";
            break;

        case 'n':
            pBoard = normalBoard;
            gameAmmo = NORMAL_AMMO;
            worldSize = NORMAL_WORLD_SIZE;
            cout << "You have selected [normal].\n";
            break;

        case 'h':
            pBoard = hardBoard;
            gameAmmo = HARD_AMMO;
            worldSize = HARD_WORLD_SIZE;
            cout << "You have selected [hard].\n";
            break;

        default:
            pBoard = normalBoard;
            gameAmmo = NORMAL_AMMO;
            worldSize = NORMAL_WORLD_SIZE;
            cout << "Default selection: [normal].\n";
            break;
    }

    cout << "You have "<< gameAmmo << " Shots\n";
}

if else

@pyTony

You are absolutely right. So, rephrasing: the main constraint is achieve high performance with good practices and style.

@Lucaci Andrew
Sorry about this! Indeed I knew it, but I've forgotten!
I'll remeber next time! Thanks for the warning!

THE ABOVE CODE DOES NOT RUN USING DEV C++ WHAT SALL I USE TO RUN IT?

THE ABOVE CODE DOES NOT RUN USING DEV C++ WHAT SALL I USE TO RUN IT?

At a glance it doesn't look like the code uses anything that Dev-C++ shouldn't be able to handle. What errors are you getting?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.