program matches; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, crt, {timerutils}time { you can add units after this }; var pole,hrac1,hrac2 : array [0..21,0..31] of string[5]; pom_prom : string[20]; typ : string[2]; //polex,poley jsou pripravena do budoucna na dynamicka pole, zatim jsou jenom staticky dana x,y,i, tah,prodleva, polex,poley, skore1,skore1old, skore2,skore2old : smallint; //v souvislosti se zmenou casove prodlevy za behu typu hry cc {currenttime : longint;} const cekani : smallint = 3000; (****************************************************) (* vypise napovedu *) (****************************************************) procedure help; begin writeln ('---------------------------- help ----------------------------'); writeln ; writeln (paramstr(0)); writeln ; writeln (' -h help'); writeln (' vypise tuto napovedu'); writeln ; writeln (' -t type [ hh | hc | cc ]'); writeln (' typ hry: hh - human X human [ default ]'); writeln (' hc - human X computer'); writeln (' cc - computer X computer'); writeln ; writeln (' -d delay ( interval 0 az 32767 ) [ default: 1000 ]'); writeln (' casova prodleva mezi tahy (v milisekundach)'); writeln (' ! lze pouzit jen s volbou -t cc !'); writeln ; end; (****************************************************) (* vraci vstupni parametry programu *) (****************************************************) procedure input_param (var typ:string[2]; var prodleva:smallint); var parametry : array [1..3] of string[10]; allparamok : boolean; returned : smallint; begin parametry[1]:='-h'; parametry[2]:='-t'; parametry[3]:='-d'; prodleva:=-1; typ:='hh'; allparamok := false; if paramcount>=1 then for i:=1 to paramcount do begin //jestli nektery parametr odpovida, tak break for y:=1 to length(parametry) do if paramstr(i) = parametry[y] then begin allparamok := true; break; end //jestli predchozi parametr byl "mozny", treba toto bude jeho hodnota else if paramstr(i-1) = parametry[y] then begin allparamok := true; break; end; //kdyz nektery parametr neodpovida if allparamok = false then begin writeln ; writeln ('neexistujici parametr nebo spatna hodnota parametru: ',paramstr(i)); writeln ; break; end; end else allparamok:=true; if allparamok = false then begin help; halt(0); end else if paramcount >= 1 then begin for i:=1 to paramcount do begin //jestli napoveda if paramstr(i)=parametry[1] then begin help; halt(0); end; //jestli typ if paramstr(i)=parametry[2] then begin if (paramstr(i+1)='hh') or (paramstr(i+1)='hc') or (paramstr(i+1)='cc') then typ:=paramstr(i+1) else if (i+1) > paramcount then begin writeln ('ERROR: prazdny parametr ',parametry[2]); halt(0); end else begin writeln ('spatna hodnota parametru ',parametry[2]); halt(0); end; continue; end; //jestli prodleva if paramstr(i)=parametry[3] then begin if (i+1) > paramcount then begin writeln ('ERROR: prazdny parametr ',parametry[3]); halt(0); end else begin val(paramstr(i+1),prodleva,returned); if returned<>0 then begin writeln ('hodnota parametru ',parametry[3],' neni cislo'); halt(0); end //neslo to pres interval, nevim proc, docela by me to zajimalo else if not((prodleva <= 32767) and (prodleva >= 0)) then begin writeln ('cislo v parametru ',parametry[3],' neni z intervalu 0 az 32767'); halt(0); end; end; end; end; end; end; (****************************************************) (* maze pocet radku, vcetne nynejsiho *) (****************************************************) procedure smazradky (radku:byte); var i : byte; begin delline; for i:=1 to radku-1 do begin y:=wherey-1; gotoxy(1,y); clreol; end; end; (****************************************************) (* vykresli hraci pole *) (****************************************************) procedure drawtab(x,y:smallint); begin for y:=0 to length(pole[0])-1 do begin for x:=0 to length(pole)-1 do if (hrac1[x,y][1]=' ') and (hrac2[x,y][1]=' ') then write (pole[x,y]) else if hrac1[x,y][1]=' ' then begin //svitiva zelena textcolor(10); write (hrac2[x,y]); normvideo; end else begin //svitiva zluta textcolor(14); write (hrac1[x,y]); normvideo; end; writeln; end; end; (****************************************************) (* vraci souradnice uzivatele *) (****************************************************) procedure OwnSouradnice (var x,y : smallint); var xovain, yova : string; ok, z : smallint; begin //opakovat zadavani x a y, dokud nebudou sedet repeat (* xova *) ok:=1; repeat write ('zadejte souradnice sirky: x = '); readln (xovain); val(xovain,x,ok); if not(ok=0) then begin writeln; write ('zadane znaky nelze povazovat za cislo, zadejte je znovu'); delay(cekani); smazradky(3); end else if not(x in [1..length(pole)-1]) then begin ok:=1; writeln; write ('zadane cislo neni z cisel na ose x, zadejte je znovu'); delay(cekani); smazradky(3); end; until (ok=0); (* yova *) //vypocte posledni pismenko z osy y i:=0; for z:=1 to length(pole[0])-1 do if (z mod 3) = 0 then i:=i+1 else if (z mod 3) = 1 then i:=i+1; ok:=1; repeat write (' y = '); readln (yova); if (yova[1]='1') or (length(yova)>1) or not(yova[1] in ['a'..chr(96+i)]) then begin writeln; write ('tomu rikate male pismenko z osy y ?! - zadejte znovu'); delay(cekani); smazradky(3); end else if ((((ord(yova[1])-ord('a')+1) mod 2)=0) and ((x mod 2)=0)) or ((((ord(yova[1])-ord('a')+1) mod 2)=1) and ((x mod 2)=1)) or ((ord(yova[1])-ord('a')+1) = x) then begin writeln; write ('tato souradnice prece neexistuje!'); delay(cekani); smazradky(4); break; end else ok:=0; until ok=0; until ok=0; //vypocet radku y:=(ord(yova[1])-ord('a')+1) + ((ord(yova[1])-ord('a')+1) div 2); end; (****************************************************) (* vraci kolik uzavira kruhu *) (****************************************************) function kruhu(x,y:smallint):smallint; begin kruhu:=0; // pro '|' if (hrac1[x,y][1]='|') or (hrac2[x,y][1]='|') then begin //kruh vlevo //aby nesahal mimo pole - nekam do pameti, kde nevim, co je if ( x-1 > 1 ) and ((hrac1[x-2,y ][1]='|') or (hrac2[x-2,y ][1]='|')) and ((hrac1[x-1,y-2][1]='_') or (hrac2[x-1,y-2][1]='_')) and ((hrac1[x-1,y+1][1]='_') or (hrac2[x-1,y+1][1]='_')) then kruhu:=kruhu+1; //kruh vpravo //aby nesahal mimo pole - nekam do pameti, kde nevim, co je if ( x+1 < length(pole)-1 ) and ((hrac1[x+2,y ][1]='|') or (hrac2[x+2,y ][1]='|')) and ((hrac1[x+1,y-2][1]='_') or (hrac2[x+1,y-2][1]='_')) and ((hrac1[x+1,y+1][1]='_') or (hrac2[x+1,y+1][1]='_')) then kruhu:=kruhu+1; end; // pro '_' if (hrac1[x,y][1]='_') or (hrac2[x,y][1]='_') then begin //kruh nad //aby nesahal mimo pole - nekam do pameti, kde nevim, co je if ( y-1 > 1 ) and ((hrac1[x,y-3][1]='_') or (hrac2[x,y-3][1]='_')) and ((hrac1[x-1,y][1]='|') or (hrac2[x-1,y][1]='|')) and ((hrac1[x+1,y][1]='|') or (hrac2[x+1,y][1]='|')) then kruhu:=kruhu+1; //kruh pod //aby nesahal mimo pole - nekam do pameti, kde nevim, co je if ( y+1 < length(pole[0])-1 ) and ((hrac1[x ,y+3][1]='_') or (hrac2[x ,y+3][1]='_')) and ((hrac1[x-1,y+2][1]='|') or (hrac2[x-1,y+2][1]='|')) and ((hrac1[x+1,y+2][1]='|') or (hrac2[x+1,y+2][1]='|')) then kruhu:=kruhu+1; end; end; (****************************************************) (* vraci nahodny integer ze zadaneho intervalu *) (****************************************************) function randomint (min, max: integer): integer; begin if min < max then randomint := min + random (max - min) else randomint := min - random (min - max) end; (****************************************************) (* vraci idealni souradnice *) (****************************************************) procedure ideal(var a,b : smallint); var skonci : boolean; begin skonci:=false; //nahodne generovat tah dokud se netrefi prazdne pole :) //(maximalne vsak 39x, pak se vezme prvni prazdne misto, // kvuli setreni procesorovym casem) for i:=1 to 40 do begin x:=randomint(1,length(pole)-1); y:=randomint(1,length(pole[0])-1); if ( (((y mod 3)=0) and ((x mod 2)=1)) or (((y mod 3)=1) and ((x mod 2)=0)) ) and //je tam volno? (hrac1[x,y][1]=' ') and (hrac2[x,y][1]=' ') then break; end; //vraci souradnice prvniho prazdneho mista if i=40 then begin for y:=1 to length(pole[0])-1 do begin for x:=1 to length(pole)-1 do //spravna souradnice? if ( (((y mod 3)=0) and ((x mod 2)=1)) or (((y mod 3)=1) and ((x mod 2)=0)) ) and //je tam volno? ((hrac1[x,y][1]=' ') and (hrac2[x,y][1]=' ')) then begin skonci:=true; break; end else continue; if skonci=true then break; end; end; a:=x; b:=y; end; (****************************************************) (****************************************************) (* *) (* START *) (* *) (****************************************************) (****************************************************) begin //kontrola/vyplneni vstupnich parametru prodleva:=1000; typ:='hh'; input_param(typ,prodleva); if (typ<>'cc') and (prodleva>=0) then begin writeln ('nemuzete zadavat casovou prodlevu, kdyz to neni typ hry cc'); halt(0); end; //kdyz neni parametr -d VUBEC zadany if prodleva<0 then prodleva:=1000; //zaplneni hracu mezerami for y:=0 to length(hrac1[0])-1 do for x:=0 to length(hrac1)-1 do begin hrac1[x,y]:=(' '); end; for y:=0 to length(hrac2[0])-1 do for x:=0 to length(hrac2)-1 do begin hrac2[x,y]:=(' '); end; (****************************************************) (* hraci pole *) (****************************************************) //prvni radek y:=0; for x:=0 to length(pole)-1 do if x=0 then pole[x,y]:=(' ') else if (x mod 2) = 0 then if x > 9 then begin str(x,pom_prom); pole[x,y]:=(' '+pom_prom+' ') end else begin str(x,pom_prom); pole[x,y]:=(' '+pom_prom+' ') end else begin str(x,pom_prom); pole[x,y]:=(pom_prom); end; //ostatni radky i:=0; for y:=1 to length(pole[0])-1 do begin for x:=0 to length(pole)-1 do begin //jestli JE to prvni "string" v radku if x=0 then //jestli JE to prvni radek if y=1 then begin i:=i+1; pole[x,y]:=(chr(96+i)+' _'); end //kdyz to NEni prvni radek else if (y mod 3) = 0 then begin i:=i+1; pole[x,y]:=(chr(96+i)+' '); end else if (y mod 3) = 1 then begin i:=i+1; pole[x,y]:=(chr(96+i)+' _'); end else pole[x,y]:=(' ') //kdyz to NEni prvni "string" v radku else if (y mod 3) = 1 then if (x mod 2) = 0 then pole[x,y]:=('_____') else pole[x,y]:=('|') else if (x mod 2) = 0 then pole[x,y]:=(' ') else pole[x,y]:=('|'); end; end; //naplneni dulezitych promennych tah:=1; skore1:=0; skore2:=0; skore1old:=0; skore2old:=0; polex:=10; poley:=10; (****************************************************) (* vysledny vypis na obrazovku *) (****************************************************) repeat clrscr; drawtab(x,y); skore1old:=skore1; skore2old:=skore2; writeln ('--------------------------- skore ----------------------------'); write (' zluty hrac: ',skore1); write (' '); writeln ('zeleny hrac: ',skore2); if skore1+skore2 <> polex*poley then repeat //hrac1 if tah = 1 then begin write ('------------------- na tahu je '); //svitiva zluta textcolor(14); write ('zluty'); normvideo; writeln (' hrac --------------------'); //kdyz typ = hh if (typ='hh') or (typ='hc') then begin // toto je zakomentovane, protoze je to pekne otravne - hlavne to je podvod pri hre :) // jiny zpusob reseni me nenapadnul, // jedine zmacknuti klavesy F1, s tim jsem se ale uz nechtel delat, // protoze mi to prislo zbytecne - tu hru by to zkazilo :) { repeat write ('chce aby tento tah za Vas provedl pocitac? y/n : '); readln (pom_prom); if (pom_prom <> 'y') and (pom_prom <> 'n') then begin writeln ('nezadal jste "y" nebo "n", zkuste to znovu !'); delay(cekani); smazradky(3); end; until (pom_prom = 'y') or (pom_prom = 'n'); if pom_prom='y' then ideal(x,y) else }ownsouradnice(x,y); if hrac1[x,y][1]=' ' then if hrac2[x,y][1]=' ' then if (x mod 2)=0 then begin hrac1[x,y]:=('_____'); skore1:=skore1+kruhu(x,y); end else begin hrac1[x,y+1]:=('|'); hrac1[x,y ]:=('|'); hrac1[x,y-1]:=('|'); //skore skore1:=skore1+kruhu(x,y); end else begin writeln ('to nevidis, ze tam Tvuj protihrac ma uz svoji sirku?!'); delay(cekani); smazradky(5); end else begin writeln ('to nevidis, ze uz sis tam jednou sirku dal(a)?!'); delay(cekani); smazradky(5); end; end; //kdyz typ = cc if typ='cc' then begin ideal(x,y); if (x mod 2)=0 then begin hrac1[x,y]:=('_____'); skore1:=skore1+kruhu(x,y); end else begin hrac1[x,y+1]:=('|'); hrac1[x,y ]:=('|'); hrac1[x,y-1]:=('|'); //skore skore1:=skore1+kruhu(x,y); end; end; end //hrac2 else begin write ('------------------ na tahu je '); //svitiva zelena textcolor(10); write ('zeleny'); normvideo; writeln (' hrac --------------------'); //kdyz typ = hh if typ='hh' then begin // toto je zakomentovane, protoze je to pekne otravne - hlavne to je podvod pri hre :) // jiny zpusob reseni me nenapadnul, // jedine zmacknuti klavesy F1, s tim jsem se ale uz nechtel delat, // protoze mi to prislo zbytecne - tu hru by to zkazilo :) { repeat write ('chce aby tento tah za Vas provedl pocitac? y/n : '); readln (pom_prom); if (pom_prom <> 'y') and (pom_prom <> 'n') then begin writeln ('nezadal jste "y" nebo "n", zkuste to znovu !'); delay(cekani); smazradky(3); end; until (pom_prom = 'y') or (pom_prom = 'n'); if pom_prom='y' then ideal(x,y) else }ownsouradnice(x,y); if hrac2[x,y][1]=' ' then if hrac1[x,y][1]=' ' then if (x mod 2)=0 then begin hrac2[x,y]:=('_____'); skore2:=skore2+kruhu(x,y); end else begin hrac2[x,y+1]:=('|'); hrac2[x,y ]:=('|'); hrac2[x,y-1]:=('|'); //skore skore2:=skore2+kruhu(x,y); end else begin writeln ('to nevidis, ze tam Tvuj protihrac ma uz svoji sirku?!'); delay(cekani); smazradky(5); end else begin writeln ('to nevidis, ze uz sis tam jednou sirku dal(a)?!'); delay(cekani); smazradky(5); end; end; //kdyz typ = cc nebo hc if (typ='cc') or (typ='hc') then begin ideal(x,y); if (x mod 2)=0 then begin hrac2[x,y]:=('_____'); skore2:=skore2+kruhu(x,y); end else begin hrac2[x,y+1]:=('|'); hrac2[x,y ]:=('|'); hrac2[x,y-1]:=('|'); //skore skore2:=skore2+kruhu(x,y); end; end; end; until (hrac1[x,y][1]='|') or (hrac1[x,y][1]='_') or (hrac2[x,y][1]='|') or (hrac2[x,y][1]='_') //aby se vyskocilo z cyklu - kvuli hezcimu vypisu else skore1:=skore1+1; if tah=1 then if skore1>skore1old then tah:=1 else tah:=2 else if skore2>skore2old then tah:=2 else tah:=1; //toto je reseni zmeny casove prodlevy pri typu hry cc //ale nefunguje mi - nejde zkompilovat, i kdyz by to melo jit { currenttime:=start_timer; if typ='cc' then begin writeln ('Muzete menit rychlost obnovovani,'); writeln ('staci zadat casovou prodlevu v milisekundach.'); repeat write ('prodleva: '); readln (pom_prom); val(pom_prom,prodleva,i); if i<>0 then begin writeln ('Zadane znaky nelze povazovat za cislo! Zkuste to znovu.'); delay(prodleva); smazradky(4); end else smazradky(3); until i=0; end wait_to (currenttime, (prodleva div 1000)); } if typ='cc' then delay(prodleva); //pricitam jednicku, aby se cyklus nacal jeste jednou // - proste kvuli "hezcimu" vystupu na obrazovce until skore1+skore2 = polex*poley+1; writeln ; writeln ('This program is licensed under the terms of GNU-GPLv3 or higher'); writeln ('If You want to know something more, look at this web-page:'); writeln ('www.gymnachod.cz/~pacner.jan'); writeln ; writeln ('written by Globator007 on 6/2008 in Lazarus'); writeln ('for EXIT press Enter'); readln; end.