Iks-Oks je stara igra kojoj ovo sigurno neće biti prvo interaktivno izdanje, ali je to dobar primjer programiranja u Delphiju.

     Dakle, prvo se pobrinimo za izgled. Primjenimo sljedeće promjene osobina Form1:

Caption Iks - Oks
ClientHeight 300
ClientWidth  300
BorderIcons
  biMaximize

False
BorderStyle bsSingle
Position poScreenCenter

     Iks-Oks sam izabrao iz mnogih razloga, ali glavni je upotreba Canvas-a ( prim. prev. Platno ). Dakle, pomoću Canvas po Formu se može crtati, pisati, bojiti...
     Pomoću Canvas-a, mi ćemo nacrtati polje za igru, ispisivati znakove i križati pobjednika.

    Dakle, na tabli Event Object Inspector-a, kliknimo dvaput na OnPaint. U proceduru upišimo sljedeće:

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.Pen.Width := 1;
  Canvas.Brush.Color := clBlack;
  Canvas.MoveTo(100,0);
  Canvas.LineTo(100,300);
  Canvas.MoveTo(200,0);
  Canvas.LineTo(200,300);
  Canvas.MoveTo(0,100);
  Canvas.LineTo(300,100);
  Canvas.MoveTo(0,200);
  Canvas.LineTo(300,200);
  Ispis;
end;

     Primjetimo: MoveTo pomjera fokus do tačke M(x,y), a LineTo crta liniju od tačke M to tačke N(x1,y1). Brush.Color je boja kojom ce Canvas crtati.
     Toliko o izgledu.

     Sad pređimo na pravo programiranje. Potez se igra tako što se klikne u kvadrat u koji želimo postaviti svoj znak ( igrač ce biti X, a računar O ). Polje treba posmatrati kao matricu, te kao privatnu definišemo matricu a:

a: Array[1..9]of Integer;

     A uz nju i

k: Integer;

     Gornje lijevo polje biće a[1] i tako dalje do donjeg desnog koje je a[9]. Kad igrač odigra u određeno polje, to polje dobija vrijednost 1, a kad odigra racunar -1.  Poslije svakog poteza treba provjeriti da li je igra završena ( pobjeda, poraz ili nerješeno ). Zato kao privatnu definišemo funkciju Provjera. Kao što je rečeno u poglavlju Funkcije, funkcija vraća neku vrijednost, pa će ova funkcija vraćati vrijednost 1, 2 ... 11 ( 1 - ništa, 2 - poraz, 3 - nerješeno, 4..11 pobjeda na određenom mjestu ).

function Provjera: Integer;

A funkcija izgleda ovako:

function TForm1.Provjera: Integer;
var
  b: Array[1..8]of Integer;
  i, t: Integer;
begin
  t := 3;
  b[1] := a[1] + a[2] + a[3];
  b[2] := a[4] + a[5] + a[6];
  b[3] := a[7] + a[8] + a[9];
  b[4] := a[1] + a[4] + a[7];
  b[5] := a[2] + a[5] + a[8];
  b[6] := a[3] + a[6] + a[9];
  b[7] := a[1] + a[5] + a[9];
  b[8] := a[7] + a[5] + a[3];
  for i := 1 to 9 do
    if a[i] = 0 then
      t := 1;
  for i := 1 to 8 do
    begin

      if b[i] = 3 then
        t := 3 + i;
      if b[i] = -3 then
        t := 2;
    end;
  Provjera := t;
end;

     Nova matrica sadrži zbirove po tri polja na kojima mora biti isti znak za pobjedu. Dakle, ako bar jedan zbir iznosi 3 ili -3 postoji pobjednik. Ako bar jedno polje nosi vrijednost 0, ono nije zauzeto, pa nije nerješeno.
     Da ne bi došlo do greške, potrebno je prije prvog poteza svakom polju dodijeliti vrijednost 0. Dakle, dvoklik na Form ( ili na tabli Events Object Inspector-a na OnCreate ):

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  for
i := 1 to 9 do
    a[i] := 0;
