Gra kółko i krzyżyk tym razem z algorytmem minimax

0
uses Crt;
type
     tab = array[1..3,1..3] of char;
     tab_pol = array[1..9] of byte;
var
   X,O: char;
   gra: tab;
   zajete_pola,i,j,tpoldlugosc: byte;
   tpol: tab_pol;
function Wyg(wsk_linii: tab; znak_wyg: char): boolean;
var
  r,c,z: byte;
begin
     wyg := false;

     for r := 1 to 3 do
        begin z := 0;
             for c := 1 to 3 do
                if wsk_linii[r,c] = znak_wyg then
                  z := z + 1;
             if z = 3 then begin wyg := true; { wiersz } break end;
        end;

     for c := 1 to 3 do
        begin z := 0;
             for r := 1 to 3 do
                if wsk_linii[r,c] = znak_wyg then
                  z := z + 1;
             if z = 3 then begin wyg := true; { kolumna } break end;
        end;

     z := 0;
     for r := 1 to 3 do
        if wsk_linii[r,r] = znak_wyg then z := z + 1;

     if z = 3 then wyg := true; { przekatna nr. 1 }

     z := 0;
     for r := 1 to 3 do
        if wsk_linii[r,4-r] = znak_wyg then z := z + 1;

     if z = 3 then wyg := true { przekatna nr. 2 }
end;
function MiniMax(tablica_gry: tab; znak_gracza: char; ilosc_zajetych_pol: byte): longint;
var
   m,mmx: longint;
   fi,fj: byte;
begin
      if Wyg(tablica_gry,X) = true then MiniMax := 1
      else
          if Wyg(tablica_gry,O) = true then MiniMax := -1
          else
              if ilosc_zajetych_pol = 9 then
                MiniMax := 0
              else
                  begin
                       if znak_gracza = X then znak_gracza := O else znak_gracza := X;
                       if znak_gracza = X then mmx := -10 else mmx := 10;
                       for fi := 1 to 3 do
                          for fj := 1 to 3 do
                             if tablica_gry[fi,fj] = ' ' then
                               begin
                                    tablica_gry[fi,fj] := znak_gracza;
				    m := MiniMax(tablica_gry,znak_gracza,ilosc_zajetych_pol+1);
				    tablica_gry[fi,fj] := ' ';
				    if ((mmx < m) and (znak_gracza = X)) or ((m < mmx) and (znak_gracza = O)) then
                                      mmx := m
			       end;
                       MiniMax := mmx
                  end
end;
function Nr_Wezla(w,k: byte): byte;
begin
     if k mod 3 = 0 then
       Nr_Wezla := w * k
     else
         Nr_Wezla := (w - 1) * 3 + k
end;
function RuchKomputera(tab_gry: tab; liczba_pol: byte): byte;
var
   fi,fj: byte;
   m,mmx: longint;
begin
     mmx := -10; tpoldlugosc := 0;
     for fi := 1 to 3 do
        for fj := 1 to 3 do
           if tab_gry[fi,fj] = ' ' then
             begin
                  tab_gry[fi,fj] := X;
                  liczba_pol := liczba_pol + 1;
                  m := MiniMax(tab_gry,X,liczba_pol);
                  liczba_pol := liczba_pol - 1;
                  tab_gry[fi,fj] := ' ';
                  if mmx <= m then
                    begin
                         if ((mmx < 0) and (m = 0)) or ((mmx <= 0) and (m = 1)) then
                           tpoldlugosc := 0;
                         tpoldlugosc := tpoldlugosc + 1;
                         tpol[tpoldlugosc] := Nr_Wezla(fi,fj);
                         mmx := m;
                         RuchKomputera := Nr_Wezla(fi,fj)
                    end
             end
end;
procedure Wspolrzedne(nr_pola: byte; var wsp_y,wsp_x: byte);
begin
     if nr_pola mod 3 = 0 then
       begin
            wsp_y := nr_pola div 3;
            wsp_x := 3
       end
     else
         begin
              wsp_y := (nr_pola div 3) + 1;
              wsp_x := nr_pola mod 3
         end
end;
procedure Rozgrywka(zaczyna: byte);
var
   rows,cols: integer;
