Delphi

Stian Søiland, IT 112, øvingsgruppe 15 (stud.ass. Helle Haugenes)

Delphi - Øving 3 - Oppgave 1

<
program Oving3;

uses
  Forms, Graphics, Unit1;

{$r oving3.scu}

begin
  Application.Create;
  Application.CreateForm (TForm1, Form1);
  Application.Run;
  Application.Destroy;
end.

unit Unit1;

interface

uses
  Classes, Forms, Graphics, Grids, matriseklatter,
  ExtCtrls, Buttons, StdCtrls, SysUtils;

type
  TForm1 = class (TForm)
    StringGrid1: TStringGrid;
    RadioGroup1: TRadioGroup;
    Label1: TLabel;
    Button1: TButton;
    procedure Button1OnClick (Sender: TObject);
    procedure StringGrid1OnSelectCell (Sender: TObject; Col: LongInt;
      Row: LongInt);
  private
    {Insert private declarations here}
  public
    {Insert public declarations here}
  end;

var
  Form1: TForm1;

const fylt = #219;
      tomt = '';

implementation

procedure TForm1.Button1OnClick (Sender: TObject);
 var resultat:boolean;
     i,j:integer;
begin
  initier(resultat);
  if resultat then
    begin
      // Nullstiller Stringgriden
      StringGrid1.Visible := False;
      for i:=0 to StringGrid1.Colcount-1 do
        for j:=0 to StringGrid1.Rowcount-1 do
          StringGrid1.Cells[i,j] := tomt;
      // Viser frem Stringgriden som man nå får lov å klikke på
      StringGrid1.Visible := True;
      // Setter valget til 'markert'
      RadioGroup1.ItemIndex := 0;
      Label1.Caption := 'Initiert';
    end
  else
    Label1.Caption := 'Feil!';
end;

procedure TForm1.StringGrid1OnSelectCell (Sender: TObject; Col: LongInt;
  Row: LongInt);
  var markert,resultat:boolean;
      antall:integer;
  begin
     if RadioGroup1.ItemIndex < 1 then
       // Markering
       begin
         Label1.Caption := 'Markerer..';
         // Kobler inn ShowSelection for at Stringriden skal bli oppdatert
         StringGrid1.Options := StringGrid1.Options + [goShowSelection];
         // Sjekker om cellen allerede er markert
         hent(Col,Row,markert,resultat);
         if resultat then
           begin
             if not markert then
               // Markerer i stringgrid
               StringGrid1.Cells[Col,Row] := fylt
              else
               // Fjerner markering i stringgrid
               StringGrid1.Cells[Col,Row] := tomt;
             // Lagrer det motsatte av markert-verdien i matrisen
             lagre(Col,Row,(not markert),resultat);
           end;
         // Kobler ut igjen ShowSelection for at ikke den ekle mark›ren skal vises
         StringGrid1.Options := StringGrid1.Options - [goShowSelection];
      end // markering
     else
      // Telling
      begin
        // Kaller prosedyren klatt som returnerer antall
        klatt(Col,Row,antall,resultat);
        if resultat then
          begin
            // Skriver ut resultat
            Label1.Caption := 'Klatten er ' + inttostr(antall) + ' stor';
          end
        else
          begin
            Label1.Caption := 'Feil!';
          end;
      end; // telling
  end; // Prosedyre StringGridOnSelectCell
initialization
  RegisterClasses ([TForm1, TStringGrid, TRadioGroup, TLabel, TButton]);
end.

unit matriseklatter;

