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
|
#include <iostream>
#include <fstream>
using namespace std;
struct fieldSpace// rows x cols of these make the field
{
char cnt;// dual use: 'M' if mine or neighboring mine count
bool revealed;
void init( bool mined, char Count=0 )
{
revealed = false;
cnt = mined ? 'M' : Count;
}
};
// core game data
int rows=0, cols=0, mines=0;
fieldSpace** ppField = NULL;
const int y[] = { -1, -1, -1, 1, 1, 1, 0, 0 };// 8 shifts
const int x[] = { -1, 0, 1, -1, 0, 1, -1, 1 };// to neighbors
bool createField( ifstream& is );// dynamic memory allocated
void destroyField();// dynamic memory cleanup
int clearSpace( int r, int c );// Recursive. returns # of spaces cleared
bool isInField( int r, int c );// validate position
int main()
{
ifstream fin("DATA.txt");// input file
if( !fin ) return 1;// bail - no input
else
{
string line;
while(getline(fin,line)) // getline returns false at EOF
{
cout <<line << endl;
}
}
//ofstream fout("field.txt");// output file
//if( !fout ) return 2;// bail - can't save output
if( !createField( fin ) ) return 3;// get party started ( or not )
int r, c;
while( fin >> r >> c )// Game loop
{
--r;
--c;// 1 based in file. 0 based here
int spacesCleared = clearSpace(r,c);// make play
if( ppField[r][c].cnt == 'M' )// write required output to file
cout << "MINE - YOU LOSE\n";
else if( spacesCleared > 1 )
cout << "NO MINE - " << spacesCleared << " SQUARES REVEALED\n";// fill clear triggered
else
cout << "NO MINE - " << ppField[r][c].cnt << " SURROUNDING IT\n";// one space cleared
}
destroyField();// cleanup
return 0;
}
bool createField(ifstream& is )
{
rows = 16;// magic numbers
cols = 30;// not in file
if( is )// stream good?
{
mines = 0;// read in the mine distribution
bool* mineDist = new bool[rows*cols];
for( int i=0; i<rows*cols; ++i )
{
// char chIn; is >> chIn;
char chIn;
if( !(is >> chIn) )
{
delete [] mineDist; // input failure
return false;
}
if( chIn == 'X' )
{
mineDist[i] = true;
++mines;
}
else mineDist[i] = false;
}
// build field
ppField = new fieldSpace*[rows];
for(int r=0; r<rows; ++r)
{
ppField[r] = new fieldSpace[cols];
for(int c=0; c<cols; ++c)
{
if( mineDist[r*cols+c] )
{
ppField[r][c].init( true ); // MINE - noted. next space!
continue;
}
char mineCnt = '0';// find # of neighboring mines
for(int i=0; i<8; ++i)// visit the 8 spaces around it
if( isInField( r+y[i], c+x[i] ) )
if( mineDist[ (r+y[i])*cols + c+x[i] ] ) ++mineCnt;
ppField[r][c].init( false, mineCnt );// NOT a mine
}
}// end for
delete [] mineDist;
return true;
}// end if
return false;
}
void destroyField()
{
// release memory
if( ppField )
{
for(int r=0; r<rows; ++r) delete [] ppField[r];
delete [] ppField;
}
ppField = NULL;// safed off?
}
bool isInField( int r, int c )// validate position
{
if( r < 0 || r >= rows ) return false;
if( c < 0 || c >= cols ) return false;
return true;
}
// Recursive. returns # of spaces cleared
int clearSpace( int r, int c )
{
// base case: space already uncovered
if( ppField[r][c].revealed ) return 0;
ppField[r][c].revealed = true;// clear the space
int numCleared = 1;
// was a space with zero mines around it hit?
if( ppField[r][c].cnt == '0' )// clear the 8 spaces around this space
{
for(int i=0; i<8; ++i)// visit the 8 spaces around it
if( isInField( r+y[i], c+x[i] ) )
numCleared += clearSpace( r+y[i], c+x[i] );// and so on as required
}
return numCleared;
}
|