home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_show / spread_illness.e < prev   
Text File  |  1999-06-05  |  10KB  |  343 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. --
  17. -- Originally written by Cyril ADRIAN and Antony LE LABOUSSE
  18. --
  19. class SPREAD_ILLNESS
  20.    -- To compile type command : compile SPREAD_ILLNESS make
  21.    --
  22.    -- Also try Optimised version adding options "-boost -O2"
  23.    --
  24. creation {ANY}
  25.    make
  26.  
  27. feature {NONE}
  28.  
  29.    world1, world2: ARRAY2[INTEGER];
  30.  
  31.    empty : INTEGER is 1;
  32.  
  33.    healthy : INTEGER is 0;
  34.  
  35.    di: ARRAY[INTEGER] is
  36.       once
  37.          Result := <<-1,-1,-1,0,1,1,1,0 >>
  38.       end;
  39.  
  40.    dj: ARRAY[INTEGER] is
  41.       once
  42.          Result := <<-1,0,1,1,1,0,-1,-1 >>
  43.       end;
  44.  
  45.    error_msg : STRING is "Error : do it again !%N"
  46.  
  47. feature {ANY}
  48.  
  49.    make is
  50.          -- Try to spreads an illness through a set of people.
  51.       local
  52.          day: INTEGER;
  53.          fed_up: BOOLEAN;
  54.       do
  55.          from
  56.             day := 1;
  57.             first_day;
  58.          until
  59.             fed_up
  60.          loop
  61.             io.put_string("Day #");
  62.             io.put_integer(day);
  63.             io.put_new_line;
  64.             display;
  65.             io.put_string("Continue ? [y/n] ");
  66.             io.flush;
  67.             io.read_line;
  68.             io.last_string.to_lower;
  69.             fed_up := (io.last_string.first = 'n')
  70.             day := day + 1;
  71.             next_day
  72.          end;
  73.       end;
  74.  
  75. feature {ANY}
  76.  
  77.    first_day is
  78.          -- Create the world in the 1st day's state.
  79.       local
  80.          i, j, ill_state: INTEGER;
  81.          ok: BOOLEAN;
  82.       do
  83.          io.put_string("Default First World (y/n) ? ");
  84.          io.flush;
  85.          io.read_word;
  86.          if io.last_string.is_equal("y") then
  87.             !!world1.from_model(
  88.               <<<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  89.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  90.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  91.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  92.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  93.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  94.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  95.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  96.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1>>,
  97.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  98.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  99.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  100.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  101.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  102.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  103.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  104.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
  105.                 <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>>>);
  106.          else
  107.             io.put_string("World size : ");
  108.             io.flush;
  109.             io.read_integer;
  110.             !!world1.make(1,io.last_integer,1,io.last_integer);
  111.             io.put_string("%Ne)mpty, i)ll with number of days, h)ealthy%N%N");
  112.             from
  113.                i := world1.lower1
  114.             until
  115.                i > world1.upper1
  116.             loop
  117.                from
  118.                   j := world1.lower2
  119.                until
  120.                   j > world1.upper2
  121.                loop
  122.                   from
  123.                      ok := false;
  124.                   until
  125.                      ok
  126.                   loop
  127.                      io.put_string("State of [");
  128.                      io.put_integer(i);
  129.                      io.put_character(',');
  130.                      io.put_integer(j);
  131.                      io.put_string("] : ");
  132.                      io.flush;
  133.                      io.read_word;
  134.                      inspect
  135.                         io.last_string.first
  136.                      when 'E','e' then
  137.                         if io.last_string.count /= 1 then
  138.                            io.put_string(error_msg)
  139.                         else
  140.                            world1.put(empty,i,j);
  141.                            ok := true
  142.                         end
  143.                      when 'H','h' then
  144.                         if io.last_string.count /= 1 then
  145.                            io.put_string(error_msg)
  146.                         else
  147.                            world1.put(healthy,i,j);
  148.                            ok := true
  149.                         end
  150.                      when 'I','i' then
  151.                         ok := true;
  152.                         io.flush;
  153.                         io.read_integer;
  154.                         ill_state := io.last_integer;
  155.                         ill_state := ill_state.max(1);
  156.                         ill_state := ill_state.min(4);
  157.                         world1.put(- ill_state,i,j);
  158.                      else
  159.                         io.put_string(error_msg)
  160.                      end;
  161.                   end;
  162.                   j := j + 1;
  163.                end;
  164.                i := i + 1;
  165.             end;
  166.          end;
  167.          world2 := clone(world1)
  168.       end;
  169.  
  170.    display is
  171.          -- Displays current `world2'.
  172.       local
  173.          i,j : INTEGER;
  174.       do
  175.          io.put_character('+');
  176.          io.put_character('-');
  177.          from
  178.             i := world1.lower1
  179.          until
  180.             i > world1.upper1
  181.          loop
  182.             io.put_character('-');
  183.             io.put_character('-');
  184.             i := i+1
  185.          end;
  186.          io.put_character('+');
  187.          io.put_new_line;
  188.          from
  189.             i := world1.lower1
  190.          until
  191.             i > world1.upper1
  192.          loop
  193.             io.put_character('|');
  194.             io.put_character(' ');
  195.             from
  196.                j := world1.lower2
  197.             until
  198.                j > world1.upper2
  199.             loop
  200.                inspect
  201.                   world2.item(i,j)
  202.                when empty then
  203.                   io.put_character(' ')
  204.                when healthy then
  205.                   io.put_character('O')
  206.                else
  207.                   io.put_character((- world2.item(i,j)).digit)
  208.                end;
  209.                io.put_character(' ');
  210.                j := j+1
  211.             end;
  212.             io.put_character('|');
  213.             io.put_new_line;
  214.             i := i+1
  215.          end;
  216.          io.put_character('+');
  217.          io.put_character('-');
  218.          from
  219.             i := world1.lower1
  220.          until
  221.             i > world1.upper1
  222.          loop
  223.             io.put_character('-');
  224.             io.put_character('-');
  225.             i := i+1
  226.          end;
  227.          io.put_character('+');
  228.          io.put_new_line;
  229.       end;
  230.  
  231.    next_day is
  232.          -- `world1' and `world2' are swapped.
  233.       local
  234.          i,j: INTEGER;
  235.       do
  236.          world1.copy(world2);
  237.          from
  238.             i := world1.lower1;
  239.          until
  240.             i > world1.upper1
  241.          loop
  242.             from
  243.                j := world1.lower2;
  244.             until
  245.                j > world1.upper2
  246.             loop
  247.                inspect
  248.                   world1.item(i,j)
  249.                when empty then
  250.                when healthy then
  251.                   spread(i,j);
  252.                else
  253.                   cure_or_die(i,j);
  254.                end;
  255.                j := j + 1;
  256.             end;
  257.             i := i + 1;
  258.          end;
  259.       end;
  260.  
  261. feature {NONE}
  262.  
  263.    cure_or_die(i,j : INTEGER)  is
  264.          -- When ill, inspects if must be death or more ill or cured.
  265.       do
  266.          inspect
  267.             - world1.item(i,j)
  268.          when 1 then
  269.             world2.put(-2,i,j)
  270.          when 2 then
  271.             die(i,j)
  272.          when 3 then
  273.             world2.put(-4,i,j)
  274.          when 4 then
  275.             world2.put(healthy,i,j)
  276.          end
  277.       end;
  278.  
  279.    die(i,j: INTEGER) is
  280.          -- When two days ill, dies or more ill ?
  281.       local
  282.          d,k:INTEGER;
  283.       do
  284.          from
  285.             d := 1;
  286.          variant
  287.             9 - d
  288.          until
  289.             d > 8
  290.          loop
  291.             if v(i+di.item(d),j+dj.item(d)) <= -2 then
  292.                k := k+1;
  293.             end;
  294.             d := d+1;
  295.          end;
  296.          if k >= 4 then
  297.             world2.put(empty,i,j);
  298.          else
  299.             world2.put(-3,i,j);
  300.          end
  301.       end;
  302.  
  303.    spread(i,j: INTEGER) is
  304.          -- spread the illness ?
  305.       local
  306.          d: INTEGER;
  307.       do
  308.          from
  309.             d := 1;
  310.          variant
  311.             10 - d
  312.          until
  313.             d = 9
  314.          loop
  315.             if ill(i + di @ d , j + dj @ d) then
  316.                world2.put(-1,i,j);
  317.                d := 9;
  318.             else
  319.                d := d+1;
  320.             end
  321.          end
  322.       end;
  323.  
  324.    ill(i,j: INTEGER): BOOLEAN is
  325.          -- Is there someone is ill at `i', `j'.
  326.       do
  327.          Result := (v(i,j) < 0)
  328.       end;
  329.  
  330.    v(i,j: INTEGER): INTEGER is
  331.          -- Gives `empty' when out of range or the
  332.          -- value in `world1'
  333.       do
  334.          if (world1.lower1 <= i and then i <= world1.upper1)
  335.             and (world1.lower2 <= j and then j <= world1.upper2) then
  336.             Result := world1.item(i,j)
  337.          else
  338.             Result := empty
  339.          end;
  340.       end;
  341.  
  342. end -- SPREAD_ILLNESS
  343.