1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
|
#include <iostream>
#include <string>
#include <conio.h>
#include <ctime>
#include <Windows.h>
using namespace std;
// To use the arrow keys instead of letters
#define UP 72
#define LEFT 75
#define RIGHT 77
#define DOWN 80
int solvedBoard[10][10];
void printBoard(int board[][10], int);
void initializeBoard(int board[][10], int);
void slideTile(int board[][10],int move,int);
bool isBoardSolved(int board[][10],int);
void scrambleBoard(int board[][10],int);
void WaitKey();
int main()
{
int amount=0;
do
{
system("CLS"); // Best NOT to use system calls, but I'll use for now. Find a better solution
// Just to drop request a bit down and over, for looks.
cout << endl << endl << endl << "\t\tHow large of a sliding puzzle, do you want? (3 to 10)";
cout << endl << endl << "\t\t\t\t\t";
cin >> amount;
if(amount <3 || amount > 10)
cout << "\t\t\tSorry, I don't have that size, handy. Try again please!" << endl << endl;
Sleep(1300);
}while (amount <3 || amount > 10);
int gameBoard[10][10];
char input;
string direction;
bool invalid = false;
amount--; // Subtract 1, so checking of array would be from 0 to amount. No need to add -1 to checks
// to keep it in bounds of board
initializeBoard(gameBoard,amount);
printBoard(gameBoard,amount);
cout << boolalpha;
cout<<"isBoardSolved(): "<<isBoardSolved(gameBoard,amount)<<endl;
cout<<"Press enter to begin"<<endl;
WaitKey();
cout<<"Scrambling board..."<<endl;
scrambleBoard(gameBoard, amount);
cout<<"Scrambling complete, press enter to continue"<<endl;
cin.get();
system("CLS");
printBoard(gameBoard,amount);
cout<<endl<<endl;
cout<<"Use arrow keys to move the tiles in the desired direction!"<<endl;
cout<<"Input: ";
while(!isBoardSolved(gameBoard, amount))
{
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(gameBoard,amount);
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;
}
/* Print board and replace zero with a character 177 */
void printBoard(int board[][10], int amt)
{
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 << "\xB1\xB1 ";
}
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);
}
/*Set up board*/
void initializeBoard(int board[][10], int amt)
{
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;
}
}
/*Make a move*/
void 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 isBoardSolved(int board[][10], int amt)
{
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 scrambleBoard(int board[][10], int amt)
{
time_t t;
srand((unsigned) time(&t));
int move;
while(isBoardSolved(board,amt)) //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 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)
}
|