You are on page 1of 29

Aplicação em Prolog para um Jogo de Tabuleiro:

Pente

Autores
André Santos Cardoso
João Nuno Ferrreira Batista
Ricardo Simão Garcez

Faculdade de Engenharia da Universidade do Porto


Departamento de Engenharia Informática

6 de Outubro de 2008
Aplicação em Prolog para um Jogo de Tabuleiro:

Pente

Autores
André Santos Cardoso — ei05090@fe.up.pt
João Nuno Ferrreira Batista — ei05031@fe.up.pt
Ricardo Simão Garcez — ei05068@fe.up.pt

Trabalho realizado no âmbito da disciplina de Programação em Lógica, do 1o semestre do 3o


ano, do Mestrado Integrado em Eng. Informática e Computação, da Faculdade de Engenharia
da Universidade do Porto

Docentes
Daniel Moura — daniel.c.moura@gmail.com
Eugénio da Costa Oliveira — eco@fe.up.pt
Luís Paulo Reis — lpreis@fe.up.pt

Faculdade de Engenharia da Universidade do Porto


Departamento de Engenharia Informática

6 de Outubro de 2008
Resumo

Este trabalho visa a implementação do jogo de tabuleiro Pente em linguagem Prolog. O Pente é
um jogo para 2 pessoas, com peças circulares cuja cor corresponde a cada um dos jogadores, que
se colocam nas intersecções de uma matriz de 19X19, sendo as linhas horizontais do tabuleiro
numeradas de 1 a 19 e as linhas verticais assinaladas por letras de A a T. O objectivo do jogo é
formar linhas com 5 peças da mesma cor, em qualquer direcção possível, sendo que o primeiro
jogador a conseguir fazê-lo ganha o jogo.
A implementação final deverá permitir os seguintes modos de jogo:

• humano – humano;

• humano – computador;

• computador – computador;

Este relatório apresentará a primeira fase do projecto, descrevendo a representação do estado


do jogo, como se processa uma jogada e como se visualiza o tabuleiro em modo de texto.
Serão apresentados os predicados em Prolog que permitem a implementação do estado do
jogo, visualização do tabuleiro e efectuar jogadas, assim como alguns algoritmos considerados
relevantes neste contexto.

Palavras-chave: Prolog, lógica, jogo, tabuleiro, Pente;

iii
Conteúdo

Resumo iii

Conteúdo iv

Lista de Figuras v

Listagens de Código vi

1 Introdução 1

2 Descrição do Problema 2
2.1 Background histórico do jogo Pente . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Regras do jogo de tabuleiro Pente . . . . . . . . . . . . . . . . . . . . . . . . 2
2.3 Nomenclatura de Algumas Formações . . . . . . . . . . . . . . . . . . . . . . 3
2.4 Restrições aplicadas para equilibrar o jogo entre brancas e pretas . . . . . . . . 4
2.5 Captura das peças do adversário . . . . . . . . . . . . . . . . . . . . . . . . . 4

3 Implementação do jogo em Prolog 7


3.1 Representação do tabuleiro/estado do jogo . . . . . . . . . . . . . . . . . . . . 7
3.2 Representação de uma Jogada . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3 Visualização do Tabuleiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4 Conclusão e Perspectivas de Desenvolvimento 11

Referências 12

A Código Implementado em Prolog i

B Exemplo de Funcionamento vi

iv
Lista de Figuras

2.1 Tabuleiro de pente, evidenciando as peças do jogo . . . . . . . . . . . . . . . . 3


2.2 Representação de um tabuleiro de Pente . . . . . . . . . . . . . . . . . . . . . 3
2.3 Primeira jogada das Brancas . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4 Captura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.1 Antes da jogada das Pretas . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.2 Depois da jogada das Pretas as peças são capturadas . . . . . . . . . . . 5
2.4.3 Estado final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5 Captura Múltipla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5.1 Antes da jogada das Pretas . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5.2 Depois da jogada das Pretas as peças são capturadas . . . . . . . . . . . 6
2.5.3 Estado final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

B.1 Apresentação do tabuleiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi


B.2 Jogada das Brancas, Risco de Captura . . . . . . . . . . . . . . . . . . . . . . vii
B.3 Captura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii
B.4 Jogada Pretas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
B.5 Jogada Sobreposta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x

v
Listagens de Código

3.1 Representação do Tabuleiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7


3.2 Representação do Tabuleiro, após algumas jogadas. . . . . . . . . . . . . . . . 8
3.3 Predicados para as Jogadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.4 Predicados para Visualização do Tabuleiro . . . . . . . . . . . . . . . . . . . . 10
A.1 Código Prolog para o Pente . . . . . . . . . . . . . . . . . . . . . . . . . . . . i

