Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Sliding Tile Puzzle Simulator (Procedural Paradigm) C++ Introduction In this ass

ID: 3673941 • Letter: S

Question

Sliding Tile Puzzle Simulator (Procedural Paradigm)

C++

Introduction

In this assignment, you will be writing a C++ command-line program that simulates a 3x3 sliding puzzle game. In a sliding puzzle game, 8 tiles with the numerals 1-8 are placed onto a 3x3 square grid. One of the positions is left open for tiles coming from the top, bottom, left, or right (depending on the puzzle configuration). The goal of the game is to slide the tiles around so they appear in order on the puzzle board. When writing this program, you should adhere to the procedural programming paradigm.

Assignment

When completing this program, it would be useful to write a number of functions that perform elementary operations on the board. Once these functions have been written and tested, you can proceed with writing driver control logic that takes the user's input and frames an appropriate call to a function to handle the move.

We should conceptualize the board as a 3x3 two-dimensional array.

int puzzleBoard[3][3];

By writing the following functions, you can create a framework for making moves on the board.

void initializeBoard(int[3][3]);
Description: This function takes the board as a single 3x3 integer array. This function should fill the board with values that represent the tiles on the sliding puzzle. Initially the puzzle should look like this:

1 2 3
4 5 6
7 8 *   <=== the * represents the blank space on the board

void printBoard(int[3][3]);
Description: This function takes the board as its only argument. It displays the board on the screen. Initially, I suggest you write this function to give a quick and dirty display so you can move onto coding the core logic of the program. Later, you can come back and upgrade the function to display grid-work and color (see the hints section to learn how to change the console display color).

bool isBoardSolved(int[3][3]);
Description: This function takes the board and determines if it is in the solved state. The solved state looks exactly like the initialization state where the numbers read in order and the empty tile is in the lower-right corner. After the function determines if the board is in the solved state, a boolean value reflecting this should be returned. Later, your driver code will use this value to determine when the puzzle has been solved. You may want to upgrade your return value to an integer if you decide to have additional reporting codes returned from this function. For example, it would help during design to have a return value that indicates if the board has reached a corrupted state (i.e. there are two 5s on the board, an extra empty space was created, etc...)

void slideTile(int[3][3], int);
Description: This function takes two arguments and will attempt to slide a single tile in a single direction on the board. The first argument is the board. This is needed for obvious reasons. The second argument is a "direction code". I suggest coming up with a number scheme to label to four different directions in which the player can move (UP, DOWN, LEFT, RIGHT). The function will take the move direction and first determine if a tile can be slid in that direction. If the move isn't possible at this time, the board should remain unchanged. However, if the move is possible, you should exchange the values on the faces of the two involved tiles to reflect the move.

void scrambleBoard(int[3][3]);
Description: This function takes a board and makes a series of random moves. Write this function after you have written slideTile() and just have it use a random number generator to send a few thousand random moves at the board from the initialized state.

Hints

The following function demonstrates color printing. You can compile and play with the code to learn the basics of color. Keep in mind that you must include the Windows API in order for this to work.

#include <windows.h>
void printTheRainbow();

void printTheRainbow() {
int currentColor = 7;

// get the handle for the console
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

// exhaustively print the colors
cout << left;
for(currentColor = 0; currentColor <= 255; currentColor++) {
SetConsoleTextAttribute(hConsole, currentColor);
cout << setw(5) << currentColor
<< "Look at the pretty COLORS!" << endl;
}
}

P01 - Screen Shot 1

P01 - Screen Shot 2

P01 - Screen Shot 3

P01 - Screen Shot 4

P01 - Screen Shot 5

P01 - Screen Shot 6

P01 - Screen Shot 7

Explanation / Answer

main.cpp

# include "includes.h"
# include "CSlidingPuzzle.h"

using namespace std;

int
main()
{
  
   CSlidingPuzzle CMyPuzzle;

   while(CMyPuzzle.SetEvent());

  
   return 0;
}


CSlidingPuzzle.h
# include <iostream>
# include <string>
# include <conio.h>
# include <ctype.h>
# include <Windows.h>
# include <stdlib.h>
# include <time.h>
using namespace std;