interface
  const
    // innholdet i tomme celler.. må være i datatype kolonnedata
    tomcelle = false;
  type
    // Setter matrisens datatype
    kolonnedata = boolean;
    // Setter matrisens dimensjoner
    kolonner = 0..11;
    rader = 0..11;


  // Prosedyren initier oppretter matrisen, resultat true hvis vellykket
  procedure initier(var resultat:boolean);

  // Prosedyren hent henter ut data fra matrisen i angitt celle,
  // resultat er true hvis vellykket, er koordinatene utenfor
  // matrisens dimensjoner er resultat false
  procedure hent(kolonne,rad:integer; var data:kolonnedata;
                 var resultat:boolean);

  // Prosedyren lagre lagrer data i matrisen i angitt celle,
  // resultat er true hvis vellykket, er koordinatene utenfor
  // matrisens dimensjoner er resultat false
  procedure lagre(kolonne,rad:integer; data:kolonnedata;
                  var resultat:boolean);

  // Prosedyren klatt finner størrelsen på en klatt hvor koordinatene
  // peker på et punkt innenfor klatten. Storrelse er 0 dersom
  // ingen klatt er ved punktet, resultat er false hvis koordinatene er
  // utenfor matrisens dimensjoner, hvis ikke er resultat true
  procedure klatt(kolonne,rad:integer; var storrelse:integer;
                  var resultat:boolean);

implementation
  // Global variabel matrise
  type matrisetype = array [kolonner,rader] of kolonnedata;
  var matrise : matrisetype;

  procedure initier(var resultat:boolean);
    var i,j:integer;
    begin
      // Sjekker om dimensjonene er fornuftige
      resultat := not ( (high(kolonner) < low(kolonner)) or
                        (high(rader) < low(rader)) );
      if resultat then
        // Gjennomløper hver kolonne i
        for i:=low(kolonner) to high(kolonner) do
          begin
            // Gjennomløper hver rad j
            for j:=low(rader) to high(rader) do
              begin
                // Setter cellen til den tomme konstanten
                matrise[i,j] := tomcelle;
              end; // radgjennomløping
          end; // kolonnegjennomløping
    end; // prosedyre initier

  // Funksjon for å sjekke om gitte koordinater er innenfor matrisen
  function sjekkdimensjon(kolonne,rad:integer):boolean;
    begin
      sjekkdimensjon := not (
                             (kolonne < low(kolonner))
                          or (kolonne > high(kolonner))
                          or (rad < low(rader))
                          or (rad > high(rader))
                            );
    end;

  procedure hent(kolonne,rad:integer; var data:kolonnedata;
                 var resultat:boolean);
    begin
      resultat := sjekkdimensjon(kolonne,rad);
      if resultat then
        begin
          data := matrise[kolonne,rad];
        end;
    end; // prosedyre hent

  procedure lagre(kolonne,rad:integer; data:kolonnedata;
                  var resultat:boolean);
    begin
      resultat := sjekkdimensjon(kolonne,rad);
      if resultat then
        begin
          matrise[kolonne,rad] := data;
        end;
    end; // prosedyre lagre

  procedure klatt(kolonne,rad:integer; var storrelse:integer;
              var resultat:boolean);
    // Peker til en temporær matrise
    type matrisepeker = ^matrisetype;
    var tempmatrise : matrisepeker;
    // Rekursiv funksjon
    function rekursiv(matrise:matrisepeker;
                      kolonne,rad,storrelse:integer):integer;
      var i,j:integer;
      begin
        if matrise^[kolonne,rad] <> tomcelle then
          begin
            // Denne cellen finnes og er ikke telt, teller opp
            storrelse := storrelse + 1;

            // ..og markerer den som telt
            matrise^[kolonne,rad] := tomcelle;

            // Sjekker alle celler som er i nærheten, også diagonalt
            // og seg selv en gang til (men den er merket tom nå)..
            // noe ueffektivt, men..
            for i:=-1 to 1 do
              for j:=-1 to 1 do
                begin
                  if sjekkdimensjon(kolonne+i,rad+j) then
                    storrelse := rekursiv(matrise,kolonne+i,rad+j,storrelse);
                end;
          end; // if cellen er utelt
        // Returnerer storrelse, berørt eller ikke
        rekursiv := storrelse;
      end; // funksjon rekursiv
    begin
      resultat := sjekkdimensjon(kolonne,rad);
      if resultat then
        begin
          // Tempmatrisen settes lik originalmatrisen, bare celler
          // som er markerte fra før trenger å telles
          new(tempmatrise);
          tempmatrise^ := matrise;
          storrelse := 0;
          storrelse := rekursiv(tempmatrise,kolonne,rad,storrelse);
        end;
    end; // prosedyre klatt

initialization
end.

 


© Stian Søiland 1999

Valid HTML 4.0!