vi
Capítulo 1

Introdução

A implementação de um jogo de tabuleiro, que não implique elementos de sorte, serve como
forma de aquisição de conhecimentos na área da programação em lógica onde, fazendo uso da
linguagem de programação Prolog, seremos introduzidos a um novo paradigma da programa-
ção que, fazendo uso das regras de lógica, será aplicado à resolução de problemas facilitando
a implementação correcta da mecânica de jogo e, numa fase mais avançada, uma inteligência
artificial que se oponha a um jogador. Importa também referir que, até este momento, utiliza-
mos quase exclusivamente linguagens de programação procedimental, sendo que este trabalho
servirá também como uma primeira abordagem séria à programação em lógica usando Prolog.
O grupo de trabalho desenvolveu o trabalho aqui apresentado em vários ambientes, nome-
adamente diferentes sistemas operativos e interpretadores de prolog: Windows/Linux e Swi-
Prolog/Sicstus Prolog.
O objectivo do trabalho é desenvolver um módulo computacional em Prolog capaz de con-
cretizar o jogo de tabuleiro Pente. Este é um jogo para 2 pessoas, no qual o objectivo é formar
linhas de cinco peças consecutivas numa qualquer direcção. Para tal, é necessário desenvolver
métodos de representar o estado do jogo em Prolog, assim como algoritmos que permitam a
visualização do tabuleiro e toda a interacção com os jogadores. Além disto, será necessário im-
plementar técnicas que permitam a inclusão de uma certa inteligência computacional de forma
a que a aplicação permita modos de jogo humano – computador e computador – computador.
Para este efeito, espera-se ainda incluir alguns algoritmos da área da Teoria dos Jogos como,
por exemplo, MiniMax.
Nesta primeira fase, interessa principalmente definir qual a representação mais adequada
para o estado do jogo em Prolog, implementar o predicado que permita a visualização correcta
do tabuleiro e os cabeçalhos dos predicados Prolog que permitam efectuar uma jogada.
As próximas secções deste documento apresentam:
• Alguma história do jogo de tabuleiro Pente;
• As regras do jogo;
• Representação do estado do jogo em Prolog;
• Representação de uma jogada em Prolog;
• Visualização do tabuleiro e código Prolog para o efectuar;
• Conclusões acerca do trabalho efectuado sob um ponto de vista crítico;
• Todo o código escrito até ao momento assim como exemplos do módulo a funcionar.

1
Capítulo 2

Descrição do Problema

O projecto baseia-se na implementação do jogo Pente para computador, utilizando Prolog como
linguagem de programação. Este é um jogo de tabuleiro para duas pessoas, cujo objectivo é
colocar as peças do jogo nas intersecções de uma matriz de 19 x 19 de forma a formar linhas de
5 peças consecutivas em qualquer direcção: horizontal, diagonal ou vertical.

2.1 Background histórico do jogo Pente


O Pente foi criado em 1987 por Gary Gabrel. Diz-se que Gary inventou o jogo durante o seu tra-
balho como lavador de pratos numa pizzaria chamada The Hideaway em Stillwater, Oklahoma.
Foi criado como uma simplificação do jogo Japonês ninuki-renju, uma variante de gomoku
jogado num tabuleiro de Go de 19 x 19 intersecções, com peças brancas e pretas. O objectivo do
jogo é formar linhas de 5 peças da mesma cor consecutivas, daí o seu nome Pente que significa
em Grego cinco (5).
A partir do jogo original, Rollie Tesh o então campeão de Pente, propôs uma mudança de
regras para equilibrar o jogo — ele afirmava que as brancas podiam sempre ganhar com um
conjunto de jogadas apropriadas — surgindo então uma variação de Pente chamada Keryo-
Pente.
A companhia Hasbro era quem detinha o direitos do jogo Pente. A Hasbro deixou de distri-
buir este jogo de tabuleiro em 1993, licenciando mais tarde o jogo à Winning Moves que trouxe
de novo o jogo às lojas em 2004 [1].

2.2 Regras do jogo de tabuleiro Pente


Neste jogo existem dois tipos de peças — brancas e pretas — correspondendo a dois jogadores
(figura 2.1).
Cada jogador tem a sua vez após uma (1) jogada do adversário.
Define-se jogada como sendo a colocação da peça do jogador correspondente numa inter-
secção vazia.
O fim do jogo atinge-se no momento em que um jogador consegue formar uma linha de
5 peças suas consecutivas numa determinada direcção ou quando consegue capturar 10 peças
do adversário. Esta situação corresponde à vitória do jogador. Por outro lado, também existe a
possibilidade do jogo acabar em empate, quando todas as intersecções do tabuleiro se encontram
usadas e nenhuma das situações anteriores se verificam. No entanto, esta é uma situação rara
devido às características do jogo relativas à captura de peças.

