I am new with Ada programming. I am trying to generate a 80 column and 40 rows table, each case is randomly filled with either M or V. Any help with how to create this kind of table would be much appreciated !
Here's what I have so far for the table in .ads :
package Life is
type Grid is (mort, vivant);
type TableauCell is array ( 0..80, 0..40 ) of Grid;
procedure Grid_Random_Fill(A : in out Grid);
end Life;
and the randomization:
with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Numerics.Discrete_Random ;
use Ada.Text_IO, Ada.Integer_Text_IO;
package body Life is
procedure Grid_Random_Fill is
type Life is (V, M);
package Random_Life is new Ada.Numerics.Discrete_Random (Life) ;
use Random_Life ;
G : Generator ;
begin
Reset (G) ; -- intialise the generator
loop
Case Random(G) is
when V =>
put("V"); -- put V in table
when M =>
put("M"); -- put M in table
end case;
end loop ;
end Grid_Random_Fill;
end life;
Unfortunately I can't get it to compile - and I don't see how I can automatically generate M and V into my table. I'm not sure I was clear, I'm all new to coding.
Since this has the feel of homework, how about an overly-complex, overly-generalized example? Everything works, except the randomization, which is an exercise left to the reader.
Test_Table.adb
With
Tabling,
Ada.Streams.Stream_IO,
Ada.Text_IO.Text_Streams;
Use
Ada.Text_IO;
Procedure Test_Table is
-- Here we declare a stream and associate it with the standard-output,
-- this can easily be altered to any file. Yay streams!
Output : Access Ada.Streams.Root_Stream_Type:=
Ada.Text_IO.Text_Streams.Stream( Standard_Output );
Package test is new Tabling( Rows => 40, Cols => 80 );
temp : test.Table;
Begin
-- A single line to write the table.
Test.Table'Write( Output, temp );
New_Line;
End Test_Tables;
Now isn't that nice and simple? Well, here's the over-complex & over-generalized part: the specification and implementation!
Tabling.ads
Pragma Ada_2012;
With Ada.Streams;
Generic
Rows : Positive := 3;
Cols : Positive := 4;
Package Tabling is
-- Tables with rows or columns exceeding 200 are absurd, so we disallow them.
Maximum : constant:= 200;
Pragma Assert (Rows <= Maximum and Cols <= Maximum);
-- Table is a private entity.
Type Table is private;
-- Forward declaring the rows and columns here.
Type Col is private;
Type Row is private;
Private
Use Ada.Streams;
-- We are defining a type with elements of 'V' or 'M'.
Type Element_Type is ( 'M', 'V' );
-- We are declaring a stream writing function.
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Element_Type);
-- We are overriding the default write function with the one we defined.
For Element_Type'Write use Write;
-- Because we don't want an allocation wrror we restrict index-ranges to
-- a more reasonable value.
SubType Short_Positive is Positive Range Positive'First..Maximum;
-- We create subtypes representing the ranges that Rows or Columns take.
subtype column_index is Short_Positive Range Positive'First..Cols;
subtype row_index is Short_Positive Range Positive'First..Rows;
-- Here we define stream-writing functions for rows and columns.
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Col);
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Row);
-- Here we override the stream-writing methods for rows and columns.
For Col'Write Use Write;
For Row'Write Use Write;
-- Here we finally define Rows and Columns.
Type Col is Array(column_index)of Element_Type;
Type Row is Array( row_index ) of Col;
-- THIS IS A STUB, SUBSTITUTED FOR YOUR CALL TO RANDOM.
Function RANDOM_CALL Return Element_Type is ( 'M' );
-- Finally we define the stream-writing for a table...
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Table);
-- and define what a table is...
Type Table is record
Data : Row:= ( others => (others => RANDOM_CALL) );
end record;
-- finishing off by assigning our write function to the type.
For Table'Write Use Write;
End Tabling;
Tabling.adb
package body Tabling is
-- Quick definition of the new-line, windows-style.
New_Line : Constant String:= ASCII.CR & ASCII.LF;
-- Implementations of our stream writing functions.
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Element_Type) is
-- Convert takes the element-type and transforms it into a character.
Function Convert (Input : Element_Type:= Item) Return Character is
begin
-- A simple mapping using case, it also has the advantage of raising
-- a compiler error should the valuse "Element_Type" can take change.
case Input is
when 'M' => return 'm';
when 'V' => return 'v';
end case;
end Convert;
begin
Character'Write( Stream, Convert );
end Write;
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Col) is
begin
-- Using the new-style for-loop, we iterate over the given columns,
-- taking care to wrap the elements in the table's cell-definition tag.
for Element of Item loop
String'Write( Stream, ASCII.HT & "<td>" );
Element_Type'Write( Stream, Element );
String'Write( Stream, "</td>" & New_Line );
end loop;
end Write;
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Row) is
begin
-- Using the new-style loop, we iterate through the row, wrapping each
-- in the table-row tag, <tr>.
for Element of Item loop
String'Write( Stream, "<tr>" & New_Line);
col'Write( Stream, Element );
String'Write( Stream, "</tr>" & New_Line);
end loop;
end Write;
Procedure Write(
Stream : access Root_Stream_Type'Class;
Item : in Table) is
begin
-- Start the table.
String'Write(Stream, "<Table>" & New_Line);
-- Write out the rows.
Row'Write (Stream, Item.Data );
-- End the table.
String'Write(Stream, "</Table>");
end Write;
End Tabling;