PROGRAM Stars (Input,Output);

(* Problem 6, Chapter 13, Pascal by Dale & Weems
CMIS 150
SHAPE  Term 5  1991
David Wills
Turbo Pascal 5.5   *)

CONST
   MaxRows = 20;         (* Screenful of stars *)
   MaxColumns = 80;
   MaxIntensity = 20;    (* Maximum data intensity level *)
   Blank = ' ';
   Threshold = 6.0;      (* "Visibility" threshold *)

TYPE
   NumberRows = 1..MaxRows;
   NumberColumns = 1..MaxColumns;
   Intensity = 0..MaxIntensity;
   RawArray = ARRAY [NumberRows,NumberColumns] OF Intensity;
   StarArray = ARRAY [NumberRows,NumberColumns] OF Char;

VAR
   RawDataArray : RawArray;    (* Raw image data *)
   StarMap : StarArray;        (* Probable star locations *)
   Rows : NumberRows;          (* Row dimension of raw input data *)
   Columns : NumberColumns;    (* Column dimension of raw input data *)





(**********************************************************
Input the raw data from user or redirected file.
First datum is number of rows (<= MaxRows) in data.
Second datum is number of columns (<= MaxColumns) in data.
Intensity data follows, one datum per line of input. *)

PROCEDURE GetRawData (Var RawData : RawArray;
                      Var RowSize : NumberRows;
                      Var ColumnSize : NumberColumns);
Var
   Datum : Intensity;
   I : NumberRows;
   J : NumberColumns;

(* Input number of rows and number of columns of raw data. *)
PROCEDURE GetSizes (Var Rows : NumberRows;
                    Var Columns : NumberColumns);
Begin  (* GetSizes *)
   Write('Enter number of rows: ');
   Readln(Rows);
   Write('Enter number of columns: ');
   Readln(Columns);
End;  (* GetSizes *)

Begin  (* GetRawData *)
   GetSizes(RowSize,ColumnSize);
   FOR I := 1 TO RowSize DO
     Begin
       Writeln('Row ',i,': ');      (* Prompt for row's data *)
       FOR J := 1 TO ColumnSize DO  (* Input row's data, column by column *)
         Begin
           Read(Datum);
           IF Datum > MaxIntensity THEN  (* Reset datum > maximum value to *)
              Datum := MaxIntensity;     (* maximum value.*)
           RawData[I,J] := Datum;
         End;
       Readln;
     End;
End;   (* GetRawData *)




(*****************************************************************)
(* Initialize star map to blanks *)

PROCEDURE InitStarMap (Var StarMap : StarArray;
                       RowSize : NumberRows;
                       ColumnSize : NumberColumns);
Var
   I : NumberRows;
   J : NumberColumns;
Begin
   FOR I := 1 TO RowSize DO
      FOR J := 1 TO ColumnSize DO
         StarMap[I,J] := Blank;
End;





(***************************************************************
Search raw data for elements whose intensity averaged with its
north, south, east and west neighbors is larger than a threshold. *)

PROCEDURE StarSearch (Raw : RawArray;
                      Var StarMap : StarArray;
                      RowSize : NumberRows;
                      ColumnSize : NumberColumns);
Var
   I : NumberRows;
   J : NumberColumns;


(* Find sum of raw data element and its four cardinal neighbors *)

FUNCTION Sum (A : RawArray; R : NumberRows; C : NumberColumns) : Integer;
Begin
   Sum := A[R,C] + A[R,C-1] + A[R,C+1] + A[R-1,C] + A[R+1,C];
End;


Begin   (* StarSearch *)
   FOR I := 2 TO RowSize-1 DO      (* All rows except first and last *)
      FOR J := 2 TO ColumnSize-1 DO  (* All columns except first and last *)
         (* if average of element and its 4 neighbors > threshold *)
         IF (Sum(Raw,I,J) / 5) > Threshold THEN
            StarMap[I,J] := '*';      (* then say found a star *)
End;    (* StarSearch *)




(*************************************************************
Display the probable star map *)

PROCEDURE DisplayStars (StarMap : StarArray;
                        RowSize : NumberRows;
                        ColumnSize : NumberColumns);
Var
   I : NumberRows;
   J : NumberColumns;
Begin
   Write(' ');
   FOR J := 1 TO ColumnSize DO     (* Border on top *)
      Write('-');
   Writeln;

   FOR I := 1 TO RowSize DO
    Begin
      Write('|');      (* Left border *)
      FOR J := 1 TO ColumnSize DO
         Write(StarMap[I,J]);      (* Blank or astersisk *)
      Writeln;
    End;
End;




BEGIN  (* Stars *)

      GetRawData(RawDataArray,Rows,Columns);

      InitStarMap(StarMap,Rows,Columns);

      StarSearch(RawDataArray,StarMap,Rows,Columns);

      DisplayStars(StarMap,Rows,Columns);

END.   (* Stars *)