2
Figura 2.1: Tabuleiro de pente, evidenciando as peças do jogo

Figura 2.2: Representação de um tabuleiro de Pente

O tabuleiro do jogo é como um tabuleiro de damas, apenas maior, com 19 x 19 intersec-


ções(figura 2.2), em que as peças são jogadas não nos quadrados mas nas intersecções.

2.3 Nomenclatura de Algumas Formações


Existem algumas formações/disposições de peças que são perigosas para o adversário e que
podem levar ao fim do jogo. Estas têm nomes específicos:

Tessera É uma linha com quatro peças, com pelo menos uma ponta aberta. Existem duas
situações a analisar neste momento:

• se ambas as pontas da tessera estiverem abertas, então o jogador que formou a tes-
sera irá ganhar na jogada seguinte, a não ser que o jogador adversário consiga cap-
turar as peças do primeiro que formam a tessera.

3
Figura 2.3: Primeira jogada das
Brancas

• se apenas uma das pontas estiver aberta, então o adversário tem oportunidade de
bloquear a tessera, evitando assim a derrota.

Tria Corresponde a uma linha com três peças de uma mesma cor consecutivas, com as pontas
abertas. Esta situação está apenas a duas jogadas do Pente e da vitória do jogador. Se o
jogador adversário não bloquear uma das pontas, na jogada a seguir forma-se uma tessera
não bloqueável e o jogo encontra-se ganho.

Pente Corresponde a uma situação de vitória, em que um jogador consegue formar uma linha
com cinco das suas peças seguidas.

É habitual o jogador que consegue atingir estas formações alertar o jogador adversário da
situação[4].

2.4 Restrições aplicadas para equilibrar o jogo entre brancas


e pretas
Como o jogador que inicia o jogo poderá ter maior probabilidade de ganhar o jogo, existem
várias restrições aplicadas ao jogo de modo a equilibrar o jogo entre brancas e pretas. São as
seguintes:
• As brancas iniciam o jogo. As brancas são obrigadas a iniciar
o jogo no centro do tabuleiro1 (figura 2.3).

• A segunda jogada das brancas é feita obrigatoriamente a pelo menos três intersecções de
distância do centro do tabuleiro, onde a primeira jogada foi feita;

• Não existem restrições quanto às jogadas das peças pretas.

2.5 Captura das peças do adversário


O Pente também inclui a possibilidade da captura de pares de peças adversárias. Para poder
capturar peças adversárias, é necessário colocar as suas próprias peças nas "pontas"de uma
1 Na realidade,as regras originais publicadas pela Hasbro dizem que se deve tirar à sorte para ver qual o jogador
que começa o jogo e este deve iniciar com uma jogada no centro do tabuleiro [2]. No entanto, este projecto não se
aplica a jogos com qualquer componente de sorte, sendo esta regra posta de parte neste implementação.

4
2.4.1: Antes da jogada das Pretas 2.4.2: Depois da jogada das Pretas
as peças são capturadas

2.4.3: Estado final

Figura 2.4: Captura

linha consecutiva de peças adversárias. A captura apenas se verifica quando o jogador consegue
encurralar duas, e apenas duas, peças adversárias. É impossível capturar três peças adversárias,
por exemplo. O processo de captura está evidenciado nas figuras 2.4.1, 2.4.2 e 2.4.3.
Existe também a possibilidade de uma jogador fazer uma captura múltipla, encurralando
mais do que um par de peças adversárias (nunca vários pares de peças consecutivas), por exem-
plo, colocando uma peça sua de modo a formar um vértice comum a duas linhas de peças
adversárias, tal como está evidenciado nas figuras 2.5.1, 2.5.2 e 2.5.3.
As peças apenas podem ser capturadas por "iniciativa"do adversário, ou seja, apenas são
capturadas após uma jogada do jogador que captura. Portanto, se um jogador colocar uma peça
numa posição tal que satisfaça uma situação de captura das suas próprias peças, estas não podem
ser capturadas pelo adversário.

5
2.5.1: Antes da jogada das Pretas 2.5.2: Depois da jogada das Pretas
as peças são capturadas

2.5.3: Estado final

Figura 2.5: Captura Múltipla

6
Capítulo 3

Implementação do jogo em Prolog

Aqui se apresentam algumas estruturas em prolog escolhidas para a implementação do jogo em


Prolog, assim como algumas descrições dos algoritmos que irão ser utilizados para implementar
as jogadas.

3.1 Representação do tabuleiro/estado do jogo


Este jogo desenrola-se num tabuleiro quadrado de 19 X 19, portanto optou-se por uma repre-
sentação em Prolog através de uma lista de listas.
Listagem 3.1: Representação do Tabuleiro
tabuleiro_inicial (
[
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
4 [0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
8 [0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
12 [0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
16 [0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
20 [0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
[0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ,
]
).

A representação em 3.1 mostra o estado inicial do tabuleiro, que corresponde também à


jogada inicial das peças brancas, representadas pelo número 1. Esta jogada das brancas é obri-
gatória, portanto optou-se por incluí-la automaticamente no estado inicial dando a vez imedia-
tamente ao jogador preto.
Por exemplo, se existe nas coordenadas (1, 1) uma peça branca e em (2, 2) uma peça preta,
a estrutura que alberga a representação do tabuleiro teria os dados mostrados no código 3.2.

7
Listagem 3.2: Representação do Tabuleiro, após algumas jogadas.
tabuleiro_inicial (
[
[1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
4 [ 0 , −1, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
8 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
12 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
16 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
20 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
]
).

3.2 Representação de uma Jogada


No Pente o jogador pode efectuar uma jogada em qualquer posição do tabuleiro desde que esta
se encontre vazia (com excepção da segunda jogada das brancas), assim sendo, uma jogada
pode ser representada apenas pelo jogador que a efectua, respectivamente um 0 ou um @, e
pelas coordenadas de colocação da peça.
O processo de realização de uma jogada envolve dois passos distintos: um de validação e
um subsequente que faz definitivamente a jogada, caso seja válida.
O primeiro passo faz recurso ao predicado valida_jogada(X,Y,Tabuleiro,Incremento), onde
X e Y são as coordenadas do local onde se pretende fazer a jogada, Tabuleiro é o objecto onde
se guardam as informações do tabuleiro e o Incremento é uma variável auxiliar de modo a se
verificar se se atingiu o elemento pretendido da lista. Esta função percorre a lista de listas
Tabuleiro e verifica se o elemento que está no local em que se pretende jogar (X e Y) é um 0,
ou seja, se a intersecção estiver vazia, e não um 1 ou -1. O segundo passo recorre ao predicado
joga(X, Y, Tabuleiro, Peca, Resto, Incremento) para colocar a peça no local pretendido, sendo
a única informação adicional necessária, além da utilizada no predicado anterior, a peça, que
representa a qual dos jogadores pertence a jogada (ou -1 ou 1).
Ambos predicados são chamados pelo predicado jogar_jogador que apenas irá permitir que
uma jogada seja feita se for indicada uma jogada válida. Este e outros predicados podem ser
vistos no código 3.3.
Para já, apenas existe este tipo de verificação, onde se decide se uma jogada é válida em
determinada posição. Não se encontra implementado qualquer outro tipo de verificação como,
por exemplo, o fim do jogo ou captura de peças.
Listagem 3.3: Predicados para as Jogadas
% I n i c i a o Jogo

8
s t a r t :−
t a b u l e i r o _ i n i c i a l ( Tabuleiro ) , % Inicia o tabuleiro
4 j o g a r ( T a b u l e i r o , − 1 , 0 , 0 ) . % Comeca a j o g a r

%j o g a r (+ T a b u l e i r o ,+ Jogador ,+ ContagemJogador1 ,+ ContagemJogador2 )


8 % Tabuleiro :
% Jogador :
% ContagemJogador1 :
% ContagemJogador2 :
12

j o g a r ( T a b u l e i r o , J o g a d o r , C o n t a g e m J o g a d o r 1 , C o n t a g e m J o g a d o r 2 ) :−
C o n t a g e m J o g a d o r 1 >= 1 0 , % V e r i f i c a s e o j o g a d o r 1 ganhou
16 w r i t e ( 'Ganhou jogador 1!!! ' ) , !
;
C o n t a g e m J o g a d o r 2 >= 1 0 , % V e r i f i c a s e o j o g a d o r 2 ganhou
w r i t e ( 'Ganhou jogador 2!!! ' ) , !
20 ;
% Faz j o g a d a s
(
desenha_tabuleiro ( Tabuleiro ) ,
24 j o g a r _ j o g a d o r ( T a b u l e i r o , T a b u l e i r o F i n a l , J o g a d o r , X, Y) ,
O u t r o _ j o g a d o r i s −J o g a d o r ,
j o g a r ( T a b u l e i r o F i n a l , Outro_jogador , ContagemJogador1 ,
ContagemJogador2 )
).
28

j o g a r _ j o g a d o r ( T a b u l e i r o , T a b u l e i r o F i n a l , J o g a d o r , X, Y) :−
i f t h e n e l s e ( l e r _ j o g a d a (X, Y, J o g a d o r , T a b u l e i r o ) ,
32 w r i t e ( 'Jogada valida!' ) ,
( w r i t e ( 'Jogada invalida!' ) , nl ,
j o g a r _ j o g a d o r ( T a b u l e i r o , T a b u l e i r o F i n a l , J o g a d o r , X, Y) ) ) ,
J o g a d o r A d v e r s a r i o i s −J o g a d o r , % acho que i s t o e s t a a m a i s . . .
36 j o g a (X, Y, T a b u l e i r o , J o g a d o r , T a b u l e i r o F i n a l , 1 ) .

l e r _ j o g a d a (X, Y, J o g a d o r , T a b u l e i r o ) :−
40 w r i t e ( 'Jogador ' ) ,
w r i t e ( J o g a d o r ) , nl ,
w r i t e ( 'X:' ) ,
read (X) , nl ,
44 w r i t e ( 'Y:' ) ,
read (Y) ,
j o g a d a _ v a l i d a (X, Y, T a b u l e i r o , 1 ) .

3.3 Visualização do Tabuleiro


Para a visualização do tabuleiro, sendo este uma lista de listas em Prolog, utiliza-se um algo-
ritmo que itera sobre cada uma das listas, chamando uma outra função que itera sobre este lista
e, para cada elemento da lista, utiliza um predicada para o imprimir. Temos portanto três níveis:
iterar sobre o tabuleiro, iterar sobre uma lista do tabuleiro e imprimir um elemento do tabuleiro.
Para desenvolver estes predicados, o grupo baseou-se na implementação do jogo de damas
disponível na página da disciplina [7].

9
Os predicados que efectuam a escrita do tabuleiro em modo de texto podem ser vistos na
listagem de código 3.4.
Listagem 3.4: Predicados para Visualização do Tabuleiro
d e s e n h a _ t a b u l e i r o ( T a b u l e i r o ) :−
nl , w r i t e ( ' A B C D E F G H I J L M N O P Q R S T' ) , nl ,
( mostra_linhas (1 , Tabuleiro ) ) ,
4 write ( ' A B C D E F G H I J L M N O P Q R S T' ) , nl , ! .

%a p e n a s m o s t r a uma l i n h a com m a i s de 2 e l e m e n t o s . . . .
8 %
mostra_linhas (_ , []) .
m o s t r a _ l i n h a s (N, [ L i n h a | R e s t o ] ) :−
(N> 9 ; N<10 , w r i t e ( ' ' ) ) ,
12 w r i t e (N) , w r i t e ( ' ' ) , m o s t r a _ l i n h a ( L i n h a ) ,
w r i t e ( ' ' ) , w r i t e (N) , nl ,
N2 i s N+1 ,
m o s t r a _ l i n h a s ( N2 , R e s t o ) .
16

mostra_linha ( [ ] ) .
m o s t r a _ l i n h a ( [ E l e m e n t o | R e s t o ] ) :−
20 t r a d u z ( Elemento ) ,
mostra_linha ( Resto ) .

24 t r a d u z ( 0 ) :−
w r i t e ( '+ ' ) .

t r a d u z ( 1 ) :−
28 w r i t e ( '0 ' ) .

t r a d u z ( −1) :−
w r i t e ( '@ ' ) .

10
Capítulo 4

Conclusão e Perspectivas de
Desenvolvimento

Cremos que os objectivos propostos para esta primeira entrega se encontram atingidos: a repre-
sentação do estado do jogo encontra-se definida, a visualização do tabuleiro em modo de texto
está também concluída, além dos predicados para a colocação de peças pelo jogador que estão
também implementados.
Além do referido acima, já existem também predicados que verificam se uma jogada pode
ou não ser feita consoante a sua posição, ou seja, se a jogada não corresponde a uma casa do
tabuleiro já ocupada.
O jogo, tal como está, não inclui ainda nenhum tipo de inteligência, permitindo apenas o
jogo entre humanos. Algo que ainda falta implementar são os predicados para verificação de
fim do jogo. Portanto, o que existe neste momento corresponde a uma aplicação que mostra um
tabuleiro e permite colocar peças em posições vazias do tabuleiro, não incluindo nenhum tipo
de verificação de fim do jogo.
Além disto, iremos também substituir o mecanismo de inserção de coordenadas, de modo a
ser coerente com a representação do tabuleiro: inteiros para as linhas e letras maiúsculas para
as colunas. Até ao momento de entrega deste relatório, esta situação não foi corrigida.
Perante o trabalho efectuado, estimamos que foram atingidos cerca de 20% do trabalho
necessário para o finalizar. Os objectivos mais próximos que são necessários atingir e nos quais
o grupo centra a sua atenção de momento são a implementação dos predicados para verificação
do fim do jogo e para verificar se existe ou não uma situação de captura de peças.

11
Referências

[1] Board game encyclopedia: Pente. http://www.gaissa.com/Board_Games/modern/


Pente.htm. Breves notas históricas acerca do Pente. Consultado em Outubro de 2008.
[2] Pente, the classic game of skill. http://www.hasbro.com/common/instruct/Pente.
PDF, 1984. Regras originais do Pente. Consultado em Outubro de 2008.
[3] Pente. http://brainking.com/pt/GameRules?tp=38, 2002. Descrição do jogo Pente.
Consultado em Setembro de 2008.

[4] Pente. http://en.wikipedia.org/wiki/Pente, Setembro 2008. Desrição do jogo


Pente. Consultado em Setembro de 2008.

[5] Patrick Blackburn, Johan Bos, and Kristina Striegnitz. Learn prolog now! http://www.
coli.uni-saarland.de/~kris/learn-prolog-now/lpnpage.php?pageid=online,
2007. Tutorial online de Prolog. Consultado em Setembro de 2008.

[6] Faculdade de Engenharia da Universidade do Porto. TRABALHOS PRÁTICOS DA DIS-


CIPLINA DE PROGRAMAÇÃO EM LÓGICA, 2008. http://paginas.fe.up.pt/~eol/
LP/0809/documents/Trabalhos/Trabalhos2008_09_PL.pdf Descrição dos trabalhos
da disciplina. Consultado em Setembro de 2008.

[7] Luis Paulo Reis. Programação em lógica 2008/2009. http://paginas.fe.up.pt/~eol/


LP/0809/, 2008. Página da disciplina de Programação em Lógica. Materiais Diversos.

12
Apêndice A

Código Implementado em Prolog

Aqui se lista todo o código escrito, até ao momento, para a implementação do jogo Pente.
Listagem A.1: Código Prolog para o Pente

%D e v i d o a p r o b l e m a s com o LATEX , p o r f a v o r , nao i n c l u i r c o m e n t a r i o s com


4 %a c e n t o s ou o u t r o s c a r a c t e r e s e s p e c i a i s n e s t e f i c h e i r o !

%%%%%%%%%%%%%%%%%%%%%% TABULEIRO %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


8 %
%

12
%t a b u l e i r o de 19 x19
%o s e l e m e n t o s da l i s t a r e p r e s e n t a m i n t e r s e c c o e s ( e a m e l h o r m a n e i r a ? )
%a p r i m e i r a j o g a d a ( nao n e g o c i a v e l ) d a s b r a n c a s e no c e n t r o do t a b u l e i r o ,
16 %p o r t a n t o , o e s t a d o i n i c i a l pode c o n t a r i m e d i a t a m e n t e com e s s a j o g a d a
%
%o e s t a d o tambem tem de c o n t a r com o numero de c a p t u r a s p a r a cada j o g a d o r
%a s s i m como um v a l o r b o o l e a n o p a r a s e p o d e r d e c i d i r s e a s b r a n c a s j a podem
20 %j o g a r d e n t r o do q u a d r a d o r e s t r i c t o na p r i m e i r a j o g a d a
tabuleiro_inicial (
[
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
24 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
28 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
32 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
36 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,
40 [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0] ,

i
[0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0]
]
).
44

%%%%%%%%%%%%%%%%%%%%%%%%%% VISUALIZACAO
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

48

d e s e n h a _ t a b u l e i r o ( T a b u l e i r o ) :−
nl , w r i t e ( ' A B C D E F G H I J L M N O P Q R S T' ) , nl ,
52 ( mostra_linhas (1 , Tabuleiro ) ) ,
write ( ' A B C D E F G H I J L M N O P Q R S T' ) , nl , ! .

56 %a p e n a s m o s t r a uma l i n h a com m a i s de 2 e l e m e n t o s . . . .
%
mostra_linhas (_ , []) .
m o s t r a _ l i n h a s (N, [ L i n h a | R e s t o ] ) :−
60 (N> 9 ; N<10 , w r i t e ( ' ' ) ) ,
w r i t e (N) , w r i t e ( ' ' ) , m o s t r a _ l i n h a ( L i n h a ) ,
w r i t e ( ' ' ) , w r i t e (N) , nl ,
N2 i s N+1 ,
64 m o s t r a _ l i n h a s ( N2 , R e s t o ) .

mostra_linha ( [ ] ) .
68 m o s t r a _ l i n h a ( [ E l e m e n t o | R e s t o ] ) :−
t r a d u z ( Elemento ) ,
mostra_linha ( Resto ) .

72
t r a d u z ( 0 ) :−
w r i t e ( '+ ' ) .

76 t r a d u z ( 1 ) :−
w r i t e ( '0 ' ) .

t r a d u z ( −1) :−
80 w r i t e ( '@ ' ) .

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% JOGAR %%%%%%%%%%%%%%%%%%%%%%%%%%%%%

84
% I n i c i a o Jogo
s t a r t :−
t a b u l e i r o _ i n i c i a l ( Tabuleiro ) , % Inicia o tabuleiro
88 j o g a r ( T a b u l e i r o , − 1 , 0 , 0 ) . % Comeca a j o g a r

%j o g a r (+ T a b u l e i r o ,+ Jogador ,+ ContagemJogador1 ,+ ContagemJogador2 )


92 % Tabuleiro :
% Jogador :
% ContagemJogador1 :
% ContagemJogador2 :
96

ii
j o g a r ( T a b u l e i r o , J o g a d o r , C o n t a g e m J o g a d o r 1 , C o n t a g e m J o g a d o r 2 ) :−
C o n t a g e m J o g a d o r 1 >= 1 0 , % V e r i f i c a s e o j o g a d o r 1 ganhou
100 w r i t e ( 'Ganhou jogador 1!!! ' ) , !
;
C o n t a g e m J o g a d o r 2 >= 1 0 , % V e r i f i c a s e o j o g a d o r 2 ganhou
w r i t e ( 'Ganhou jogador 2!!! ' ) , !
104 ;
% Faz j o g a d a s
(
desenha_tabuleiro ( Tabuleiro ) ,
108 j o g a r _ j o g a d o r ( T a b u l e i r o , T a b u l e i r o F i n a l , J o g a d o r , X, Y) ,
O u t r o _ j o g a d o r i s −J o g a d o r ,
j o g a r ( T a b u l e i r o F i n a l , Outro_jogador , ContagemJogador1 ,
ContagemJogador2 )
).
112

j o g a r _ j o g a d o r ( T a b u l e i r o , T a b u l e i r o F i n a l , J o g a d o r , X, Y) :−
i f t h e n e l s e ( l e r _ j o g a d a (X, Y, J o g a d o r , T a b u l e i r o ) ,
116 w r i t e ( 'Jogada valida!' ) ,
( w r i t e ( 'Jogada invalida!' ) , nl ,
j o g a r _ j o g a d o r ( T a b u l e i r o , T a b u l e i r o F i n a l , J o g a d o r , X, Y) ) ) ,
j o g a (X, Y, T a b u l e i r o , J o g a d o r , T a b u l e i r o F i n a l , 1 ) .
120

l e r _ j o g a d a (X, Y, J o g a d o r , T a b u l e i r o ) :−
w r i t e ( 'Jogador ' ) ,
124 w r i t e ( J o g a d o r ) , nl ,
w r i t e ( 'X:' ) ,
read (X) , nl ,
w r i t e ( 'Y:' ) ,
128 read (Y) ,
j o g a d a _ v a l i d a (X, Y, T a b u l e i r o , 1 ) .

132

136

%%%%%%%%%%%%%%%%%%%%%%%%%% VALIDACAO %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

140 %j o g a d a _ v a l i d a ( X , Y , L i s t a s , I n c r e m e n t o ) .
%p e r c o r r e r o t a b u l e i r o a t e a s c o o r d e n a d a s d a d a s p a r a a j o g a d a e v e r i f i c a r
se o
%e l e m e n t o n e s s a s c o o r d e n a d a s c o r r e s p o n d e a uma c a s a v a z i a
j o g a d a _ v a l i d a ( _ , _ , [ ] , _ ) . %:− w r i t e ( ’ j o g a d a _ v a l i d a 0 ’ ) , n l .
144
% X d u p l i c a d o de modo a t e s t a r s e o s v a l o r e s da v a r i a v e i s s a o i g u a i s
j o g a d a _ v a l i d a (X, Y , [ Z | Kr ] ,X) :−
%w r i t e ( ’ j o g a d a _ v a l i d a 1 ’ ) , n l ,
148 j o g a d a _ v a l i d a _ a l t (Y, Z , 1 ) ,
X1 i s X+1 ,
j o g a d a _ v a l i d a (X, Y, Kr , X1 ) .

152

iii
j o g a d a _ v a l i d a (X, Y , [ K | Kr ] , I ) :−
%w r i t e ( ’ j o g a d a _ v a l i d a 2 ’ ) , n l ,
156 X\ = I ,
I 1 i s I +1 ,
j o g a d a _ v a l i d a (X, Y, Kr , I 1 ) .

160

%j o g a d a _ v a l i d a _ a l t ( X , L i s t a , I n c r e m e n t o )
jogada_valida_alt (_ ,[] , _) .
164
j o g a d a _ v a l i d a _ a l t (X , [ 0 | Kr ] ,X) :−
X1 i s X+1 ,
j o g a d a _ v a l i d a _ a l t (X, Kr , X1 ) .
168

j o g a d a _ v a l i d a _ a l t (X , [ K | Kr ] , I ) :−
I \ =X,
172 I 1 i s I +1 ,
j o g a d a _ v a l i d a _ a l t (X, Kr , I 1 ) .

176 %j o g a ( X , Y , T a b u l e i r o , Peca , R e s t o , I n c r e m e n t o ) .
j o g a ( _ , _ , [ ] , _ , [ ] , _ ) . %:− w r i t e ( ’ j o g a 0 ’ ) , n l .

180 j o g a (X, Y , [ K | Kr ] , Peca , [ Z | J r ] ,X) :−


%w r i t e ( ’ j o g a 1 ’ ) , n l ,
j o g a _ a l t (Y, K, Peca , Z , 1 ) ,
X1 i s X+1 ,
184 j o g a (X, Y, Kr , Peca , J r , X1 ) .

j o g a (X, Y , [ K | Kr ] , Peca , [ K | J r ] , I ) :−
188 %w r i t e ( ’ j o g a 2 ’ ) , n l ,
X\ = I ,
I 1 i s I +1 ,
j o g a (X, Y, Kr , Peca , J r , I 1 ) .
192

%j o g a _ a l t ( X , L i s t a , Peca , R e s t o , I n c r e m e n t o )
196 j o g a _ a l t ( _ , [ ] , _ , [ ] , _ ) . %:− w r i t e ( ’ j o g a _ a l t _ 0 ’ ) , n l .

j o g a _ a l t (X , [ K | Kr ] , Peca , [ P e c a | J r ] ,X) :−
%w r i t e ( ’ j o g a _ a l t _ 1 ’ ) , n l ,
200 X1 i s X+1 ,
j o g a _ a l t (X, Kr , Peca , J r , X1 ) .

204
j o g a _ a l t (X , [ K | Kr ] , Peca , [ K | J r ] , I ) :−
%w r i t e ( ’ j o g a _ a l t _ 2 ’ ) , n l ,
I \ =X,
208 I 1 i s I +1 ,
j o g a _ a l t (X, Kr , Peca , J r , I 1 ) .

iv
212 %%%%%%%%%%%%%%%%%%%%%%%%%%% F u n c o e s a u x i l i a r e s %%%%%%%%%%%%%%%%%%%%

i f t h e n e l s e (X, Y, Z ) :− X , ! , Y .
i f t h e n e l s e (X, Y, Z ) :−Z .

v
Apêndice B

Exemplo de Funcionamento

Este anexo apresenta alguns screenshots do interpretador Swi-Prolog a correr com a nossa im-
plementação de Pente.

Figura B.1: Depois de carregar o script apresentado no anexo A, inicia-se o jogo utilizando o
predicado start/0. O tabuleiro é apresentado, já com a jogada inicial das brancas, e é perguntado
ao jogador as coordenadas onde deseja jogar.

vi
Figura B.2: Esta figura mostra-nos o tabuleiro já com algumas peças colocadas. Surge agora
uma situação em que a próxima jogada das Pretas pode levar a uma situação de captura.

vii
Figura B.3: Esta figura mostra-nos uma situação onde existe captura das peças brancas que
estão encurraladas entre duas peças pretas. No entanto, este mecanismo de captura ainda não
está implementado.

viii
Figura B.4: Aqui, logo após o iniciar do jogo, as pretas jogam na casa (1, 1). Esta casa torna-se
ocupada, portanto, é impossível jogar novamente nesta mesma casa.

ix
Figura B.5: Após a jogada anterior, o jogador branco tenta jogar sobre a casa (1, 1). Esta
figura mostra como a implementação do jogo detecta essa tentativa e não o permite, voltando a
perguntar, ao mesmo jogar, uma nova casa para jogar.