# ifndef __CSLIDING_PUZZLE__
class //-----------------------------------------------------------------------
CSlidingPuzzle
{
   private:
       // ints
       int blank_y;
       int blank_x;
       int lastEvent;
       // structs
       struct
       ArrowKeys
       {
           int SlideUp, SlideDown, SlideRight, SlideLeft;
       }
       BoardEvent;
       // enums
       enum eventCodes {QUIT = 'q', SCRAMBLE = 32, RESET = 'r', CALIBRATE = 'c'};
       enum keyPress {W = 'w', S = 's', D = 'd', A = 'a'};
       enum directions {UP, DOWN, LEFT, RIGHT};
       enum Colors {WHITE = 15, GREEN = 10, RED = 12, YELLOW = 14} oColor;
       enum boardStuff {ROWS = 3, COLS = 3, BLANK = 0};
       // private methods
       int theBoard[ROWS][COLS];
       void InitializeBoard();
       bool IsBoardSolved();
       void GetBlankLocation();
       bool IsScrambled();
       void ScrambleBoard();
       bool SlideTile(int);
       bool CalibrateBoard(); // credit goes to Miles for the calibration idea
       int GetKeyStroke();

   public:
       // public methods
       CSlidingPuzzle();
       void PrintBoard();
       bool SetEvent();
}; // end CSlidingPuzzle definition
# endif

CSlidingPuzzle.cpp

# include "CSlidingPuzzle.h"

// CTOR // --------------------------------------------------------------------
CSlidingPuzzle::CSlidingPuzzle()
{
   InitializeBoard();
   oColor = WHITE;
   srand(unsigned int (time(NULL)));

   CalibrateBoard();
   system("cls");


} // end CSlidingPuzzle::CSlidingPuzzle()

void // -----------------------------------------------------------------------
CSlidingPuzzle::InitializeBoard()
{
   for(int i = 0; i < ROWS; ++i)
   {
       for(int j = 0; j < COLS; ++j)
       {   // populate the board with numbers 1 to 9 then 0
           theBoard[i][j] = (3 * i + j + 1 ) % 9;
       }
   }
} // end CSlidingPuzzle::InitializeBoard()

bool // -----------------------------------------------------------------------
CSlidingPuzzle::IsBoardSolved()
{
   int solvedElements = 0;
   for(int i = 0; i < ROWS; ++i)
   {
       for(int j = 0; j < COLS; ++j)
       {   // tally correctly positioned elements
           if(theBoard[i][j] == (3 * i + j + 1 ) % 9)
               ++solvedElements;
       }
   }
   // compare tally to number of elements
   if(solvedElements == ROWS * COLS)
       return true;
   else
       return false;
} // end CSlidingPuzzle::IsBoardSolved()

void // -----------------------------------------------------------------------
CSlidingPuzzle::GetBlankLocation()
{
   for(int i = 0; i < COLS; ++i)
    {
        for(int j = 0; j < ROWS; ++j)
        {
            if(theBoard[i][j] == BLANK)
            {
                blank_x = j;
                blank_y = i;
                break;
            }
        }
    }
} // end CSlidingPuzzle::GetBlankLocation()

bool // -----------------------------------------------------------------------
CSlidingPuzzle::IsScrambled()
{
   for(int i = 0; i < ROWS; ++i)
    {
        for(int j = 0; j < COLS; ++j)
        {
           // if a piece is in correct position, then board not scrambled
            if(theBoard[i][j] == (3 * i + j + 1 ) % 9)
                return false;
        }
    }
   // if we've made it this far without returning, then board is scrambled
   return true;

}
void // -----------------------------------------------------------------------
CSlidingPuzzle::ScrambleBoard()
{
   InitializeBoard();
   do // a series of random moves to create solvable and scrambled board
   {
       SlideTile(rand() % 4);

   }
   while( !(IsScrambled()) );
} // end ScrambleBoard()


bool // -----------------------------------------------------------------------
CSlidingPuzzle::SlideTile(int direction)
{

   GetBlankLocation();


   // slide tiles if movement key is pressed
    if(direction == UP && blank_y < ROWS - 1)
    {
        theBoard[blank_y][blank_x] = theBoard[blank_y + 1][blank_x];
        theBoard[blank_y + 1][blank_x] = BLANK;
    }
    else if(direction == DOWN && blank_y > 0)
    {
        theBoard[blank_y][blank_x] = theBoard[blank_y - 1][blank_x];
        theBoard[blank_y - 1][blank_x] = BLANK;
    }
    else if(direction == RIGHT && blank_x > 0)
    {
        theBoard[blank_y][blank_x] = theBoard[blank_y][blank_x - 1];
        theBoard[blank_y][blank_x - 1] = BLANK;
    }
    else if(direction == LEFT && blank_x < COLS - 1)
    {
        theBoard[blank_y][blank_x] = theBoard[blank_y][blank_x + 1];
        theBoard[blank_y][blank_x + 1] = BLANK;
    }
    else
    {
        return false;
    }
    return true;
} // end SlideTile()

