Kółko i krzyżyk - tłumaczenie dla nooba ...

0

Witam !

Niedawno zainteresowałem się delphi i znajomy mi "podpowiedział" że dobrze jest zacząć od klasycznej gry "kółko i krzyżyk". Znalazłem więc w internecie 'gotowca' ale nie bardzo rozumiem jak on działa (tzn sam algorytm myślący).

Czy ktoś mógłby wytłumaczyć na czym ta rzecz polega ?

Wstawiam tutaj kod całej gry ... wiem ze dla fachowcow to jedno spojrzenie pewnie, ale ja sie glowie od dwoch dni :P

var
  Form1: TForm1;
  p:array[1..9]of TPanel; {tworzy kratki do gry}
  k,los:byte;
implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  for k:=1 to 9 do
    p[k].free  {czyści kratki po grze}
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
  for k:=1 to 9 do
  begin
    p[k]:=TPanel.Create(form1);
    p[k].parent:=form1;
    p[k].left:=100+55*((k-1) mod 3);
    p[k].top:=200+55*((k-1) div 3);
    p[k].width:=50;
    p[k].height:=50;
    p[k].color:=clwhite;
    p[k].OnClick:=Click;
    p[k].font.size:=12;
    p[k].font.name:='Comic Sans MS';
    p[k].enabled:=false;
  end
end;

procedure TForm1.Click(sender: TObject);
begin
  If ((sender is TPanel)and((sender as TPanel).caption=''))and(not koniec) then {!!!!!!!}
  begin
    If x.checked then
      with (sender as TPanel) do
      begin
        caption:='x';
        font.color:=clnavy
      end
    else
      with (sender as TPanel) do
      begin
        caption:='o';
        font.color:=clmaroon
      end;
    if (not remis)and(not koniec) then
    case wybor.ItemIndex of
      0:komp1;
      1:komp2;
    end
  end
end;

procedure TForm1.startClick(Sender: TObject);
begin
  if start.caption='Rozpocznij grę' then
    if not wybor.ItemIndex in [0,1] then showmessage('Wybierz poziom trudności!')
    else if (x.checked=false)and(o.checked=false) then showmessage('Wybierz kółko albo krzyżyk!')
         else
           begin
             los:=random(2)+1;
             case los of
               1:label1.caption:='zaczyna gracz!';
               2:label1.caption:='zaczyna komputer!';
             end;
             x.enabled:=false;
             o.enabled:=false;
             wybor.enabled:=false;
             start.enabled:=false;
             for k:=1 to 9 do
               p[k].enabled:=true;
             if los=2 then poczatek
           end
  else
    begin
      button1.visible:=false;
      x.enabled:=true;
      o.enabled:=true;
      wybor.enabled:=true;
      start.enabled:=true;
      start.caption:='Rozpocznij grę';
      panel.caption:='kólko i krzyzyk';
      label1.caption:='';
      for k:=1 to 9 do
      begin
        p[k].caption:='';
        p[k].enabled:=false;
        p[k].color:=clwhite
      end
    end
end;

procedure TForm1.poczatek;
var j,i:byte;
begin
  j:=random(4);
  case j of
    0:i:=1;
    1:i:=3;
    2:i:=7;
    3:i:=9
  end;
  wstaw(i)
end;

procedure TForm1.Komp1;
var i:byte;
begin
  repeat
    i:=random(9)+1
  until p[i].caption='';
  wstaw(i);
  koniec;
  remis
end;

procedure TForm1.Komp2;
var z:string;
    a:byte;
