/** * Assignment #8 * Program to analyze minesweeper board * Author: Mark Allen Weiss * SSN: 000-00-0000 * Course: COP-2210 Section 8 * Date: November 9, 1998 * * CERTIFICATION OF SOLE AUTHORSHIP * I certify that this work is solely my own and * that none if it is the work of any other person. * I further certify that I have not provided any * assistance to other students enrolled in COP-2210 that * would render their CERTIFICATION OF SOLE AUTHORSHIP * invalid. I understand that violations of this pledge * may result in severe sanctions. * * * * ----------------------------------- * (Mark Allen Weiss) <--- Put your name here, and sign above */ #include #include #include "apstring.h" #include "apmatrix.h" const char MINE_SYMBOL = 'o'; const int MINE_VAL = 99; void OpenInput( apstring & infile, ifstream & fin ); void OpenOutput( apstring infile, apstring outfile, ofstream & fout ); void ProcessFile( istream & fin, ostream & fout ); void ComputeMap( const apmatrix & Board, apmatrix & Map ); void PrintMap( ostream & fout, const apmatrix & Map ); int CountMines( const apmatrix & Board, int r, int c ); int Matches( const apmatrix & Board, int row, int col ); int main( ) { apstring infile; // Input file name apstring outfile; // Output file name ifstream fin; // Input file stream ofstream fout; // Output file stream OpenInput( infile, fin ); OpenOutput( infile, outfile, fout ); ProcessFile( fin, fout ); return 0; } /** * Usual stuff; you should copy this. */ void OpenInput( apstring & infile, ifstream & fin ) { for( ; ; ) { cout << "Enter the input file name: "; cin >> infile; fin.open( infile.c_str( ), ios::in | ios::nocreate ); if( !fin ) { cout << "Bad file." << endl; fin.clear( ); } else break; } } /** * Usual stuff. This routine also checks to * make sure that outfile is different from infile. * To avoid this test, call it with infile equal to "". */ void OpenOutput( apstring infile, apstring outfile, ofstream & fout ) { for( ; ; ) { cout << "Enter the output file name: "; cin >> outfile; if( infile == outfile ) { cout << "Input and output files are identical!!" << endl; continue; } fout.open( outfile.c_str( ) ); if( !fout ) { cout << "Bad file." << endl; fout.clear( ); } else break; } } /** * Process the input file and write the map. * Pre: fin and fout are open and ready for reading/writing respectively * fin contains number of rows and cols, respectively on first line. */ void ProcessFile( istream & fin, ostream & fout ) { apmatrix Board; apmatrix Map; int r, c, Rows, Cols; apstring OneLine; fin >> Rows >> Cols; if( Rows <= 0 || Cols <= 0 ) { cout << "Preposterous dimensions read: " << Rows << "x" << Cols << endl; return; } Board.resize( Rows, Cols ); // Read the board for( r = 0; fin >> OneLine && r != Rows; r++ ) { if( OneLine.length( ) != Cols ) { cout << "Row " << r << " has incorrect number of columns" << endl; return; } for( c = 0; c < Cols; c++ ) Board[ r ][ c ] = OneLine[ c ]; } if( r != Rows ) { cout << "Insufficient rows read" << endl; return; } if( !fin.eof( ) ) { cout << "Too many rows in the file" << endl; return; } // Process the board and output the map ComputeMap( Board, Map ); PrintMap( fout, Map ); } /** * Compute the map * Post: Map is resized; each cell contains number of adjacent mines */ void ComputeMap( const apmatrix & Board, apmatrix & Map ) { Map.resize( Board.numrows( ), Board.numcols( ) ); for( int r = 0; r < Board.numrows( ); r++ ) { for( int c = 0; c < Board.numcols( ); c++ ) { Map[ r ][ c ] = CountMines( Board, r, c ); } } } int CountMines( const apmatrix & Board, int r, int c ) { if( Board[ r ][ c ] == MINE_SYMBOL ) return MINE_VAL; else return Matches( Board, r - 1, c - 1 ) + Matches( Board, r - 1, c ) + Matches( Board, r - 1, c + 1 ) + Matches( Board, r + 1, c - 1 ) + Matches( Board, r + 1, c ) + Matches( Board, r + 1, c + 1 ) + Matches( Board, r, c - 1 ) + Matches( Board, r, c + 1 ); } int Matches( const apmatrix & Board, int row, int col ) { if( row >= 0 && col >= 0 && row < Board.numrows( ) && col < Board.numcols( ) && Board[ row ][ col ] == MINE_SYMBOL ) return 1; else return 0; } /** * Print the map (but mines still get o) * Pre: Map is filled in with numbers between 0 and 8 * Post: The Map is output, but mines are still shown */ void PrintMap( ostream & fout, const apmatrix & Map ) { for( int r = 0; r < Map.numrows( ); r++ ) { for( int c = 0; c < Map.numcols( ); c++ ) { if( Map[ r ][ c ] == MINE_VAL ) fout << MINE_SYMBOL; else fout << Map[ r ][ c ]; } fout << endl; } }