Introduction In this assignment, you will be writing a C++ command-line program
ID: 3679342 • Letter: I
Question
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 object-oriented programming paradigm.
Assignment
When writing this program, you must design an object that represents the sliding puzzle board. To do this, you must consider the attributes and methods needed by the board to respond to a driver that contains the core logic of the game.
We should begin with a preliminary run-down of the object's features.
Attributes
int SlidingPuzzle::theBoard[3][3];
Description: The primary attribute of the object represents the data on the board. The board array contains the digits 1-8 and the asterisk (*) to represent the open position on the puzzle. When making moves, the data in this array will change to reflect the new state of the board. When the object displays itself on the screen, we will use this array to determine the board's current state.
Methods
SlidingPuzzle::SlidingPuzzle();
Description: This is the constructor method for the object. It will automatically execute once the board has been instantiated in the driver. Upon creation, it would be wise to immediately populate the board with valid values for all of the tiles. You should be able to trigger this with a single call to InitializeBoard().
void SlidingPuzzle::InitializeBoard();
Description: This method will manually populate the board with the game's starting configuration. Initially, the board should look like this:
1 2 3
4 5 6
7 8 *Â Â Â <=== the * represents the blank space on the board
bool SlidingPuzzle::isBoardSolved();
Description: This method examines the board to determine if it is in the solved state. It returns a boolean value reflecting this determination.
bool SlidingPuzzle::slideTile(int);
Description: This method takes a single argument indicating the direction to slide a tile. A good approach would be to set up numerical codes representing the four possible movement directions (UP, DOWN, LEFT, and RIGHT). When the method is called, movement in the indicated direction should take place by exchanging the values in the appropriate tiles. If the move is not possible, the state of the board should remain unchanged. A boolean value should be returned reflecting whether or not the board has been mutated.
void SlidingPuzzle::scrambleBoard();
Description: This method will use the pseudo-random number generator to make an arbitrary number of random moves on the board (I suggest 10,000+ moves to thoroughly confuscate the board). Keep in mind that the seeding of the random number generator should take place in the driver code (not the object's constructor). Also keep in mind that randomly placing the pieces on the board will result in a situation where half of the time the puzzle can be solved and the other half of the time a solution is impossible.
void SlidingPuzzle::PrintBoard();
Description: This method will display the board on the console as a 3x3 grid.  I suggest writing a "quick and dirty" version of this method initially so you can look at the maneuvers as they take place on the board during development. When the core logic of the program is done, you should revisit this method and upgrade it to support console color.
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;
}
}
Screen shots:
Explanation / Answer
#include <iostream>
#include <string>
#include <conio.h>
#include <ctime>
#include <Windows.h>
using namespace std;
//define direction arrows
#define UP 72
#define LEFT 75
#define RIGHT 77
#define DOWN 80
class SlideGame
{
//initializing board
int solvedBoard[10][10];
int gameBoard[10][10];
int amount;
public:
Game(); //
void printBoard();
void initializeBoard();
void slideTile(int move);
bool isBoardSolved();
void scrambleBoard();
}
int main()
{
//declaring variables
       char input;
         string direction;
         bool invalid = false;
         amount=0;
         do
         {
                  system("CLS");
  cout << endl << endl << endl << " How large of a sliding puzzle, do you want? (3 to 10)";
cout << endl << endl << " ";
cin >> amount;
if(amount <3 || amount > 10)
cout << " Sorry, I don't have that size, handy. Try again please!" << endl << endl;
Sleep(1300);
         }while (amount <3 || amount > 10);
amount--; // Subtract 1, so checking of array would be from 0 to amount.
initializeBoard();
printBoard();
cout << boolalpha;
cout<<"isBoardSolved(): "<<isBoardSolved()<<endl;
cout<<"Press enter to begin"<<endl;
WaitKey();
cout<<"Scrambling board..."<<endl;
scrambleBoard();
cout<<"Scrambling complete, press enter to continue"<<endl;
cin.get();
system("CLS");
printBoard();
cout<<endl<<endl;
cout<<"Use arrow keys to move the tiles in the desired direction!"<<endl;
cout<<"Input: ";
//continue the while loop until isBoardSloved() gets true
while(!isBoardSolved())
         {
                  input = _getch();
                  system("CLS");
                  switch(input)
                  {
                  case UP:
                            slideTile(gameBoard,2,amount);
                            direction = "Up";
                            break;
                  case LEFT:
                            slideTile(gameBoard,0,amount);   // move
                            direction = "Left";
                            break;
                  case DOWN:
                            slideTile(gameBoard,3,amount);
                            direction = "Down";
                            break;
                  case RIGHT:
                            slideTile(gameBoard,1,amount);
                            direction = "Right";
                            break;
                  default:
                            invalid = true;
                  }
                  printBoard();
                  cout<<endl<<endl;
                  cout<<"Use arrow keys to move the tiles in the desired direction!"<<endl;
                  if(invalid)
                            invalid = false;
                  else
                            cout<<"Last Input: "<<direction;
         }
         cout << endl;
         cout << "BOARD SOLVED" << endl;
         system("PAUSE");
         return 0;
}
}
//constructor initializes default variables
SlideGame::SlideGame()
{
this. gameBoard[10][10]= gameBoard[10][10];
}
void SlideGame::printBoard()
{
HANDLE hConsole;
         hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
         for(int row = 0; row <= amt; row++)
         {
                  for(int column = 0; column <= amt; column++)
                  {
                            if(board[row][column] == 0)
                            {
                                     SetConsoleTextAttribute(hConsole, 7); //Default color
                                     cout << "±± ";
                            }
                            else
                            {
                                     if(board[row][column] == solvedBoard[row][column])
//If board location is equal to solvedBoard location then set to green
                                               SetConsoleTextAttribute(hConsole, 10);
                                     else
                                               SetConsoleTextAttribute(hConsole, 12); //else, set to red
                                     if (board[row][column]<10) // Print a 0 first if # < 10
                                               cout<<"0";
                                     cout<<board[row][column] << " ";
                            }
                  }
                  cout<<endl;
         }
         SetConsoleTextAttribute(hConsole, 7);
}
void SlideGame::initializeBoard()
{
int i = 1;
         for(int row = 0; row <= amt; row++)
         {
                  for(int column = 0; column <= amt; column++)
                  {
                            board[row][column] = i;
                            solvedBoard[row][column] = i;
                            i++;
                  }
                  board[amt][amt] = 0;
                  solvedBoard[amt][amt] = 0;
         }
}
void SlideGame:: slideTile(int board[][10],int move, int amt
)
{
         int emptyRow;
         int emptyCol;
         bool legalMoves[4] = {1,1,1,1}; //array of legal moves, [0] = left, [1] = right, [2] = up, [3] = down. true (1) indicates a legal move.
         for(int row = 0; row <= amt; row++)
         {
                  for(int column = 0; column <= amt; column++)
                  {
                            if(board[row][column] == 0) //Find location of empty space
                            {
                                     emptyRow = row;
                                     emptyCol = column;
                            }
                  }
         }
         if(emptyRow + 1 > amt) //Can i move up?
                  legalMoves[2] = false; //If no, set move flag to false
         else if(emptyRow - 1 < 0) //Move down?
                  legalMoves[3] = false;
         if(emptyCol - 1 < 0) //Move right?
                  legalMoves[1] = false;
         else if(emptyCol + 1 > amt) //Move left?
                  legalMoves[0] = false;
         switch(move) //Replace zero space with space to the left right up or down.
         {
         case 0:
                  if(legalMoves[move])
                  {
                            board[emptyRow][emptyCol] = board[emptyRow][emptyCol + 1];
                            board[emptyRow][emptyCol + 1] = 0;
                            emptyCol = emptyCol+1;
                  }
                  break;
         case 1:
                  if(legalMoves[move])
                  {
                            board[emptyRow][emptyCol] = board[emptyRow][emptyCol - 1];
                            board[emptyRow][emptyCol- 1] = 0;
                            emptyCol = emptyCol-1;
                  }
                  break;
         case 2:
                  if(legalMoves[move])
                  {
                            board[emptyRow][emptyCol] = board[emptyRow+1][emptyCol];
                            board[emptyRow+1][emptyCol] = 0;
                            emptyRow = emptyRow+1;
                  }
                  break;
         case 3:
                  if(legalMoves[move])
                  {
                            board[emptyRow][emptyCol] = board[emptyRow-1][emptyCol];
                            board[emptyRow-1][emptyCol] = 0;
                            emptyRow = emptyRow-1;
                  }
                  break;
         }
}
bool SlideGame:: isBoardSolved()
{
         bool boardSolved = true;
         int row = 0;
         int col = 0;
         while(boardSolved && row<=amt)
         {
if(solvedBoard[row][col] == board[row][col]) //Compare each index of solved board with game board
                  {
                            col++;
                            if(col == amt)
                            {
                                     row++;
                                     col = 0;
                            }
                  }
                  else //Once a discrepancy is found, set boardSolved to false to break the loop
                            boardSolved = false;
         }
         return boardSolved;
}
void SlideGame:: scrambleBoard()
{
         time_t t;
   srand((unsigned) time(&t));
         int move;
         while(isBoardSolved()) //If the board ends up being solved at the end of the scramble, scramble the board again
         {
                  for(int i = 0; i < 100000;i++) //Series of random moves
                  {
                            move = rand() % 4;
                            slideTile(board,move,amt);
                  }
         }
}
Void SlideGame:: WaitKey()
{
         while (_kbhit()) _getch(); // Empty the input buffer
         _getch(); // Wait for a key
         while (_kbhit()) _getch(); // Empty the input buffer (some keys sends two messages)
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.