end;

     A kako to odigrati potez?

     To će doći malo kasnije. Prvo definišimo privatne procedure Ispis i Potez. U private pišemo:

procedure Ispis(q, w, p: Integer);
procedure Potez;

a u reference:

procedure TForm1.Ispis;
var
  s: String;
  i ,x, y: Integer;
begin
  Canvas.Brush.Color := clBtnFace;
  Canvas.Font.Color := clBlack;
  Canvas.Font.Size := 48;
  Canvas.Font.Style := [fsBold];
  for i := 1 to 9 do
    begin
      case a[i] of
        0: s := '';
        1: s := 'X';
        2: s := 'O';
      end;
      x := 25 + ((i - 1) mod 3) * 100;
      y := 15 + ((i - 1) div 3) * 100;
      Canvas.TextOut(x, y, s);
    end;
  if Provjera = 2 then
    begin
      Form1.Caption := 'Iks - Oks : Pobjeda O';
      Canvas.Pen.Width := 5;
      Canvas.Brush.Color := clBlack;
      case k of
        1: begin
             Canvas.MoveTo(10, 50);
             Canvas.LineTo(290, 50);
           end;
        2: begin
             Canvas.MoveTo(10, 150);
             Canvas.LineTo(290, 150);
           end;
        3: begin
             Canvas.MoveTo(10, 250);
             Canvas.LineTo(290, 250);
           end;
        4: begin
             Canvas.MoveTo(50, 10);
             Canvas.LineTo(50, 290);
           end;
        5: begin
             Canvas.MoveTo(150, 10);
             Canvas.LineTo(150, 290);
           end;
        6: begin
             Canvas.MoveTo(250, 10);
             Canvas.LineTo(250, 290);
           end;
        7: begin
             Canvas.MoveTo(10, 10);
             Canvas.LineTo(290, 290);
           end;
        8: begin
             Canvas.MoveTo(10, 290);
             Canvas.LineTo(290, 10);
           end;
      end;
    end;
  if Provjera = 3 then
    Form1.Caption := 'Iks - Oks : Nerjeseno';
  if Provjera > 3 then
    begin
      Form1.Caption := 'Iks - Oks : Pobjeda X';
      Canvas.Pen.Width := 5;
      Canvas.Brush.Color := clBlack;
      case (Provjera - 3) of
        1: begin
             Canvas.MoveTo(10, 50);
             Canvas.LineTo(290, 50);
           end;
        2: begin
             Canvas.MoveTo(10, 150);
             Canvas.LineTo(290, 150);
           end;
        3: begin
             Canvas.MoveTo(10, 250);
             Canvas.LineTo(290, 250);
           end;
        4: begin
             Canvas.MoveTo(50, 10);
             Canvas.LineTo(50, 290);
           end;
        5: begin
             Canvas.MoveTo(150, 10);
             Canvas.LineTo(150, 290);
           end;
        6: begin
             Canvas.MoveTo(250, 10);
             Canvas.LineTo(250, 290);
           end;
        7: begin
             Canvas.MoveTo(10, 10);
             Canvas.LineTo(290, 290);
           end;
        8: begin
             Canvas.MoveTo(10, 290);
             Canvas.LineTo(290, 10);
           end;
      end;
    end;
end;

Ovdje vidimo još neke Canvas funkcije. U proceduru FormPaint sada dodajemo:

Ispis;

Dakle, nikakva promjena na ekranu neće uticati na izgled polja.

     Procedura Potez je, ustvari, potez računara. Prvo razvijamo strategiju. Računar prvo treba da provjeri da li ima negdje mogućnost za pobjedu i, ako ima, vuče taj potez. Ako nema, gleda da li igrač ima mogućnost za pobjedu i, ako ima, zatvara. Ako nema onda igra na prvo slobodno mjesto, gledajući s lijeva na desno.

procedure TForm1.Potez;
var
  b: Array[1..8]of Integer;
  i: Integer;
  Odig, po: Boolean;
