program wp08zad2;

const
    WYSOKOSC = 15;
    SZEROKOSC = 20;
    LICZBA_MIN = 50;

type
    StanPol = array [1 .. WYSOKOSC, 1 .. SZEROKOSC] of Boolean;

var mina, odsloniete, oznaczone : StanPol;
    sasiadujaceMiny : array [1 .. WYSOKOSC, 1 .. SZEROKOSC] of Integer;
    liczbaOdslonietych, liczbaFlag : Integer;

procedure wypelnij;
var i, j, k, x, y : Integer;
begin
    for i := 1 to WYSOKOSC do
        for j := 1 to SZEROKOSC do begin
            mina[i, j] := false;
            odsloniete[i, j] := false;
            oznaczone[i, j] := false;
            sasiadujaceMiny[i, j] := 0
        end;
    k := 1;
    while k <= LICZBA_MIN do begin
        i := random(WYSOKOSC) + 1;
        j := random(SZEROKOSC) + 1;
        if not mina[i, j] then begin
            mina[i, j] := true;
            for x := i - 1 to i + 1 do
                if x in [1 .. WYSOKOSC] then
                    for y := j - 1 to j + 1 do
                        if y in [1 .. SZEROKOSC] then
                            sasiadujaceMiny[x, y] := sasiadujaceMiny[x, y] + 1;
            k:=k+1
        end
    end;
    liczbaFlag := LICZBA_MIN;
    liczbaOdslonietych := 0
end;

procedure odslon(x, y : Integer);
var i, j : Integer;
begin
    if (x in [1 .. WYSOKOSC]) and (y in [1 .. SZEROKOSC]) then
        if not odsloniete[x, y] then begin
            liczbaOdslonietych := liczbaOdslonietych + 1;
            odsloniete[x, y] := true;
            if sasiadujaceMiny[x, y] = 0 then
                for i := x - 1 to x + 1 do
                    for j := y - 1 to y + 1 do
                        if (i <> x) or (j <> y) then
                            odslon(i, j)
        end
end;

procedure wypisz(pokazacMiny : Boolean);
var i, j : Integer;
    c : Char;
begin
    write(' +');
    for i := 1 to SZEROKOSC do
        write('--');
    writeln('-+');
    for i := WYSOKOSC downto 1 do begin
        write(i mod 10, '|');
        for j := 1 to SZEROKOSC do
            if pokazacMiny and mina[i, j] then
                write(' *')
            else
                if odsloniete[i, j] then
                    if sasiadujaceMiny[i, j] = 0 then
                        write('  ')
                    else
                        write(' ', chr(ord('0') + sasiadujaceMiny[i, j]))
                else
                    if oznaczone[i, j] then
                        write(' #')
                    else
                        write(' .');
        writeln(' |')
    end;
    write(' +');
    for i := 1 to SZEROKOSC do
        write('--');
    writeln('-+');
    write('  ');
    for c := 'a' to chr(ord('a') + SZEROKOSC - 1) do
        write(' ', c);
    writeln
end;

procedure graj;
var kc : Char;
    ruch, w, k : Integer;
    koniec, oznaczam : Boolean;
begin
    koniec:=false;
    ruch:=1;
    wypisz(false);
    while not koniec do begin
        write(ruch,'(',liczbaFlag,')',': ');
        ruch:=ruch+1;
        read(kc);
        oznaczam:=kc='#';
        if oznaczam then
            readln(kc,w)
        else
            readln(w);
        k:=ord(kc)-ord('a')+1;
        if (k in [1..SZEROKOSC]) and (w in [1..WYSOKOSC]) then
            if odsloniete[w,k] then
                writeln('To pole jest odsloniete')
            else if oznaczam then
                if oznaczone[w,k] then begin
                    liczbaFlag:=liczbaFlag+1;
                    oznaczone[w,k]:=false;
                    writeln('Skasowales oznaczenie')
                end else begin
                    liczbaFlag:=liczbaFlag-1;
                    oznaczone[w,k]:=true;
                    writeln('Oznaczyles pole')
                end
            else if oznaczone[w,k] then
                writeln('Pola oznaczonego nie mozna odslonic')
            else if mina[w,k] then begin
                writeln('Na tym polu jest mina. Przegrales !');
                koniec:=true
            end else begin
                odslon(w,k);
                if liczbaOdslonietych+LICZBA_MIN=WYSOKOSC*SZEROKOSC then begin
                    writeln('Odsloniles wszystkie pola bez min. Wygrales !');
                    koniec:=true
                end else
                    writeln('Odsloniles pole')
            end
        else
            writeln('Niepoprawny ruch');
        wypisz(koniec)
    end
end;

begin
    randomize;
    if SZEROKOSC > ord('z') - ord('a') + 1 then begin
        writeln('Plansza za szeroka');
        halt
    end;
    if LICZBA_MIN > (SZEROKOSC - 1) * (WYSOKOSC - 1) then begin
        writeln('Za duzo min');
        halt
    end;
    wypelnij;
    graj
end.
