program jogo_da_velha;

const
  VAZIO=' ';
  EMPATE='*';

type
  T_Tabuleiro = record
                  tab:array [1..3, 1..3] of char;
                  jogada:integer;
                  ultimo:char;
                end;

procedure inicializa_jogo(var Jogo:T_Tabuleiro);
var
  l,c:integer;
begin
  for l:=1 to 3
  do for c:=1 to 3
     do Jogo.tab[l,c]:=VAZIO;
  Jogo.jogada:=0;
  Jogo.ultimo:=VAZIO;
end;

function fim_de_jogo(Jogo:T_Tabuleiro):char;
begin
  { Linha Superior }
  if (Jogo.tab[1,1] = Jogo.tab[1,2]) and (Jogo.tab[1,1] = Jogo.tab[1,3]) and (Jogo.tab[1,1] <> ' ')
  then fim_de_jogo:=Jogo.tab[1,1]
  else
  { Linha do Meio }
  if (Jogo.tab[2,1] = Jogo.tab[2,2]) and (Jogo.tab[2,1] = Jogo.tab[2,3]) and (Jogo.tab[2,1] <> ' ')
  then fim_de_jogo:=Jogo.tab[2,1]
  else
  { Linha Inferior }
  if (Jogo.tab[3,1] = Jogo.tab[3,2]) and (Jogo.tab[3,1] = Jogo.tab[3,3]) and (Jogo.tab[3,1] <> ' ')
  then fim_de_jogo:=Jogo.tab[3,1]
  else
  { Coluna Inicial }
  if (Jogo.tab[1,1] = Jogo.tab[2,1]) and (Jogo.tab[1,1] = Jogo.tab[3,1]) and (Jogo.tab[1,1] <> ' ')
  then fim_de_jogo:=Jogo.tab[1,1]
  else
  { Coluna do Meio }
  if (Jogo.tab[1,2] = Jogo.tab[2,2]) and (Jogo.tab[1,2] = Jogo.tab[3,2]) and (Jogo.tab[1,2] <> ' ')
  then fim_de_jogo:=Jogo.tab[1,2]
  else
  { Coluna Final }
  if (Jogo.tab[1,3] = Jogo.tab[2,3]) and (Jogo.tab[1,3] = Jogo.tab[3,3]) and (Jogo.tab[1,3] <> ' ')
  then fim_de_jogo:=Jogo.tab[1,3]
  else
  { Diagonal Superior }
  if (Jogo.tab[1,1] = Jogo.tab[2,2]) and (Jogo.tab[1,1] = Jogo.tab[3,3]) and (Jogo.tab[1,1] <> ' ')
  then fim_de_jogo:=Jogo.tab[1,1]
  else
  { Diagonal Inferior }
  if (Jogo.tab[3,1] = Jogo.tab[2,2]) and (Jogo.tab[3,1] = Jogo.tab[1,3]) and (Jogo.tab[3,1] <> ' ')
  then fim_de_jogo:=Jogo.tab[3,1]
  else if Jogo.jogada=9
       then fim_de_jogo:=EMPATE   { Empatou    }
       else fim_de_jogo:=VAZIO;  { NÆo acabou }
end;

procedure exibe_tabuleiro(Jogo:T_Tabuleiro);
var
 l,c:integer;
begin
  writeln('+---+---+---+');
  for l:=1 to 3
  do begin
       for c:=1 to 3
       do write ('| ',Jogo.tab[l,c],' ');
       writeln('|');
       writeln('+---+---+---+');
     end;
  writeln;
end;

var
  T:T_Tabuleiro;
  J1,J2:char;
  Ganhador:char;
  NJog:integer;
  L,C:integer;
  Fim:boolean;
  LC_Valida:boolean;
begin
  writeln;
  writeln('=================================================================');
  writeln;
  writeln ('>> Jogo da Velha <<');
  writeln;
  inicializa_jogo(T);
  writeln('=> Jogador 1 come‡a o jogo.');
  repeat
    write('Escolha (O ou X): ');
    readln(J1);
  until (J1 = 'O') or (J1 = 'X');
  writeln;
  if J1 = 'O'
  then J2:= 'X'
  else J2:= 'O';
  writeln('Jogador 1 = ',J1);
  writeln('Jogador 2 = ',J2);
  writeln;
  Fim:=false;
  while not(Fim)
  do begin
       T.jogada:=T.jogada+1;
       if odd(T.jogada)
       then begin
              writeln('Jogador 1 (',J1,') :');
              T.ultimo:=J1;
            end
       else begin
              writeln('Jogador 2 (',J2,') :');
              T.ultimo:=J2;
            end;
       LC_Valida:=false;
       repeat
         write('Linha: ');
         readln(L);
         write('Coluna: ');
         readln(C);
         if (L > 3) or (L < 1) or (C > 3) or (C < 1)
         then writeln('=> Linha e coluna devem ser entre 1 e 3! Tente novamente...')
         else if T.tab[L,C] <> VAZIO
              then writeln('=> Posi‡Æo ocupada! Tente novamente...')
              else LC_Valida:=True;
       until LC_Valida;
       if odd(T.jogada)
       then T.tab[L,C]:=J1
       else T.tab[L,C]:=J2;
       exibe_tabuleiro(T);
       Ganhador:=fim_de_jogo(T);
       if Ganhador <> VAZIO
       then Fim:=true;
     end;
  if Ganhador = J1
  then writeln('Jogador 1 (',J1,') venceu!')
  else if Ganhador = J2
       then writeln('Jogador 2 (',J2,') venceu!')
       else writeln('Empate!');
  readln;
end.

