program hex; uses SysUtils; { (c) copyright David van Deijk herfst,1999 eind opdracht programeren 0 s990247 id 479765 email d.d.v.deijk@student.tue.nl} {aanname: het krijgt juiste invoer van stdin effect : associeert stdin met een zettenpatroon voor het spelletje hex en analyseert deze waarna deze de uitvoer naar twee files BORD.TXT waarin het uiteindelijke speelbord staat en STAT.TXT waarin een analyse van de zetten staat } const MaxN = 20; { maximale bord afmeting } Leeg = '-'; { lege cel toestand } Wit = 'w'; { witte celtoestand } Zwart = 'z'; { zwarte celtoestand } type Index = 1..MaxN;{ rij- of kolom-index } Cel = char; { Leeg, Wit, Zwart } var { de variabelen van de toestands ruimte } N:1..MaxN; { bordafmeting } Bord:array[Index,Index] of Cel; { Bord[r,k] is celtoestand in rij r en kolom k, met 1 <= r <= N en 1 <= k <= N } zettabel:array[0..6,0..1] of integer; function Bordcel(r,k:Integer):cel; forward; { deze functie wordt later pas gespecifieerd } { aanname : geen resultaat: als r,k niet op het bord ligt leeg, anders de waarde van de cel r,k } function Aantalburen(r,k:Index):integer; forward; { deze functie wordt later pas gespecifieerd } { aanname : r,k ligt op bord; resultaat: het aantal buren van r,k met de zelfde status als r,k behalve als r,k op de rand van het bord ligt en r,k leeg is } function spelerno(c:cel):integer; { aanname : c is Wit of Zwart resultaat: als c wit is dan 0 als c zwart is dan 1 anders 2 } begin if c=Wit then spelerno:=0 else if c=zwart then spelerno:=1 else spelerno:=2; end; procedure LeegBord; { aanname: geen effect : Bord is leeg } var r,k:Index; { met r,k wordt het hele bord doorlopen } begin for r:=1 to N do for k:= 1 to N do Bord[r,k]:=Leeg; end; procedure ToonBord(var f:text); { aanname: f is geopend voor schrijven effect : Bord is naar f geschreven } var r,k:Index; { met r,k wordt het hele bord doorlopen } c:char; { deze wordt gebruikt voor overzichtelijk uitvoer } begin for c:='a' to chr(ord('a')+N-1) do write(f,' ',c); { schrijf een kolom-index naar file} writeln(f); { en nu komt het veld met aan het begin voldoende spaties en een rij index } for r:= 1 to N do begin write(f,r:r);{ schrijf de rij-index aan het begin } for k:= 1 to N do { doorloop alle kolomen } write(f,Bord[r,k]:2); { en toon de waarde van die cel } writeln(f); { en een endl character } end; end; procedure Leeszet(var f:text;var r,k:Index;var c:cel); { aanname: f is een voor lezen geopende tekst file effect : r,k en c zijn een waarde toegekend en de file-pointer is opgeschoven } var d:char;{hierin wordt de kolom index opgeslagen om geconverteerd te worden} begin read(f,c);{lees uit f de celinhoud } read(f,d);{lees uit f de kolom-index } read(f,r);{lees uit f de rij-index } k:=ord(d)-ord('a')+1;{ converteer het gelezen teken naar een waarde die in het programma past } readln(f);{en verwijder de endl uit de buffer } end; procedure Doezet(r,k:Index;c:Cel); { aanname: bord[r,k] is leeg; r,k<=N effect : bord[r,k] = c de zet wordt bekeken op aantal aangrenzende vakjes met zelfde status } var t:integer; begin bord[r,k]:=c; t:=aantalburen(r,k); if spelerno(c)<>2 then zettabel[t,spelerno(c)]:=zettabel[t,spelerno(c)]+1; end; procedure Leespartij(var f:text); { aanname : f is een voor-lezen-geopende-file effect : de partij in file f wordt verwerkt } var r,k:index;{ r en k worden als tijdelijke variabelen gebruikt } c:cel; { c wordt gebruikt om de celwaarde van leeszet naar doezet over te brengen} begin readln(f,N);{lees de grootte van het bord in} Leegbord; repeat leeszet(f,r,k,c); Doezet(r,k,c); until eof(f); end; function Bordcel(r,k:Integer):cel; { aanname : geen resultaat: als (r,k) niet op het bord ligt leeg, anders de waarde van de cel (r,k) } begin if (r>N) or (k>N) or (r<1) or (k<1) then { als (r,k) niet op het bord ligt } Bordcel:=leeg else { (r,k) ligt op het Bord } Bordcel:=Bord[r,k]; { endif } end; function Aantalburen(r,k:Index):integer; { aanname : r,k ligt op bord; resultaat: het aantal buren van (r,k) met dezelfde status als (r,k) behalve als (r,k) op de rand van het bord ligt en (r,k) leeg is } var t : integer; { tijdelijke variabele om Aantalburen onder tot nog toe geteste } x,y: -1..1; { deze doorlopen het veld om r,k heen } { k-1 k k+1 r-1 - + + r + * + r+1 + + - het plusje geeft aan of een veld getest moet worden als * (r,k) is we zien dat dit alle velden zijn waar x <> y als (0,0) als (r,k) word beschouwd) } begin t:=0; for x := -1 to 1 do { doorloop de drie rijen } for y:= -1 to 1 do{ en doorloop de drie kolommen } if (x<>y) and (bordcel(r+x,k+y)=bord[r,k]) then { als x<>y en de status van de } t:=t+1; { aangewezen bordcel komt overeen } { met de status van (r,k) dan } { verhoog de teller met 1 } Aantalburen:=t; end; procedure ToonTabel(var f:text); { aanname : f is geopend voor schrijven effect : de analyse tabel van zetten wordt naar file geschreven } var a :integer;{ teller om aantalzetten te doorlopen } s :integer;{ teller om speler te doorlopen } totaal :array[0..1]of integer;{hierin staan het totale aantal zetten per speler} begin for s:=0 to 1 do totaal[s]:=0; {initialiseer totaal} writeln(f,' aantal wit zwart totaal'); for a:= 0 to 6 do begin writeln(f,a:7,zettabel[a,0]:7,zettabel[a,1]:7,zettabel[a,0]+zettabel[a,1]:7); for s:=0 to 1 do totaal[s]:=totaal[s]+zettabel[a,s]; end; writeln(f,'totaal:',totaal[0]:7,totaal[1]:7,totaal[0]+totaal[1]:7); end; {das wirkliche program vonher} var f:text; begin Assignfile(f,'con'); { lees van stdin (con = console) } reset(f); { open om te lezen } Leespartij(f); { doe de zetten volgens f } close(f); { en sluit de file netjes } assignfile(f,'BORD.TXT');{ schrijf naar de bord uitvoer file } rewrite(f); { open om te schrijven } Toonbord(f); { schrijf het bord naar f } close(f); { en sluit de file netjes } assignfile(f,'STAT.TXT'); { schrijf naar de status file } rewrite(f); { open om te schrijven } toontabel(f); { en schrijf de tabel } close(f); { en sluit de file netjes } end.