begin
     repeat
          for rows := 1 to 9 do
             tpol[rows] := 0;
          
          tpoldlugosc := 0;
          
          if (zaczyna = 1) or (zajete_pola > 0) then
            begin
	             writeln('Podaj współrzędne:');
	             readln(rows,cols);
		         if gra[rows,cols] = ' ' then
		           begin
		                gra[rows,cols] := O;
			            zajete_pola := zajete_pola + 1
	               end
            end;

	  if zajete_pola < 9 then
            begin
                 if zajete_pola = 0 then
                   begin
                        repeat
                              rows := random(3) + 1;
                              cols := random(3) + 1;
                        until ((rows <> 2) and (cols <> 2)) or ((rows = 2) and (cols = 2));
                        writeln('Ruch komputera: ',rows,' i ',cols);
                        gra[rows,cols] := X;
                   end
                 else
                     Wspolrzedne(RuchKomputera(gra,zajete_pola),i,j);
                 
				 if 0 < tpoldlugosc then
                   begin
                        writeln('Numery pól zapewniające remis lub wygraną: ');
                        for i := 1 to tpoldlugosc do
                           write(tpol[i]:4);
                        writeln;

                        randomize;
                        Wspolrzedne(tpol[random(tpoldlugosc)+1],i,j);
                        writeln('Ruch komputera: ',i,' i ',j);
                        gra[i,j] := X
                   end;

                 zajete_pola := zajete_pola + 1
	    end;

          for rows := 1 to 3 do
	     begin
	          for cols := 1 to 3 do
		     write(gra[rows,cols]:4);
		  writeln
	     end;

          if Wyg(gra,O) = true then writeln('Win Player !!!')
          else
              if Wyg(gra,X) = true then writeln('Win Computer !!!')
              else
                  if zajete_pola = 9 then writeln('Draw !!!')

     until (zajete_pola = 9) or (Wyg(gra,O) = true) or (Wyg(gra,X) = true)
end;
begin
     writeln('Game - Tic-Tac-Toe');
     X := 'X'; O := 'O'; {Ps. można zamienić :)}

     gra[1,1] := ' '; gra[1,2] := ' '; gra[1,3] := ' ';
     gra[2,1] := ' '; gra[2,2] := ' '; gra[2,3] := ' ';
     gra[3,1] := ' '; gra[3,2] := ' '; gra[3,3] := ' ';

     zajete_pola := 0;
     randomize;
     Rozgrywka(1) {1 - Zaczyna gracz; 2 - Zaczyna komputer}
end.

Ps. Możecie testować i komentować :).

1

W kodzie nie ma ani jednej linijki komentarza więc bez sporego wysiłku nie da się tego kodu skomentować.
Do tego krzywo sformatowane... Oczy bolą od patrzenia.

0

Hejka
Z powodu niedociągnięć, które zauważyłem w czasie testowania programu, poprawiłem dwie funkcje.

function MiniMax(tablica_gry: tab; znak_gracza: char; ilosc_zajetych_pol: byte; var glebokosc: byte): integer;
var
   m,mmx: integer;
   fi,fj: byte;
begin
      if Wyg(tablica_gry,X) = true then MiniMax := 1
      else
          if Wyg(tablica_gry,O) = true then MiniMax := -1
          else
              if ilosc_zajetych_pol = 9 then
                MiniMax := 0
              else
                  begin
                       if znak_gracza = X then znak_gracza := O else znak_gracza := X;
                       if znak_gracza = X then mmx := -10 else mmx := 10;
                       for fi := 1 to 3 do
                          for fj := 1 to 3 do
                             if tablica_gry[fi,fj] = ' ' then
                               begin
                                    tablica_gry[fi,fj] := znak_gracza; glebokosc := glebokosc + 1;
				                    m := MiniMax(tablica_gry,znak_gracza,ilosc_zajetych_pol+1,glebokosc);
				                    tablica_gry[fi,fj] := ' ';
				                    if ((mmx < m) and (znak_gracza = X)) or ((m < mmx) and (znak_gracza = O)) then
                                      mmx := m
			                   end;
                       MiniMax := mmx
                  end
end;

i

function RuchKomputera(tab_gry: tab; liczba_pol: byte): byte;
var
   fi,fj,depth: byte;
   m,mmx: integer;
begin
     mmx := -10; tpoldlugosc := 0;
     for fi := 1 to 3 do
        begin
             for fj := 1 to 3 do
                if tab_gry[fi,fj] = ' ' then
                  begin
                       tab_gry[fi,fj] := X;
                       liczba_pol := liczba_pol + 1; depth := 0;
                       m := MiniMax(tab_gry,X,liczba_pol,depth);
                       liczba_pol := liczba_pol - 1;
                       tab_gry[fi,fj] := ' ';
                       if mmx <= m then
                         begin
                              if ((mmx < 0) and (m = 0)) or ((mmx <= 0) and (m = 1)) then
                                tpoldlugosc := 0;
                              tpoldlugosc := tpoldlugosc + 1;
                              tpol[tpoldlugosc] := Nr_Wezla(fi,fj);
                              mmx := m;
                              RuchKomputera := Nr_Wezla(fi,fj);
                              if (m = 1) and (depth = 0) then
                                begin
                                     tpoldlugosc := 1;
                                     tpol[tpoldlugosc] := Nr_Wezla(fi,fj);
                                     break
                                end
                         end
                  end;
             if (m = 1) and (depth = 0) then break 
      end
end;

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