Search code examples
randomadatabular

Generate a table with random elements


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.


Solution

  • 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;