-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpuzzle15.cpp
More file actions
155 lines (132 loc) · 3.27 KB
/
puzzle15.cpp
File metadata and controls
155 lines (132 loc) · 3.27 KB
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
//******************************************************
// File: puzzle15.cpp
// Description: 15-Tile Puzzle Game
// Author: CS 103
// Notes: To move a tile you should just type the number
// of the tile. Also the blank tile is represented
// by the value 0
//******************************************************
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
// Prototypes
void shuffle(int [], int);
bool isSolved(int []);
void printBoard(int []);
bool checkAndMove(int [], int);
const int DIM = 4;
int main()
{
int tiles[DIM*DIM];
int tileToMove;
int numMoves;
// Seed random number generator
srand(time(0));
// Initialize the board then permute it
for(int i=0; i < DIM*DIM; i++){
tiles[i] = i;
}
// Ask user for number of scrambling moves
cout << "How many scrambling moves should be attempted: ";
cin >> numMoves;
// Scramble the tiles
shuffle(tiles, numMoves);
// Primary gameplay loop
while ( !isSolved(tiles) ){
printBoard(tiles);
// Get a selection from the user
cout << "\n\nEnter a tile to move: ";
cin >> tileToMove;
cout << endl;
if( ! checkAndMove(tiles, tileToMove) ){
cout << "Invalid tile to move" << endl;
}
}
cout << "You win!!" << endl;
return 0;
}
// Permute the tiles -- this is a really bad
// way of initializing because we'll just
// randomly guess a tile and try to move it
// but if it's not next to the blank tile
// it will not do anything
void shuffle(int tiles[], int numMoves)
{
for(int i=0; i < numMoves; i++){
// what range of values could be produced
// by 1 + rand()%(DIM*DIM-1)
int tileToMove = 1+rand()%(DIM*DIM-1);
checkAndMove(tiles, tileToMove);
}
}
// Check if the game is solved
bool isSolved(int tiles[]) {
for (int i=0; i < DIM*DIM; i++) {
if (tiles[i] == i) {
continue;
}
else {
return false;
}
}
return true;
}
// Print the tile values in a DIMxDIM grid
// with 3-spaces per column
void printBoard(int tiles[]) {
for (int row=0; row < DIM; row++) {
for (int col=0; col < DIM; col++) {
cout << setw(3) << tiles[row*DIM+col];
}
cout << endl;
}
}
// returns true is move was able to be completed
// successfully, false otherwise
bool checkAndMove(int tiles[], int tileVal)
{
int tileIdx = -1;
int blankIdx = -1;
bool valid = false;
// Do sanity check
if(tileVal >= DIM*DIM || tileVal < 0){
return false;
}
// Find the given index of the given tile value
// and blank tile
for(int i=0; i < DIM*DIM; i++){
if(tiles[i] == tileVal){
tileIdx = i;
}
if(tiles[i] == 0){
blankIdx = i;
}
}
// Check if the blank and specified tile are
// next to each other
// Check up
if(tileIdx - DIM >= 0 && (tileIdx - DIM) == blankIdx){
valid = true;
}
// Check down
else if(tileIdx + DIM < (DIM*DIM) && (tileIdx + DIM) == blankIdx){
valid = true;
}
// Check right
else if( (tileIdx % DIM) != (DIM-1) && (tileIdx + 1) == blankIdx){
valid = true;
}
// Check left
else if( (tileIdx % DIM) != 0 && (tileIdx - 1) == blankIdx){
valid = true;
}
// Move the tile if valid
if(valid){
tiles[tileIdx] = tiles[blankIdx];
tiles[blankIdx] = tileVal;
}
// Return our status
return valid;
}