﻿// KyblMiny v1.1
// www.kyblsoft.cz/mobil/

use graph as g,math,ui

//percent of mines
procentmin=25;

o=[];

//size of one field
o['rozmer']=15;

//auto-marking of mine fields
o['doplnovanimin']=true;

//auto-open non-mine fields
o['doplnovanipolicek']=true;

rozmery=g.full(false);
g.size(rozmery[0],rozmery[1]);

o['sirka']=g.size()[0];
o['vyska']=g.size()[1];

o['mezera']=math.floor(o['rozmer']/10);

function poz2sourx(o,poz)
  return (poz*(o['rozmer']+o['mezera'])+o['okrajx']);
end;

function poz2soury(o,poz)
  return (poz*(o['rozmer']+o['mezera'])+o['okrajy']);
end;

function sour2pozx(o,sour)
  return math.floor((sour-o['okrajx'])/(o['rozmer']+o['mezera']));
end;

function sour2pozy(o,sour)
  return math.floor((sour-o['okrajy'])/(o['rozmer']+o['mezera']));
end;

function validnipozice(o,x,y)
  return (x >= 0 and y >= 0 and x < o['pocetsloupcu'] and y < o['pocetradku']);
end;

function pocetminvokoli(o,pole,x,y)
  navrat=0;
  for pozx=x-1 to x+1 do
    for pozy=y-1 to y+1 do
      if validnipozice(o,pozx,pozy) then
        if pole[pozy][pozx] then
          navrat++;
        end;
      end;
    end;
  end;
  return navrat;
end;

function nakreslipolicko(o,pole,x,y,cislo,odkryta) forward;

function samzatrhnibomby(o,pole,x,y,odkryta)
  if not o['doplnovanimin'] then
    return;
  end;
  volnych=0;
  for pozx=x-1 to x+1 do
    for pozy=y-1 to y+1 do
      if validnipozice(o,pozx,pozy) and not isnum(odkryta[pozy][pozx]) then
        volnych++;
      end;
    end;
  end;
  if volnych = odkryta[y][x] then
    for pozx=x-1 to x+1 do
      for pozy=y-1 to y+1 do
        if validnipozice(o,pozx,pozy) and odkryta[pozy][pozx]=null then
          nakreslipolicko(o,pole,pozx,pozy,true,odkryta);
	  end;
      end;
    end;
  end;
end;

function odkryjpolicko(o,pole,x,y,odkryta) forward;

function samnajdiprazdne(o,pole,x,y,odkryta)
  pocetmin=0;
  for pozx=x-1 to x+1 do
    for pozy=y-1 to y+1 do
      if validnipozice(o,pozx,pozy) and odkryta[pozy][pozx]=false then
        pocetmin++;
      end;
    end;
  end;
  if pocetmin = odkryta[y][x] then
    for pozx=x-1 to x+1 do
      for pozy=y-1 to y+1 do
        if validnipozice(o,pozx,pozy) and odkryta[pozy][pozx]=null then
          odkryjpolicko(o,pole,pozx,pozy,odkryta);
	  end;
      end;
    end;
  end;
end;

function samdoplnokoli(o,pole,x,y,odkryta)
  if not o['doplnovanipolicek'] then
    return;
  end;
  for pozx=x-1 to x+1 do
    for pozy=y-1 to y+1 do
      if validnipozice(o,pozx,pozy) then
        if isnum(odkryta[pozy][pozx]) then
          samzatrhnibomby(o,pole,pozx,pozy,odkryta);
          samnajdiprazdne(o,pole,pozx,pozy,odkryta);
        end;
      end;
    end;
  end;
end;

function nakreslipolicko(o,pole,x,y,cislo,odkryta)
  if cislo = true then //oznac minu
    g.circle(poz2sourx(o,x)+o['rozmer']/6,poz2soury(o,y)+o['rozmer']/6,o['rozmer']*2/3);
    odkryta[y][x]=false;

    samdoplnokoli(o,pole,x,y,odkryta);
    return;
  end;

  g.rect(poz2sourx(o,x),poz2soury(o,y),o['rozmer'],o['rozmer']);
  if cislo # null and cislo # 0 then
    g.text(poz2sourx(o,x)+(o['rozmer']-8)/2,poz2soury(o,y)+o['rozmer']-(o['rozmer']-10)/2,str(cislo));
  end;
end;

function odkryjpolicko(o,pole,x,y,odkryta)
  if not isnum(odkryta[y][x]) and odkryta[y][x] # false then
    if pole[y][x] then
      ui.msg('Mina!','KýblMiny');
    else
      pocetmin=pocetminvokoli(o,pole,x,y);
      nakreslipolicko(o,pole,x,y,pocetmin,odkryta);
      odkryta[y][x]=pocetmin;
      o['odkrytych']++;
      if pocetmin = 0 then
        for pozx=x-1 to x+1 do
          for pozy=y-1 to y+1 do
            if validnipozice(o,pozx,pozy) then
             odkryjpolicko(o,pole,pozx,pozy,odkryta);
           end;
          end;
        end;
      end;

 	samdoplnokoli(o,pole,x,y,odkryta);
    end;
  end;
end;

o['pocetradku']=math.floor(o['vyska']/(o['rozmer']+o['mezera']));
o['pocetsloupcu']=math.floor(o['sirka']/(o['rozmer']+o['mezera']));
o['okrajx']=(o['sirka']-(o['pocetsloupcu']*o['rozmer']+(o['pocetsloupcu']-1)*o['mezera']))/2;
o['okrajy']=math.floor((o['vyska']-(o['pocetradku']*o['rozmer']+(o['pocetradku']-1)*o['mezera']))/2);

g.brush(0x808080);

pole=[];
odkryta=[];
o['odkrytych']=0;
celkemodkryt=0;

for radek=0 to (o['pocetradku']-1) do
  append(pole,[]);
  append(odkryta,[]);

  for sloupec=0 to (o['pocetsloupcu']-1) do
    jemina=((math.random()*100/procentmin)<1);
    append(pole[radek],jemina);
    append(odkryta[radek],null);
    if not jemina then
      celkemodkryt++;
    end;

    nakreslipolicko(o,pole,sloupec,radek,null,odkryta);
  end;
end;
g.show();

g.brush(0x80FFFF);
pozstisk=null;

while true do
  ui.ptr(false);
  ui.keys(false);
  vstup=ui.cmd();
  if not isarray(vstup) then
    break;
  end;
  if vstup[2] = 1 then //stisknuti
    if pozstisk = null then
      pozstisk=[vstup[0],vstup[1]];
    end;
  elsif pozstisk # null then
                             //uvolneni
    x=sour2pozx(o,pozstisk[0]);
    y=sour2pozx(o,pozstisk[1]);
    puvx=pozstisk[0];
    puvy=pozstisk[1];
    pozstisk=null;
    if validnipozice(o,x,y) then
      if math.sqrt(math.pow(puvx-vstup[0],2)+math.pow(puvy-vstup[1],2)) < o['rozmer'] then
        if o['odkrytych'] = 0 and pole[y][x] then
          pole[y][x]=false;
          celkemodkryt++;
        end;
        odkryjpolicko(o,pole,x,y,odkryta);
      else
        if pole[y][x] = true then
          nakreslipolicko(o,pole,x,y,true,odkryta);
        elsif odkryta[y][x] = null then
          ui.msg('Tady není mina :-)');
        end;
      end;
    end;
    g.show();
    if o['odkrytych']=celkemodkryt then
      ui.msg(':-)','KýblMiny');
      break;
    end;
  end;
end;
