
Stian Søiland, IT 112, øvingsgruppe 15 (stud.ass. Helle Haugenes)
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.