Chapter 4 – A Rock Paper Scissors Game

Artificial Intelligence

For most games, we need a way to challenge the user, make him compete, in order to increase the difficulty of the game. For that we need to write AI code. AI is used widely in game programming, it is part of the game’s logic. The size and complexity of the AI code you write depends on the game. It can be only about 3 lines in a pong clone, or it can span several source-files and consist of complex algorithms in one of those chess games.

Rock, Paper, Scissors!

Although we won’t be delving into a lot of AI logic code right now, I’ll just give a simple (perhaps the simplest) example of AI code, I’ll write a console rock-paper-scissors game. Since the average rock-paper-scissors game doesn’t need any stratagems, all we need to do is generate a random choice for the computer’s turn.

Here’s the code:

///////////////////////////////////////////////////////////
// Console Rock Paper Scissors Game
// Vesion 1.0
// Author: Muhammad Ahmad Tirmazi
// Copright 2012 Muhammad Ahmad Tirmazi
// License: BSD 4-Clause
//////////////////////////////////////////////////////////

/////////////////////
// Includes
/////////////////////
#include <iostream>
#include <cstdlib>
#include <ctime>

////////////////////////////
// Preprocessor Definitions
///////////////////////////
#define ROCK 1
#define PAPER 2
#define SCISSORS 3

/////////////////////////
// Our Custom Namespace
/////////////////////////
namespace pro
{
    ////////////////////////
    // The Main Game Class
    ////////////////////////
    class Game
    {
    public:
        /////////////////
        // Constructor
        ////////////////
        Game();
    private:

        ///////////////////////
        // Handles all input
        ///////////////////////
        void GetInput();

        //////////////////////////////////
        // Displays a flashy introduction
        // at the beginning of the game
        /////////////////////////////////
        void DisplayIntro();

        ////////////////////////////////////
        // AI Code for the opponent's move
        ////////////////////////////////////
        void DecideAIMove();

        ////////////////////////////////////
        // Checks who has won the game
        ////////////////////////////////////
        void DecideWinner();
    private:
        /////////////////////////////////
        // The player's choice. R,P or S
        /////////////////////////////////
        int op;

        ////////////////////////////////
        // Opponent's Choice. R, P or S
        ////////////////////////////////
        int ai_op;

        ////////////////////////////////
        // Set to true when exiting
        ////////////////////////////////
        bool done;

    };

    Game::Game()
        : done(false) // set done to false
    {
        // so that new numbers are generated on each run
        std::srand(std::time(0));

        DisplayIntro();

        /** Game Loop **/

        while(!done)
        {
            GetInput();
            if (done) break; // if the player typed '0'

            DecideAIMove();
            DecideWinner();
        }
    }

    void Game::DisplayIntro()
    {
        /** Game Interface **/

        // a hatch block thing symbol
        char block = 177;

        /////////////////////////////
        // ======================= //
        // = ROCK PAPER SCISSORS = //
        // ======================= //
        /////////////////////////////

        std::cout << std::string(23, block) << "\n";
        std::cout << std::string(23, '=') << "\n";
        std::cout << "  ROCK PAPER SCISSORS  \n";
        std::cout << std::string(23, '=') << "\n";
        std::cout << std::string(23, block) << "\n";

        std::cout << "\n";

        std::cout << "Compete with a computer opponent.\n\n";
        std::cout << "Type 0 to exit.\n";
    }

    void Game::GetInput()
    {
        /** Game Interface **/

        while (1)
        {
            std::cout << "Type 1 For Rock.\n";
            std::cout << "Type 2 For Paper.\n";
            std::cout << "Type 3 For Scissors.\n";
            std::cout << "Enter Choice: ";

            std::cin >> op;

            // error check
            if (op < 0 || op > 3) std::cerr <<  "\nWrong entry.\n\n";

            // if the player types '0', quit the game
            else if (op == 0)
            {
                done = true;
                break;
            }

            else break;
        }
    }

    void Game::DecideAIMove()
    {
        // AI Code
        ai_op = ((std::rand() % 3) + 1);
        // ^ random decision
        // I doubt there's any technique in a rock-paper-scissors game.


        // Print out the opponents choice
        std::string choice;

        if (ai_op == 1) choice = "Rock";
        else if (ai_op == 2) choice = "Paper";
        else choice = "Scissors";

        std::cout << "Opponent chose " << choice << ".\n";
    }

    void Game::DecideWinner()
    {
        /** GAME LOGIC **/

        // 1 if you win
        // 2 if op wins
        // 0 if draw
        int win = 0;

        // If You have rock and the op has scissors
        if (op == 1 && ai_op == 3) win = 1; // you win

        // If the op has rock and you have scissors
        else if (ai_op == 1 && op == 3) win = 2; // the op wins

        // if you have paper and the op has rock
        // or you have scissors and the op has paper
        else if (op > ai_op) win = 1; // you win

        // if the op has paper and you have rock
        // or the op has scissors and you have paper
        else if (ai_op > op) win = 2; // the op wins

        // otherwise it's a draw
        else win = 0;

        // prints:
        // --------------------------------------- //
        std::cout << "\n" << std::string(23, '-') << "\n";

        // check out who won

        // It's a draw on 0
        if (win == 0) std::cout << "It's a Draw.\n";

        // If it's a 1, you won! (hey, that rhymes!)
        else if (win == 1) std::cout << "You won!\n";

        // If it's a 2, you lose.
        else if (win == 2) std::cout << "You lost!\n";

        // error check
        else std::cerr << "There seems to be a problem.\n";

        // prints:
        // --------------------------------------- //
        std::cout << std::string(23, '-') << "\n\n";
    }
}

//////////////////////////////////
// The main entry-point function
//////////////////////////////////
int main()
{
    // all we need is to call the constructor
    pro::Game();

    return 0; // exited successfully
}

// That's all folks!

Here’s the game in action:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s