begin
  a:=0;
  if x.checked then z:='o' else z:='x';
  if por2(1,5,9,z)<>0 then a:=por2(1,5,9,z) else
  if por2(3,5,7,z)<>0 then a:=por2(3,5,7,z) else
  if por2(1,2,3,z)<>0 then a:=por2(1,2,3,z) else
  if por2(4,5,6,z)<>0 then a:=por2(4,5,6,z) else
  if por2(7,8,9,z)<>0 then a:=por2(7,8,9,z) else
  if por2(1,4,7,z)<>0 then a:=por2(1,4,7,z) else
  if por2(2,5,8,z)<>0 then a:=por2(2,5,8,z) else
  if por2(3,6,9,z)<>0 then a:=por2(3,6,9,z) else
  begin
    if z='o' then z:='x' else z:='o';
    if por2(1,5,9,z)<>0 then a:=por2(1,5,9,z) else
    if por2(3,5,7,z)<>0 then a:=por2(3,5,7,z) else
    if por2(1,2,3,z)<>0 then a:=por2(1,2,3,z) else
    if por2(4,5,6,z)<>0 then a:=por2(4,5,6,z) else
    if por2(7,8,9,z)<>0 then a:=por2(7,8,9,z) else
    if por2(1,4,7,z)<>0 then a:=por2(1,4,7,z) else
    if por2(2,5,8,z)<>0 then a:=por2(2,5,8,z) else
    if por2(3,6,9,z)<>0 then a:=por2(3,6,9,z) else
    begin
      if z='o' then z:='x' else z:='o';
      if por1(1,5,9,z)<>0 then a:=por1(1,5,9,z) else
      if por1(3,5,7,z)<>0 then a:=por1(3,5,7,z) else
      if por1(1,2,3,z)<>0 then a:=por1(1,2,3,z) else
      if por1(4,5,6,z)<>0 then a:=por1(4,5,6,z) else
      if por1(7,8,9,z)<>0 then a:=por1(7,8,9,z) else
      if por1(1,4,7,z)<>0 then a:=por1(1,4,7,z) else
      if por1(2,5,8,z)<>0 then a:=por1(2,5,8,z) else
      if por1(3,6,9,z)<>0 then a:=por1(3,6,9,z) else
      begin
        if z='o' then z:='x' else z:='o';
        if por1(1,5,9,z)<>0 then a:=por1(1,5,9,z) else
        if por1(3,5,7,z)<>0 then a:=por1(3,5,7,z) else
        if por1(1,2,3,z)<>0 then a:=por1(1,2,3,z) else
        if por1(4,5,6,z)<>0 then a:=por1(4,5,6,z) else
        if por1(7,8,9,z)<>0 then a:=por1(7,8,9,z) else
        if por1(1,4,7,z)<>0 then a:=por1(1,4,7,z) else
        if por1(2,5,8,z)<>0 then a:=por1(2,5,8,z) else
        if por1(3,6,9,z)<>0 then a:=por1(3,6,9,z)
      end
    end
  end;
  if a<>0 then
  begin
    wstaw(a);
    koniec;
    remis
  end else komp1;
end;

procedure TForm1.wstaw(a:byte);
begin
  if x.checked then
  begin
    p[a].caption:='o';
    p[a].font.color:=clmaroon
  end else
      begin
        p[a].caption:='x';
        p[a].font.color:=clnavy
      end
end;

function TForm1.por1(a1,a2,a3: byte; s:string):byte;
begin
  if (p[a1].caption=p[a2].caption)and(p[a3].caption=s)and(p[a1].caption='')
    then por1:=a1
  else if (p[a3].caption=p[a2].caption)and(p[a1].caption=s)and(p[a3].caption='')
         then por1:=a3
       else if (p[a1].caption=p[a3].caption)and(p[a2].caption=s)and(p[a1].caption='')
              then por1:=a1
                else por1:=0
end;

function TForm1.por2(a1,a2,a3: byte; s:string):byte;
begin
  if (p[a1].caption=p[a2].caption)and(p[a3].caption='')and(p[a1].caption=s)
    then por2:=a3
  else if (p[a3].caption=p[a2].caption)and(p[a1].caption='')and(p[a3].caption=s)
         then por2:=a1
       else if (p[a1].caption=p[a3].caption)and(p[a2].caption='')and(p[a1].caption=s)
              then por2:=a2
            else por2:=0
end;

function TForm1.por3(a1,a2,a3: byte):string;
begin
  if (p[a1].caption<>'')and
    ((p[a1].caption=p[a2].caption)and(p[a2].caption=p[a3].caption))then
  begin
    p[a1].color:=clFuchsia;
    p[a2].color:=clFuchsia;
    p[a3].color:=clFuchsia;
    por3:=p[a1].caption
  end else por3:=''
end;

function TForm1.koniec:boolean;
var s:string;
    kon:boolean;
begin
  s:=por3(1,2,3);
  s:=s+por3(4,5,6);
  s:=s+por3(7,8,9);
  s:=s+por3(1,4,7);
  s:=s+por3(2,5,8);
  s:=s+por3(3,6,9);
  s:=s+por3(1,5,9);
  s:=s+por3(3,5,7);
  if s<>'' then
  begin
    kon:=true;
    if ((o.checked)and(s[1]='o'))or((x.checked)and(s[1]='x'))then
      Panel.caption:='Welll dan!'
    else Panel.caption:='Komputer okazal się mondrzejszy';
    start.enabled:=true;
    start.caption:='Jeszcze raz?';
    button1.visible:=true;
  end else kon:=false;
  koniec:=kon
end;

function TForm1.remis:boolean;
begin
if not koniec then
  if (p[1].caption<>'')and(p[2].caption<>'')and(p[3].caption<>'')and
     (p[4].caption<>'')and(p[5].caption<>'')and(p[6].caption<>'')and
     (p[7].caption<>'')and(p[8].caption<>'')and(p[9].caption<>'')then
    begin
      remis:=true;
      Panel.caption:='remis';
      start.enabled:=true;
      start.caption:='Jeszcze raz?';
      button1.visible:=true;
    end
  else remis:=false
end;

