/*	Depth-First Search program for finding colonies */

#include <fstream.h>
#include <iostream.h>
#include <matrix.h>
#include <lvpstring.h>

using namespace std;	// October 5, 2001

class SlideClass {
public:
	SlideClass();
	void LoadSlide(const lvpstring &FileName);
	void DisplaySlide() const;
	void DisplayColonies();

private:
	matrix<char> S;
	int CollectCells(int Row, int Col);
	const char Colony, NonColony;
};
//--------------------------------------------------------------------------------
SlideClass::SlideClass():
	Colony('*'), NonColony('-')
{
}
//--------------------------------------------------------------------------------
int SlideClass::CollectCells(int Row, int Col)
/*	Post: All Colony cells adjoining and including cell (Row,Col) have 
	been changed to NonColony, and count of these cells is returned. */
{
	if ((Row<0) || (Row>=S.numrows()) || (Col<0) || (Col>=S.numcols())
		|| (S[Row][Col] != Colony))
		return(0);
	else {
			S[Row][Col] = NonColony;
   		return(1+
					CollectCells(Row+1,Col)+
					CollectCells(Row-1,Col)+
					CollectCells(Row,Col+1)+
					CollectCells(Row,Col-1));
	}
}
//--------------------------------------------------------------------------------
void SlideClass::DisplayColonies()
/*	Post: Displays a list of the colonies on the slide S, giving
	coordinates of a point in each colony and its size           */
{
	// Make copy since CollectCells destroys matrix
	matrix<char> Temp = S;
 
	for (int Row = 0; Row < S.numrows(); Row++)
   		for (int Col = 0; Col < S.numcols(); Col++) {
     			if (S[Row][Col] == Colony) {
       		 		int Count = CollectCells(Row,Col);
        				cout << "Colony at (" << Row << "," << Col << ") with size " 
					<< Count << endl;
			}
		}
	S = Temp; // Restore matrix 
}
//--------------------------------------------------------------------------------
void SlideClass::LoadSlide(const lvpstring &FileName)
/*	Pre: File FileName exists and is formatted as:
		First line: length of slide
		Second line: width of slide
		Remaining lines: characters representing cells.
	Post: S loaded from file                                         */
{
	ifstream SlideData(FileName.c_str());
	int Length;
	int Width;
	SlideData >> Length;
	SlideData >> Width;
	S.resize(Length, Width);
	for (int Row = 0; Row < Length; Row++) {
		for (int Col = 0; Col < Width; Col++)
			SlideData >> S[Row][Col];
		}
}
//--------------------------------------------------------------------------------
void SlideClass::DisplaySlide() const
/*	Post: Contents of the slide displayed in a compact format */
{
	for (int Row = 0; Row<S.numrows(); Row++) {
		for (int Col=0; Col<S.numcols(); Col++) {
			cout << S[Row][Col];
		}
		cout << endl;
	}
}
//--------------------------------------------------------------------------------
int main()
{
	SlideClass S;
	S.LoadSlide("slide.dat");
	S.DisplaySlide();
	S.DisplayColonies();
	return(0);
}

