Um Jogo da Velha contra o oponente do Prolog (§5.3) com Java GUI

De Augusto Baffa Wiki
Ir para navegação Ir para pesquisar

Esta seção discute uma metodologia para permitir que uma GUI Java p/ o Jogo da Velha interaja com o agente de jogo Prolog para o Jogo da Velha descrito na Seção 5.3, usando um conector de dados.

Jogando o jogo da velha com o especialista Prolog

O jogo da velha pode ser iniciado executando o programa Java. Baixe o arquivo TicTacToe.jar e clique duas vezes nele. Será exibida uma caixa de diálogo semelhante a esta. O campo de texto superior é o comando que você usa para iniciar o SWI-Prolog. O campo de texto inferior é a localização exata do programa Prolog de Jogo da Velha ttt.pl. (Os valores já preenchidos são os do sistema do autor.)

Figura 8.4.1. Onde estão o Prolog e arquivo ttt.pl?


Clique em OK quando estiver pronto e o jogo deve aparecer. (Se não, algo está errado!)

Figura 8.4.2. Tabuleiro vazio inicial do jogo da velha


O usuário Java GUI vai primeiro. Suponha que marcamos 'X' no ponto superior direito. Prolog responde rapidamente com 'O' no centro.

Figura 8.4.3. Depois de uma rodada


O jogo continua e é um empate ou Prolog vence ...

Figura 8.4.4. Nós perdemos!


A arquitetura do conector

O programa Java para o Jogo da Velha inicia uma thread p/ o servidor (Connector.class) que fornece uma conexão a outros programas em execução que se conectam à mesma porta. Para o jogo da velha, estamos usando a porta 54321. Cada programa que se conecta a este servidor obtém um fluxo de texto de entrada e um fluxo de texto de saída. O que quer que um cliente escreva em seu fluxo de saída é transmitido a todos os outros clientes para que eles possam ler o que foi escrito em seu fluxo de entrada.

Para o jogo da velha, o programa Java GUI player inicia o Conector, conecta-se a ele e, em seguida, inicia um processo que carrega o Prolog com o arquivo 'ttt.pl'. O programa Prolog se conecta à porta e, em seguida, os dois programas podem conversar um com o outro.

Se o Java GUI player marcar o local X, Y, o programa escreverá "(X, Y)." para seu fluxo de saída do Conector e Prolog lê este termo de seu fluxo de entrada do Conector. O Prolog registra a movimentação do Java, chama a rotina alfa-beta, obtém a melhor movimentação e grava sua movimentação no fluxo de saída do Conector (consulte o código abaixo). O Java, por sua vez, lê o movimento do Prolog e o jogo continua assim. Aqui está o código de conexão em 'ttt.pl'

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%  Play tic tac toe with the Java GUI
%%%  using port 54321.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

connect(Port) :- 
   tcp_socket(Socket), 
   gethostname(Host),  % local host
   tcp_connect(Socket,Host:Port),
   tcp_open_socket(Socket,INs,OUTs), 
   assert(connectedReadStream(INs)), 
   assert(connectedWriteStream(OUTs)).

:- connect(54321).  % Comment out for Prolog-only testing

ttt :- 
   connectedReadStream(IStream), 
     %%%% read x's move
   read(IStream,(X,Y)),
     %%%% update Prolog's board
   record(x,X,Y), 
   board(B),
     %%%% look for best next move
   alpha_beta(o,2,B,-200,200,(U,V),_Value), 
     %%%% update the board
   record(o,U,V),
   connectedWriteStream(OStream), 
     %%%%  tell Java tic tac toe player
   write(OStream,(U,V)), 
   nl(OStream), flush_output(OStream),
   ttt.

:- ttt.             % Comment out for Prolog-only testing

Segue um pequeno diagrama que exibe o Conector graficamente ...

Figura 8.4.5. O Conector


O Conector fornece uma maneira simples de conectar programas em execução que precisam se comunicar entre si. Observe que não há intercâmbio de objetos: cada cliente simplesmente escreve um texto que outro(s) cliente(s) pode(m) analisar para obter o tipo de dados necessário.


Suponha que 'TicTacToe.java' e 'Connector.java' sejam baixados em uma pasta. Então, dentro dessa pasta, compile com...

javac TicTacToe.java

e execute a partir da linha de comando com ...

java TicTacToe <fornecer comando prolog> <fornecer caminho completo para o arquivo ttt.pl>

ou pode-se escrever um script para fazer isso.


Exercício 8.4.1. Modifique os programas do jogo da velha para que qualquer jogador possa jogar primeiro.


Exercício 8.4.2. Implemente o Conector no Prolog. É necessário que as exceções geradas pelos clientes NÃO interrompam o próprio servidor de conexão.


Exercício 8.4.3. Jogue o jogo da velha com o "especialista" Prolog e descubra como ganhar. Analise por que o jogador humano pode vencer. Em seguida, modifique o programa Prolog para que ganhe ou cause um empate, ou seja, o humano não pode mais ganhar após sua correção.


Exercício 8.4.4. (Projeto Mestre) Crie um servidor de conexão generalizado no Prolog que usa algum padrão de troca de dados, como XML, ou, melhor, XML sujeito a verificação por meio de um esquema XML. Este tipo de conexão serve então como uma maneira perfeitamente geral de conectar o Prolog a outros processos. Supõe-se que os processos manipulam objetos comuns, organizando-os dentro e fora das conexões de troca de dados. Desta forma, não há necessidade de objetos "comuns". Em vez disso, intenções "comuns" são usadas para projetar os programas que precisam se comunicar entre si; portanto, cada aplicativo usa o mesmo esquema de troca, que pode ser especificado de forma independente.


Java code:


TicTacToe.jar:


Veja Também