procedure TForm1.Button1Click(Sender: TObject);
var pytanie:word;
begin
  pytanie:= MessageDlg('Czy napewno chcesz skończyć grę? ',mtConfirmation,[mbYes,mbNo,mbCancel],0);
  case pytanie of
    mrYes:close;
    mrNo:button1.visible:=false
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
    var F: TextFile;
begin
  form1.Visible:=false;
  form2.visible:=true;

   AssignFile(F, 'instrukcja');
  Rewrite(F);
  Writeln(F, 'Just created file with this text in it...');
  CloseFile(F);

end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Close
end;

end.
0

Muszę Ci napisać, że kolega Ci źle poradził. A poza tym skoro masz zacząć od tej gry, to znaczy, że masz sam ją napisać, jaki jest sens w tym, że masz kod, skoro go nie rozumiesz ?? Właśnie napisanie przez Ciebie tej gry ma na celu naukę języka, tak, żebyś wiedział co i jak w tym działa. BTW. te wszystkie obiekty, odwołania do ich metod itp. mimo iż jest intuicyjne to jednak dla Nooba to tylko niepotrzebne zamieszanie. Żaden początkujący programista, bez nauki składni, możliwości języka nie napisze takiej gry... musisz się nauczyć języka w inny sposób, bo nikt książki dla Ciebie na forum nie napisze.

0

poczytaj najlepiej jakieś kursy z przykładami :P ja od tego zaczynałem
prosty edytor tekstu itp. ;P na gry przyjdzie czasu ;)

0

ale on napisał że nie rozumie tylko algorytmu "myślącego", a więc że mi się nudzi to tak:

każde pole ma swój indeks, plansza wygląda więc tak:

1 2 3
4 5 6
7 8 9

analizę najlepiej zacząć od d**y strony czyli zobaczyć co robią funkcję, a więc:
funkcja por1 przyjmuje trzy indeksy pól i oznaczenie pola do którego ma przyrównywać a zwraca indeks jednego z dwóch pól pustych z tych o podanych indeksach o ile w trzecim z podanych pól jest znak który podano w parametrze
jeśli nie dojdzie do sytuacji dwóch pól pustych i jednego zapełnionego przez podany znak to zwraca 0, np dla tablicy:

x o o
o x
o

i dla danych: 1, 5, 9, 'x' zwróci 0 bo znak "x" znajduje się zarówno na polu 1 jak i 5 (na dwóch polach a nie na jednym)
zaś dla danych: 3, 6, 9, 'o' zwróci 6 lub 9 (bo te są puste), ale według implementacji akurat wychodzi że zwróci to pole które jest pierwsze lub trzecie więc zwróci 9

funkcja por2 także przyjmuje trzy indeksy pól i oznaczenie a zwraca indeks pola pustego (jednego z trzech podanych) o ile pozostałe dwa są zapełnione przez podany znak (np "x"), jeżeli nie doszło do takiej sytuacji (np dwa pola z podanych są puste albo jedno jest zapełnione przez inny znak np "o") to zwraca 0
np dla tablicy powyższej i dla danych: 1, 5, 9, 'x' zwróci 9 bo to pole jest puste a pozostałe dwa zapełnione przez "x", zaś dla danych: 4, 5, 6 zwróci 0 bo w jednym z tych pól jest "o"

dalej to już po prostu zwykły (choć prosty) algorytm którego rozumienie nie zależy od rozumienia języka (może go rozumieć ktoś kto nie zna języka i może go śmiało nie rozumieć ten kto język zna):

najpierw sprawdzane jest czy w której z linii (poziomych, pionowych lub ukośnych) jest sytuacja uszczęśliwiająca funkcję por2 (czyli jedno pole puste a pozostałe zapełnione przez znak komputera), jeśli tak to właśnie w to miejsce komputer postawi swój znaczek (a := por2(a, b, c, z)) co jest akurat zrozumiałe - stawia trzeci znak żeby wygrać grę

jeśli natomiast taka sytuacja się nie pojawi to sprawdza czy jest sytuacja "kryzysowa" - czyli czy gdzieś nie ma takiej samej sytuacji ale dla znaku przeciwnika (gracza) - jeśli tak to stawia tam swój znak żeby zablokować wygranę gracza

gdy nie ma takiej linii to komputer sprawdza linie dla swojego znaku i stawia punkcik w tej linii w której jest już jego znak a nie ma jeszcze znaczku gracza

gdy nie zaszła żadna z powyższych sytuacji to komputer stawia znaczek w tej linii, w której gracz już postawił swój znak a pozostałe dwa pola są puste (sprawdzanie funkcją por1 dla znaku gracza)

gdy żadna z sytuacji nie zaszła:

if a<>0 then begin
//
end else komp1; // <--

to komputer wstawia znaczek w losowe miejsce na planszy (to dzieje się już w funkcji komp1 która robi tylko to co powyżej). Komputer cały czas korzysta tylko z funkcji komp1 jeśli wybrano łatwy poziom trudności (czyli nic nie "myśli" tylko wstawia gdzie popadnie)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0