begin
  Odig := False;
  po := False;
  k := 0;
  b[1] := a[1] + a[2] + a[3];
  b[2] := a[4] + a[5] + a[6];
  b[3] := a[7] + a[8] + a[9];
  b[4] := a[1] + a[4] + a[7];
  b[5] := a[2] + a[5] + a[8];
  b[6] := a[3] + a[6] + a[9];
  b[7] := a[1] + a[5] + a[9];
  b[8] := a[3] + a[5] + a[7];
  for i := 1 to 8 do
    begin
      if b[i] = -2 then
        begin
          k := i;
          po := True;
        end;
      if (b[i] = 2) and not po then
        k := i;
    end;
  case k of
    1: begin
         if a[1] = 0 then
           a[1] := -1;
         if a[2] = 0 then
           a[2] := -1;
         if a[3] = 0 then
           a[3] := -1;
         Odig := True;
       end;
    2: begin
         if a[4] = 0 then
           a[4] := -1;
         if a[5] = 0 then
           a[5] := -1;
         if a[6] = 0 then
           a[6] := -1;
         Odig := True;
       end;
    3: begin
         if a[7] = 0 then
           a[7] := -1;
         if a[8] = 0 then
           a[8] := -1;
         if a[9] = 0 then
           a[9] := -1;
         Odig := True;
       end;
    4: begin
         if a[1] = 0 then
           a[1] := -1;
         if a[4] = 0 then
           a[4] := -1;
         if a[7] = 0 then
           a[7] := -1;
         Odig := True;
       end;
    5: begin
         if a[2] = 0 then
           a[2] := -1;
         if a[5] = 0 then
           a[5] := -1;
         if a[8] = 0 then
           a[8] := -1;
         Odig := True;
       end;
    6: begin
         if a[3] = 0 then
           a[3] := -1;
         if a[6] = 0 then
           a[6] := -1;
         if a[9] = 0 then
           a[9] := -1;
         Odig := True;
       end;
    7: begin
         if a[1] = 0 then
           a[1] := -1;
         if a[5] = 0 then
           a[5] := -1;
         if a[9] = 0 then
           a[9] := -1;
         Odig := True;
       end;
    8: begin
         if a[3] = 0 then
           a[3] := -1;
         if a[5] = 0 then
           a[5] := -1;
         if a[7] = 0 then
           a[7] := -1;
         Odig := True;
       end;
  end;
  if not Odig then
    begin
      for i := 9 downto 1 do
        if a[i] = 0 then
          k := i;
      a[k] := -1;
    end;
  Ispis;
end;

     Sad napokon dolazimo do definisanja igračevog poteza. Na Events tabli Object Inspector-a kliknimo dvaput na OnMouseDown.

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  m: Integer;
  Odig: Boolean;
begin
  if (Button = mbLeft) and (Provjera = 1) then
    begin
      Odig := False;
      m := X div 100 + 3 * (Y div 100) + 1;
      if a[m] = 0 then
        begin
          a[m] := 1;
          Odig := True;
        end;
      Ispis;
      if (Provjera = 1) and Odig then
        Potez;
    end;
end;

     Sad da izvedemo završne radove. Dodajmo TPopupMenu na Form1 i osobinu Form1 - PopupMenu promjenimo na PopupMenu1. U PopupMenu1 stavimo 'Nova igra' i 'Izlaz'. Za 'Izlaz' u Events tabli Object Inspector-a, opcija OnClick, kreiramo proceduru:

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

     Isto uradimo za 'Nova igra':

procedure TForm1.Novaigra1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 1 to 9 do
    a[i] := 0;
  i := 0;
  if Form1.Caption[Length(Form1.Caption)] = 'O' then
    i := 1;
  Form1.Caption := 'Iks - Oks';
  Form1.Color := clGreen;
  Form1.Color := clBtnFace;
  FormPaint(Sender);
  if i = 0 then
    Potez;
end;

     To bi bilo to. A ovako bi to trebalo da izgleda u radu:


Download