RosettaCodeData/Task/Forest-fire/Ada/forest-fire.ada

70 lines
2.4 KiB
Ada

with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
with Ada.Text_IO; use Ada.Text_IO;
procedure Forest_Fire is
type Cell is (Empty, Tree, Fire);
type Board is array (Positive range <>, Positive range <>) of Cell;
procedure Step (S : in out Board; P, F : Float; Dice : Generator) is
function "+" (Left : Boolean; Right : Cell) return Boolean is
begin
return Left or else Right = Fire;
end "+";
function "+" (Left, Right : Cell) return Boolean is
begin
return Left = Fire or else Right = Fire;
end "+";
Above : array (S'Range (2)) of Cell := (others => Empty);
Left_Up, Up, Left : Cell;
begin
for Row in S'First (1) + 1..S'Last (1) - 1 loop
Left_Up := Empty;
Up := Empty;
Left := Empty;
for Column in S'First (2) + 1..S'Last (2) - 1 loop
Left_Up := Up;
Up := Above (Column);
Above (Column) := S (Row, Column);
case S (Row, Column) is
when Empty =>
if Random (Dice) < P then
S (Row, Column) := Tree;
end if;
when Tree =>
if Left_Up + Up + Above (Column + 1) +
Left + S (Row, Column) + S (Row, Column + 1) +
S (Row + 1, Column - 1) + S (Row + 1, Column) + S (Row + 1, Column + 1)
or else Random (Dice) < F then
S (Row, Column) := Fire;
end if;
when Fire =>
S (Row, Column) := Empty;
end case;
Left := Above (Column);
end loop;
end loop;
end Step;
procedure Put (S : Board) is
begin
for Row in S'First (1) + 1..S'Last (1) - 1 loop
for Column in S'First (2) + 1..S'Last (2) - 1 loop
case S (Row, Column) is
when Empty => Put (' ');
when Tree => Put ('Y');
when Fire => Put ('#');
end case;
end loop;
New_Line;
end loop;
end Put;
Dice : Generator;
Forest : Board := (1..10 => (1..40 => Empty));
begin
Reset (Dice);
for I in 1..10 loop
Step (Forest, 0.3, 0.1, Dice);
Put_Line ("-------------" & Integer'Image (I) & " -------------");
Put (Forest);
end loop;
end Forest_Fire;