-- FILE: grid2.adb -- AUTHOR: E. Burke -- DATE: November, 1996 -- PURPOSE: Procedures to initialize and display generic grid-box package body GRID2 is -- Set all cells to 'dead' procedure Initialize (Grid_Box : out BOARD) is begin for i in Grid_Box'Range(1) loop for j in Grid_Box'Range(2) loop Grid_Box(i,j) := FALSE; end loop; end loop; end Initialize; -- Ask user for coordinates of cells to be initially 'alive' procedure Input (Grid_box : out BOARD) is subtype INPUT_VALUE is NATURAL range 0..MAX_SIZE; package Number_IO is new Text_IO.Integer_IO(INPUT_VALUE); Index : INPUT_VALUE; Jndex : INPUT_VALUE; begin Text_IO.Put(Item => "On each line give a pair of"); Text_IO.Put(Item => " coordinates for a living cell"); Text_IO.New_Line; Text_IO.Put(Item => "Terminate the list by entering 0"); Text_IO.New_Line; loop -- outer loop continues until 0 is entered to exit begin -- exception-handler block Text_IO.Put(Item => "Row number : "); Number_IO.Get(Item => Index); Text_IO.Put(Item => "Column number: "); Number_IO.Get(Item => Jndex); exit when Index = 0; exit when Jndex = 0; Grid_Box (Index,Jndex) := TRUE; -- process input exception when Text_IO.Data_Error => Text_IO.Put (Item => "Value entered is out of range"); Text_IO.New_line; Text_IO.Skip_line; when Constraint_Error => Text_IO.Put (Item => "Value entered is out of range"); Text_IO.New_line; Text_IO.Skip_line; end; -- end of exception handler block end loop; end Input; -- Display cells procedure Output (Grid_Box : in BOARD) is Line_No : TEXT_IO.POSITIVE_COUNT; Col_No : TEXT_IO.POSITIVE_COUNT; begin TEXT_IO.Put (Item => ASCII.ESC); -- clear screen TEXT_IO.Put (Item => "[2J"); for i in Grid_Box'Range(1) loop for j in Grid_Box'Range(2) loop if Grid_Box(i,j) then Line_No := TEXT_IO.POSITIVE_COUNT(i); Col_No := TEXT_IO.POSITIVE_COUNT(j); TEXT_IO.Set_Line(Line_No); TEXT_IO.Set_Col(Col_No); TEXT_IO.PUT(Item => MARK_TYPE); end if; end loop; TEXT_IO.New_Line; end loop; end Output; -- Change each cell to 'alive' or 'dead' depending on status of -- neighboring cells procedure Update_Box (Grid_Box : in out BOARD) is Newmap : BOARD; begin for i in Grid_Box'Range(1) loop for j in Grid_Box'Range(2) loop case Neighbor_Count(i,j,Grid_Box) is when 0 | 1 | 4 | 5 | 6 | 7 | 8 => Newmap(i,j) := FALSE; when 2 => Newmap(i,j) := Grid_Box(i,j); when 3 => Newmap(i,j) := TRUE; when others => NULL; end case; end loop; end loop; Grid_Box := Newmap; end Update_Box; -- Count number of neighbors of a cell that are alive function Neighbor_Count (I : NATURAL; J : NATURAL; Grid_Box : BOARD) return NATURAL is Count : NATURAL; Xlow : NATURAL; Xhigh : NATURAL; Ylow : NATURAL; Yhigh : NATURAL; begin Xlow := I-1; -- set coordinates of eight neighboring cells Xhigh := I+1; -- of cell I,J Ylow := J-1; Yhigh := J+1; if Xlow < 1 then -- Reset border if cell I,J is at edge of board Xlow := 1; elsif Xhigh > MAX_ROWS then Xhigh := MAX_ROWS; end if; if Ylow < 1 then Ylow := 1; elsif Yhigh > MAX_COLUMNS then Yhigh := MAX_COLUMNS; end if; Count := 0; for X in Xlow..Xhigh loop -- Increment count for each alive neighbor for Y in Ylow..Yhigh loop if Grid_Box(X,Y) then Count := Count + 1; end if; end loop; end loop; if Grid_Box(I,J) = TRUE then -- Exclude target cell from count Count := Count - 1; end if; return Count; end Neighbor_Count; -- Ask user whether to run another or update cycle or terminate function Enquire return BOOLEAN is Run_again : BOOLEAN; Response : CHARACTER; begin while Response /= 'Y' and then Response /= 'y' and then Response /= 'N' and then Response /= 'n' loop Text_IO.Put (Item => "Continue (y / n)"); Text_IO.New_Line; Text_IO.Get (Item => Response); end loop; Run_Again := (Response ='Y') or else (Response = 'y'); return Run_Again; end Enquire; end Grid2;