bool // -----------------------------------------------------------------------
CSlidingPuzzle::SetEvent()
{
   PrintBoard();
   int keyStroke = GetKeyStroke();
   cout << keyStroke << endl;
  
   system("cls");
   if(keyStroke == BoardEvent.SlideUp || keyStroke == W)
   {   // take appropriate action
       SlideTile(UP);
   }
   else if(keyStroke == BoardEvent.SlideDown || keyStroke == S)
   {   // take appropriate action
       SlideTile(DOWN);
   }
   else if(keyStroke == BoardEvent.SlideRight || keyStroke == D)
   {   // take appropriate action
       SlideTile(RIGHT);
   }
   else if(keyStroke == BoardEvent.SlideLeft || keyStroke == A)
   {   // take appropriate action
       SlideTile(LEFT);
   }
   else if(keyStroke == QUIT)
   {   // take appropriate action
       return false;
   }
   else if(keyStroke == SCRAMBLE)
   {   // take appropriate action
       ScrambleBoard();
   }
   else if(keyStroke == RESET)
   {   // take appropriate action
       InitializeBoard();
   }
   else if(keyStroke == CALIBRATE)
   {   // credit goes to Miles for calibration idea
       CalibrateBoard();
   }
   return true;
}

void // -----------------------------------------------------------------------
CSlidingPuzzle::PrintBoard()
{
   bool boardSolved = IsBoardSolved();
   int puzzleColor;
   // used to create dynamic UI)
    string UIStrings[ROWS] = {" | | Up:    W          ^",
                              " | | Down: S          |",
                              " | | Left: A       A<--->D"};
    string solutionMessage[2] = {" Not     ", "         "};
   // get the handle for the console
   HANDLE hConsole;
   hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

   // set the puzzle color based on board state
   if(boardSolved)
       puzzleColor = GREEN;
   else
       puzzleColor = RED;

   SetConsoleTextAttribute(hConsole, WHITE);
   // begin to print user interface
   cout << "========================================" << endl
           << "        Realtime Sliding Puzzle         " << endl
               << "========================================" << endl
                   << " Puzzle   | Direction Keys:"             << endl
                       << "+-------+ |                    W"         << endl;
   // print sliding puzzle pieces
    for(int i = 0; i < ROWS; ++i)
    {
        cout << "|";
        for(int j = 0; j < COLS; ++j)
        {
            if(theBoard[i][j] == 0)
           {
                cout << " ";
           }
            else
           {   // if the board is solved, but position correct, then...
               if(!(boardSolved) && theBoard[i][j] == (3 * i + j + 1 ) % 9)
               {   // display pieces in yellow
                   SetConsoleTextAttribute(hConsole, YELLOW);
               }
               else
               {   // otherwise just use the predetermined puzzle color
                   SetConsoleTextAttribute(hConsole, puzzleColor);
               }
                cout << " " << theBoard[i][j];
               SetConsoleTextAttribute(hConsole, WHITE);
           }
        }
        cout << UIStrings[i] << endl;
    }
   // continue to print user interface
    cout << "+-------+ | Right: D          |"   << endl
           << solutionMessage[boardSolved]
               << " |                    v"           << endl
                   << " Solved. | Quit: Q          S"   << endl;
   cout << "          | Calibrate: C"                   << endl
           << "          | Reset: R"                       << endl
               << "          | Scramble: spacebar"           << endl
                   << "----------+-----------------------------"    << endl;
   cout << "To slide the puzzle pieces, press a"      << endl
           << "    direction key from the list above."    << endl
               << "To scramble the tiles, press the space"    << endl
                   << "    bar. Press Q to quit."                 << endl;
                           // end UI code
} // end PrintBoard()

bool // -----------------------------------------------------------------------
CSlidingPuzzle::CalibrateBoard()
{   // credit goes to Miles for the idea of calibration screen
   cout << "Please press your up arrow key. ";
   BoardEvent.SlideUp = GetKeyStroke();
   cout << "Please press your down arrow key. ";
   BoardEvent.SlideDown = GetKeyStroke();
   cout << "Please press your right arrow key. ";
   BoardEvent.SlideRight = GetKeyStroke();
   cout << "Please press your left arrow key. ";
   BoardEvent.SlideLeft = GetKeyStroke();
   system("cls");

   return 0;
}

int // ------------------------------------------------------------------------
CSlidingPuzzle::GetKeyStroke()
{
   int keyPress;
   keyPress = getch();
   if(!(keyPress) || keyPress == 224)
       keyPress = getch();

   return tolower(keyPress);
} // end GetKeyStroke()

include.h
# pragma once
# include <iostream>
# include <string>
# include <conio.h>
# include <ctype.h>
# include <Windows.h>
# include <stdlib.h>
# include <time.h>

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote