Slang++
O objectivo do trabalho final é o desenvolvimento de um programa para jogar o
Jogo das Damas. O trabalho deverá ser realizado em Linux, fazendo uso das
bibliotecas Slang++
, IPC++
e Utilitarios
,
distribuídas num pacote único de nome... Pacotes
. O manual
das bibliotecas está disponível em HTML ou em
PDF. O pacote está disponível para instalação e chama-se
Pacotes-1.0.tar.gz
.
O
programa a desenvolver funcionará em modo texto. I.e., não fará uso das
capacidades gráficas do ambiente XWindows (KDE) disponível no Linux. No
modo texto das consolas Linux, o ecrã correspondente à consola divide-se numa
matriz de células, cada uma das quais pode conter um caractere qualquer com
diferentes atributos (i.e., cor do fundo e cor do texto ou símbolo). Com
algum esforço é possível desenhar um tabuleiro de damas neste ambiente.
A
matriz de células do ecrã tem um número de linhas e colunas que pode variar no
tempo, i.e.: o utilizador pode redimensionar a janela da consola. No
entanto, o programa que deverá desenvolver não precisa de estar preparado para
lidar com esta possibilidade.
O trabalho divide-se em duas fases, correspondendo a duas entregas de resoluções por parte dos alunos. A primeira fase é naturalmente menos ambiciosa nos seus objectivos que a segunda fase, servindo sobretudo como incentivo à dedicação dos alunos ao trabalho o mais cedo possível. Os objectivos de cada uma das fases serão descritos mais abaixo.
O Jogo das Damas é bem conhecido. No entanto, as suas regras podem apresentar variantes. Apresentam-se aqui as regras da variante que servirá de base a este trabalho, as regras das chamadas Damas Clássicas.
O jogo desenrola-se entre 2 jogadores, sobre um tabuleiro de 8×8 (64)
casas. Essas casas são coloridas em brancas e pretas alternadamente (ou
mais genericamente, claras e escuras - tabuleiro clássico), com o quadrado
(casa) inferior direito de cor clara, ou seja a grande diagonal (escura) deve
ficar sempre à esquerda de cada jogador.
Cada jogador dispõe de 12 peças
idênticas, 12 peças brancas de um lado e 12 peças pretas do outro, colocadas nas
três primeiras filas horizontais consecutivas de cada lado do tabuleiro e sobre
as casas de cor escura. Os jogadores jogam alternadamente. A jogada
inicial cabe sempre a quem estiver com as peças brancas.
Os jogadores efectuam jogadas em alternância, uma só de cada
vez.
Cada peça existente no início do jogo (Peão) só se move para a
frente em relação ao respectivo jogador, em diagonal e em direcção ao campo
adversário, sobre as casas de cor escura, uma casa de cada vez.
Se uma
peça encontra uma peça contrária na posição imediatamente contígua e o quadrado
a seguir na mesma direcção estiver vazio, pode "saltá-la" (captura),
retirando-se imediatamente a peça capturada do tabuleiro. Este
procedimento pode repetir-se após cada salto (captura), caso logo a seguir a
peça se volte a encontrar numa situação semelhante. Assim, torna-se
possível capturar várias peças numa única jogada.
Se uma peça consegue
atingir a primeira fila de casas do campo contrário então é transformada em peça
do tipo Dama, o que em geral se realiza empilhando uma outra peça já capturada
sobre a primeira. Esta nova peça resultante (a Dama) tem movimentos mais
amplos e pode saltar e capturar sobre uma diagonal sem limitação de espaços para
o salto. A Dama pode andar para a frente e para trás mas não pode saltar
uma peça da mesma cor.
A captura é obrigatória. Duas peças juntas
(contíguas), sobre a mesma diagonal, não podem ser capturadas. O Peão pode
capturar uma Dama e uma Dama pode capturar Peões, tendo assim as duas peças o
mesmo valor para fins de captura. Se na mesma jogada se apresentar mais de
um modo de exercer captura, é obrigatório executar a jogada que capture o maior
número de peças. Além disso, se houver mais de uma situação com o mesmo
número de capturas possíveis, deve-se preferir a que contiver peças mais
poderosas (preferindo Dama a Peão) e em maior quantidade, caso isso seja
aplicável.
Numa jogada de captura é permitido passar várias vezes por uma
mesma casa vazia não sendo permitido capturar a mesma peça mais de uma vez nem
as peças capturadas podem ser retiradas do tabuleiro antes do fim da jogada de
captura.
Depois de uma jogada, a imagem do tabuleiro no ecrã deve reflectir em todo o
tempo o resultado do efeito acumulado de todas as jogadas já
realizadas.
Ganha o jogador que captura todas as peças contrárias
ou as deixa numa situação de não terem qualquer movimento
possível.
Uma situação de empate ocorre após 20 jogadas sucessivas
de damas sem que haja captura de peça. Outras situações de empate ocorrem ao fim
de cinco jogadas quando existem: (a) duas Damas de cada lado; (b) duas Damas contra uma;
(c) duas Damas
contra uma Dama e um Peão; (d) uma Dama contra uma Dama e (e) uma Dama contra Dama e
Peão.
Ambos os jogadores devem ter perfeito conhecimento da disposição e
natureza de todas as peças presentes sobre o tabuleiro, ou seja todas essas
peças devem estar visíveis e reconhecíveis.
Pretende-se neste trabalho desenvolver um Jogo das Damas com regras mais simples.
Em relação às regras descritas atrás devem ser consideradas as seguintes simplificações:
A interface do programa com o utilizador deverá ser fácil de usar,
recorrendo-se para tal à biblioteca Slang++
.
Atempadamente serão disponibilizados ficheiros executáveis oficiais, cuja interface com o utilizador deverá ser emulada pelos programas desenvolvidos pelos alunos. Sempre que surgirem dúvidas acerca do comportamento pretendido para o programa a desenvolver, os alunos deverão reproduzir o comportamento exibido pelos programas oficiais.
Os ficheiros executáveis oficiais estão disponíveis através dos comandos
damas_solitárias_oficiais
damas_oficiais
disponíveis na máquina mercurio
, no directório
/usr/local/bin/
. Em breve serão disponibilizados também a
partir de esta página.
O primeiro ficheiro executável corresponde a um jogo das damas em que alternadamente o jogador, solitário, efectua jogadas das peças brancas e pretas. O segundo ficheiro executável corresponde a um jogo das damas em que o jogador joga contra outro jogador usando um programa equivalente, e exige comunicação entre processos.
A negociação é simples. Cada um dos processos (um processo é a execução de um programa) gera um número aleatório recorrendo à
função rand()
. Depois comparam os resultados. Se forem iguais, cada um gera novo número aleatório e o tenta-se de novo.
Se forem diferentes, aquele que tiver gerado o número maior joga com as peças
brancas e é o primeiro a jogar. A função rand()
gera números pseudo-aleatórios, e portanto sempre a mesma sequência, o que pode levar a negociação a um impasse se ambos os processos começarem na mesma localização nessa sequência.
Para o evitar, deve-se começar por executar a instrução:
srand(getpid());
que levará, em princípio*, o gerador em cada processo a começar num ponto diferente da sequência de números pseudo-aleatórios.
A comunicação durante a inicialização consiste, assim, no envio e recepção de inteiros com o objectivo de determinar qual dos dois processos (e respectivo utilizador) terá o privilégio de ficar com as peças brancas. Ver exercício 2 da Aula Prática 11.
* Ou seja, continua a haver a possibilidade (remota), de os processos ficarem num impasse. Nesse caso a solução é matá-los...
Durante uma jogada, um jogador tem um papel activo e o outro tem um papel passivo. O jogador que realiza uma jogada deve movimentar uma das suas peças de acordo com as regras apresentadas atrás e o outro tem apenas de observar a jogada realizada. No final da jogada o jogador activo deve enviar ao outro os movimentos que realizou. O tabuleiro do jogador passivo deve, então, ser actualizado de acordo com os movimentos realizados pelo outro jogador.
No final de uma jogada, o jogador activo deve transmitir a seguinte informação:
O jogador passivo recebe esta mesma informação, pela mesma ordem, e utiliza-a para alterar o estado do tabuleiro, de modo a reflectir a jogada do outro jogador.
A interface é muito simples. Em vez de se descrever aqui, optou-se por disponibilizar uma versão oficial do ficheiro executável. Os alunos devem testá-lo e emular a sua interface.
Abaixo apresentam-se três exemplos de interacção do programa com o utilizador.
Figura 1: Início do jogo.
Figura 2: Captura de Peão preto.
Figura 3: Jogada realizável em mais do que um movimento (há um Peão branco sob a caixa de aviso).
Figura 4: Captura de um Peão por uma Dama (andando para trás).
O trabalho divide-se em duas fases, correspondendo a final da primeira à entrega intermédia prevista no método de avaliação da disciplina. A segunda fase corresponde à entrega definitiva.
Corresponde a um programa que serve para testar o funcionamento de algumas rotinas. As rotinas a desenvolver nesta fase do trabalho são as seguintes:
Corresponde à implementação completa do jogo com as regras simplificadas. É possível implementar quer a versão das damas solitárias, quer a versão "normal", com parceiro remoto. No primeiro caso a nota do trabalho nunca será superior a 18 valores. É possível ainda simplificar o jogo de modo a permitir apenas um movimento por jogada, independentemente de esse movimento originar ou não uma captura. Esta simplificação implicará que o trabalho não poderá ter uma nota superior a 18 valores. Com as duas simplificações em simultâneo a nota jamais ultrapassará 17 valores.
Pacotes-1.0.tar.gz
.
Pode instalá-las na sua máquina dando os seguintes comandos:
tar -zxf Pacotes-1.0.tar.gz
cd Pacotes
make
Em seguida, dê os seguintes comandos como administrador do sistema:
Para mais informações veja a documentação.
make install
Para poder executar estes programas tem de os copiar para o seu computador e dar o seguinte comando:
chmod +x damas_*
Peca
deve ser muito simples. Não deve ter
qualquer responsabilidade de desenho no ecrã ou de interface com o
utilizador.
Celula
representa uma célula, que pode estar
ocupada ou não. Uma questão importante é se são as células que
possuem as peças, quando estão ocupadas, ou se é o tabuleiro.
Sugere-se a última solução. Nesse caso a classe célula deve ter
uma propriedade que indique qual é a peça, guardada pelo tabuleiro, que a
ocupa. A classe Celula
também não deve ter qualquer
papel na interface com o utilizador.
Tabuleiro
deve fazer o grosso do trabalho,
incluindo parte substancial da interface com o utilizador e da representação
no ecrã. No entanto, a comunicação com o opositor e o ciclo
principal das jogadas deve ser realizado pela classe Jogo
.
Jogo
representa um jogo de damas,
responsabilizando-se pelo ciclo principal do jogo (o ciclo das jogadas).
No entanto, a realização das jogadas individuais, com os seus movimentos,
é responsabilidade de classe Tabuleiro
.
Tabuleiro
tenha um conjunto de
predicados (funções membro devolvendo um valor booleano) para verificar a
possibilidade dos vários tipos de movimentos e capturas. Esses
predicados simplificam muito a escrita do restante código, nomeadamente da
operação que permite que se jogue uma jogada.
Tabuleiro
a deter o conjunto
das células do tabuleiro. Recomenda-se que detenha também o conjunto
das peças em jogo.
Tabuleiro
deve possuir apenas as operações
essenciais para poder ser usada na classe Jogo
.
Esta secção irá crescendo com outras dicas. Mantenha-se atento.
Jogo
, Tabuleiro
,
Celula
e Peca
. (2ª fase)
O Trabalho Final será resolvido em grupo. Confirme o registo do seu grupo em http://br.groups.yahoo.com/group/ip-iscte/database?method=reportRows&tbl=16.
.C
). Não é necessário
entregar qualquer relatório (nem qualquer listagem). Deve também enviar
uma mensagem de correio electrónico claramente identificada (número do grupo e
constituição) com o ficheiro fonte para Ricardo.Ribeiro@iscte.pt.
.C
);
Courier
) e, caso seja possível
fazê-lo, imprima em papel reciclado, frente-e-verso. A parte
restante do relatório deverá manter os tipos de letra (proporcionais) usados
no modelo de relatório.
As datas das orais e das inscrições nas orais serão anunciadas logo que possível.
A nota deste trabalho será dada apenas após uma discussão, individual, com cada um dos elementos do grupo. Nesta discussão qualquer elemento do grupo terá de demonstrar um total conhecimento do programa e ser capaz de operar as alterações que forem pedidas. Nessa oral poderão também ser feitas perguntas sobre a matéria em geral. A nota final poderá depender não só da qualidade do trabalho, mas também, e principalmente, da avaliação que os docentes façam da participação relativa dos alunos na feitura do trabalho.
Quaisquer funcionalidades extra que não tenham sido pedidas no enunciado, tais como menus mais sofisticados etc., não serão avaliadas.
Slang++
Slang++
apresenta algumas complicações. Acontece que estas
aplicações não podem ser executadas dentro do depurador, pois fazem uso de
capacidades do terminal que este não disponibiliza. Assim, é necessário
executar o programa a depurar numa janela xterm
normal, fora do
gdb
, e depois convencer o gdb
a "agarrar-se" ao
programa já em execução. Para isso:
gdb
dentro do Emacs
, como habitualmente,
especificando o ficheiro a depurar. Não dê o comando r[un]
!
xterm
.
ps -auxww | grep nome_do_programa | grep
annnnn
nnnnn
é o seu número de
aluno e nome_do_programa
é o nome do programa a
depurar. Surgir-lhe-á uma lista dos processos que são instâncias do seu
programa e que lhe pertencem. É conveniente que tenha apenas um programa
em execução de modo a identificar claramente qual o PID que lhe interessa.
gdb
coloque um ponto de paragem onde for
conveniente. Em seguida dê o comando:
attach pid
pid
é o PID do
processo identificado na alínea anterior. Este comando faz com que o
gdb
passe a controlar o processo. Dê o comando:
c[ontinue]