Projecto de Laboratório de Computadores

Pacman


Conteúdo


Objectivos Gerais do Trabalho

O objectivo do projecto é escrever um cliente para o jogo Pacman (ou seja, dar "inteligência" ao pacman para que ele consiga o maior número possível de pontos).

O cliente receberá do servidor uma descrição do estado do jogo (o labirinto e posições do pacman e fantasmas) e deverá responder com a direção para onde se pretende mover (esquerda, direita, cima ou baixo).

Um jogo consiste em chamadas sucessivas ao cliente, sendo que de cada vez o cliente é iniciado de novo e a descrição do estado do jogo enviada. Isto significa que o cliente não tem "memória" (se pretender garantir algum tipo de persistência de informação terá de usar algo como um ficheiro)

O objectivo do jogo é apanhar todos os bónus de um nível antes de ficar sem vidas.


Avaliação, Entrega e Apresentação

O projecto deve ser implementado por grupos de 3 elementos.


Regras do Pacman

Objectivo:

O objectivo é comer todos os bónus sem perder todas as vidas.

Tipos de entidades que circulam no labirinto:

Img Descrição
Pacman
Fantasma em modo normal
(se tocar no pacman, morre o pacman)
Fantasma em modo assustado
(se tocar no pacman, morre o fantasma e volta para uma casa de início)

Tipos de células do labirinto:

Img Char Descrição
'.' Uma célula vazia
'#' Parede não atravessável pelo Pacman ou Fantasmas
'o' Um bónus (pinta) que o pacman pode comer
'O' Um bónus (powerup) que o pacman pode comer
[durante algum tempo os fantasmas ficam em modo assustado]
'D' Uma porta para a casa dos fantasmas
[não pode ser atravessada pelo pacman]
'H' Uma possível casa de início de um fantasma
[não pode ser atravessada pelo pacman]
'P' A casa onde o pacman começa (no início ou depois de morrer uma vida)

Pontuação

O pacman consegue obter pontos do seguinte modo:

Movimento

O pacman consegue andar por todas as células excepto as paredes, portas e casas de fantasmas. Já os fantasmas apenas não conseguem andar nas paredes e em células ocupadas por outros fantasmas.

O pacman consegue passar de um lado para o outro do labirinto, isto é, ao passar para lá de uma extremidade aparece do lado oposto (se não tiver parede a impedir). O fantasma não consegue fazer este tipo de movimento.


O servidor

Ficheiros para Download

Deve ir buscar o ficheiro.jar e depois para correr o servidor basta executar o comando:

java -jar pacman_01.jar
(Nota: se tiver um erro do tipo Exception in thread "main" java.lang.UnsupportedClassVersionError: Pacman : Unsupported major.minor version 51.0 quer dizer que está a usar uma versão do Java mais antiga. Use a source para recompilar e poder executar)

Ajuda sobre linha de comandos

Se quiser ver a ajuda do servidor pode fazer:

java -jar pacman_01.jar -h

Isto disponibiliza a ajuda sobre os argumentos que pode usar ao chamar o servidor.

Alguns exemplos de execução

Supondo que foi buscar todos os ficheiros indicados anteriormente, estes seriam alguns comandos possíveis:

java -jar pacman_01.jar -l maze1.txt
(no labirinto "maze1.txt", com o pacman a ser controlado pelas setas do teclado e sem fantasmas)

java -jar pacman_01.jar -l maze1.txt -p "java -jar smart_random.jar"
(no labirinto "maze1.txt", com o pacman a ser controlado pelo cliente "smart_random.jar" e sem fantasmas)

java -jar pacman_01.jar -l maze1.txt -p "java -jar smart_random.jar" -nf 1 -f 1 "java -jar smart_random.jar"
(no labirinto "maze1.txt", com o pacman a ser controlado pelo cliente "smart_random.jar" e com 1 fantasma controlado pelo cliente "smart_random.jar")

java -jar pacman_01.jar -l maze3.txt -nf 2 -f 1 KEYSWASD -f 2 KEYSIJKL
(no labirinto "maze3.txt", com o pacman - seta - se os fantasmas - WASD e IJKL - a serem controlados pelo teclado)

java -jar pacman_01.jar -l maze2.txt -p "java -jar random.jar" -nf 1 -f 1 KEYSARROWS
(no labirinto "maze2.txt", com o pacman a ser controlado pelo cliente "random.jar" e 1 fantasma controlado pelas setas do teclado)


Labirintos

Formato de um labirinto

Um labirinto é descrito no seguinte formato:

NUM_LINHAS NUM_COLUNAS
LABLINHA_0
LABLINHA_1
LABLINHA_2
...
LABLINHA_(NUM_LINHAS-1)

Cada linha é um conjunto de NUM_COLUNAS caracteres tal como indicado na tabela dos tipos de células do labirinto:

Por exemplo, o labirinto da imagem inicial desta página seria representado da seguinte maneira:

22 23
#######################
#oooooooooo#oooooooooo#
#O###o####o#o####o###O#
#o###o####o#o####o###o#
#ooooooooooooooooooooo#
#o###o#o#######o#o###o#
#ooooo#oooo#oooo#ooooo#
#####o####.#.####o#####
#####o#.........#o#####
#####o#.###D###.#o#####
.....o..#HHHHH#..o.....
#####o#.#######.#o#####
#####o#.........#o#####
#####o#.#######.#o#####
#oooooooooo#oooooooooo#
#o###o####o#o####o###o#
#Ooo#ooooooPoooooo#ooO#
###o#o#o#######o#o#o###
#ooooo#oooo#oooo#ooooo#
#o########o#o########o#
#ooooooooooooooooooooo#
#######################

Comunicação com o servidor

Fluxo de informação

Em cada jogada (turno) o servidor arranca um novo processo cliente com o comando indicando no argumento respectivo, passando-lhe o estado do jogo através da entrada padrão (stdin) e recebendo a jogada através da saída padrão (stdout).

O cliente deve ser portanto um programa que faça o seguinte:

Em cada turno o programa do cliente é chamado de novo pelo que não mantém nada em memória. Se desejar fazer experiências com algum tipo de persistência de informação entre turnos, terá de usar armazenamento externo, escrevendo e lendo por exemplo para um ficheiro auxiliar.

Para fazer debug, deve também escrever para um ficheiro, pois o que escrever na saída padrão não será mostrado (pois irá ter ao servidor).

Mensagens do servidor para o cliente

O estado do jogo enviado para o cliente tem o seguinte formato:
(o que está a verde não vem na mensagem: é apenas uma explicação do que a linha representa)

NUM_LINHAS NUM_COLUNAS                       Descrição do labirinto
LABLINHA_0
LABLINHA_1
LABLINHA_2
...
LABLINHA_(NUM_LINHAS-1)
POS_Y_PACMAN POS_X_PACMAN                    Posição do Pacman
NUM_FANT                                     Número de fantasmas
POS_Y_FANT_1 POS_X_FANT_1                    Posição do fantasma 1
...
POS_Y_FANT_(NUM_FANT) POS_X_FANT_(NUM_FANT)  Posição do último fantasma 
TEMPO_POWERUP                                Nº de turnos até terminar efeito de powerup (0 se não ativo)
TURNO                                        Número do turno atual 
NUM_VIDAS                                    Número de vidas 
QUEM_SOU                                     0 se sou pacman, 1 a NUM_FANT se sou um fantasma
ULTIMA_DIRECAO                               Última direcção tomada por nós 

Nota que quer as linhas, quer as colunas, começam no zero.

Se quiser ver um exemplo de uma mensagem enviada espreite aqui ou aqui.

Mensagens do cliente para o servidor

O cliente deve escrever uma letra (se escrever mais do que um o servidor ignora tudo exceto o primeiro caracter). Esta letra deve ser uma das seguintes 5:


Algumas ligações

Aqui ficam algumas ligações interessantes sobre o pacman:


(Pedro Ribeiro) Última actualização: