ca-moes / feup-plog-proj Goto Github PK
View Code? Open in Web Editor NEWTrabalho Prático 1 de Programação em Lógica - Talpa
Trabalho Prático 1 de Programação em Lógica - Talpa
às vezes já temos predicados que criamos antes que nos podem dar jeito mas não sabemos que existem, vamos actualizando esta lista com os predicados que temos, assim quando for preciso criar um novo de nível mais alto já sabemos os que temos e quais é que podemos usar. Os predicados relativo á logica são os mais importantes e acho que para não encher muito este issue devem ficar aqui só esses.
initial_board([
[1,2,1,2,1,2,1,2],
[2,1,2,1,2,1,2,1],
[1,2,1,2,1,2,1,2],
[2,1,2,1,2,1,2,1],
[1,2,1,2,1,2,1,2],
[2,1,2,1,2,1,2,1],
[1,2,1,2,1,2,1,2],
[2,1,2,1,2,1,2,1]
]).
% Pieces codes for board representation
code(0, 32). %ascii code for space
code(2, 216). % Ø - Player 2
code(1, 215). % × - Player 1
% codes for players to pieces
player_piece('Player 1', 1).
player_piece('Player 2', 2).
% Codes for board rows
row(0, 'A').
row(1, 'B').
row(2, 'C').
row(3, 'D').
row(4, 'E').
row(5, 'F').
row(6, 'G').
row(7, 'H').
row_lower(0, 'a').
row_lower(1, 'b').
row_lower(2, 'c').
row_lower(3, 'd').
row_lower(4, 'e').
row_lower(5, 'f').
row_lower(6, 'g').
row_lower(7, 'h').
% ascii to numeral representation
code_number(48, 0).
code_number(49, 1).
code_number(50, 2).
code_number(51, 3).
code_number(52, 4).
code_number(53, 5).
code_number(54, 6).
code_number(55, 7).
code_number(56, 8).
code_number(57, 9).
% available directions
direction(1, 'up').
direction(2, 'right').
direction(3, 'down').
direction(4, 'left').
choose_piece(Board, Player, X, Y)
- usa os predicados read_inputs
, validate_choice
e available_dirs
para devolver uma posição válida em X e Y com inimigos á beira
validate_choice(Board, Xread, Yread, Player, X, Y)
- Verifica se peça selecionada é do jogador. Valores read são passados, caso sejam incorretos são pedidos outra vez dentro da função e valores válidos são retornados em X e Y. Retorna true caso valores read sejam válidos e true após arranjar valores válidos.
value_in_board(Board, X, Y, Value)
- retorna valor de (x,y) no tabuleiro
player_in_board(Board, X, Y, Player)
- retorna jogador em (x,y) no tabuleiro
available_dirs(Board, X, Y, Player, List)
- Retorna em List uma lista com as direções onde estão as peças inimigas ou vazia se não houver peças inimigas adjacentes. Esta função poderia ser feita de forma recursiva para ir a todas as direções, mas como são só 4 não há problema em ficar como está.
check_dir(Board, X, Y, PlayerS, Direction, Result)
- Verifica na direção Direction se tem uma peça inimiga de PlayerS
replace_index(I, L, E, K)
- Substitui na Lista L o valor em index I pelo valor E, originando a lista K
replace(Board, X, Y, Value, BoardResult)
- Substitui no Board, na posição mandada, o valor Value, originando BoardResult
make_choice(Board, PlayerS, X, Y, Direction, FinalBoard)
é efetuada a jogada pelo jogador PlayerS, com peça em X Y na direção Direction, resultanto no FinalBoard
Prolog é cócó, vou deixar aqui os bugs que apareceram até agora para deixar como documentação para ajudar no futuro:
Bug - Pede input, introduz input, má leitura
Solution - Caracter no buffer, skip_line trata disso
#7 (comment)
Bug - Valores não são passados corretamente para cima
Solution - Adicionar mais argumentos para passar soluções
#7 (comment)
Bug - Ao falhar uma parte do predicado, volta atrás e faz redo. Queria que predicado falhasse e cut não funcionou.
Solution - Adicionar ganda "OU" para caso falhe ou não
#7 (comment)
play/0
- O predicado principal deve ser play/0. Deve permitir visualizar um tabuleiro/estado de jogo quando invocado usando o próximo predicado
display_game(+GameState, +Player)
- Permite visualizar um tabuleiro/estado de jogo. Recebe o estado atual do jogo e o jogador que efetuará a próxima jogada.
+Player
, apenas GameState
. Qual é a lógica de receber o próximo jogador?initial(-GameState)
- Devolve o estado de jogo inicial.
initial(+Option, -GameState)
- Temos Boards de diferentes tamanhos, precisa de mais um argumento. Podemos criar um initial(-GameState)
que teria um board mas nunca seria usadovalid_moves(+GameState, +Player, -ListOfMoves)
- Obtenção de lista com jogadas possíveis
valid_moves
temos valid_removes
para o caso final do jogo em que remove uma peça em vez de mover. valid_removes
podia ser parte de valid_moves
mas seria preciso mais um argumento para distinguir.move(+GameState, +Move, -NewGameState)
- Validação e execução de uma jogada, obtendo o novo estado do jogo.
make_choice(Board, PlayerS, X, Y, Direction, FinalBoard)
. Podemos retirar o Player, este é usado para saber a peça a pôr no final da jogada e isso é possivel saber a partir de X-Y. Temos de trocar X, Y, Direction para X-Y-Directionmove(Difficulty, GameState, Player, NewGameState)
- move
está a ser usado tanto pelo jogador como pelo Computador para decidir a jogada e efetuar. Basta trocar o nomechoose_move(+GameState, +Player, +Level, -Move)
- Escolha da jogada a efetuar pelo computador, dependendo do nível de dificuldade
choose_move
está como pretendido, mas para não ter mais argumento foi feito também um choose_remove
game_over(+GameState, -Winner)
- Verificação do fim do jogo, com identificação do vencedorgame_over(+GameState, +Player , -Winner)
- Precisa de verificar primeiro se o inimigo ganhou e para isso precisa de passar o Player que fez a última jogadavalue(+GameState, +Player, -Value)
- Forma(s) de avaliação do estado do jogo.O predicado principal deve ser play/0, e deve permitir
visualizar um tabuleiro/estado de jogo quando invocado, através do predicado de
visualização, que se deverá chamar display_game(+GameState, +Player), recebendo o
estado de jogo atual, assim como o jogador que efetuará a próxima jogada
Falta mudar o código para ter display_game(GameState, Player)
a ser chamado em play
:
play :-
initial(GameState),
print_board(GameState),
start_game(GameState).
2 passagens no board:
1 - Vai celula a celula, encontra espaço branco, guarda essa posição e faz floodfill, continua a ir celula
a celula com o board floodfilled, quando encontrar outra celula branca faz o mesmo e passa o board.
Recursividade acaba quando chegar ao final do board. Retorna lista de posições X-Y
2 - Vai a cada posição e faz floodfill no board inicial, analisa o board, adiciona valor a lista,
vai a proxima posição e faz floodfill com board inicial, ...
retorna lista de valores de cada mancha
Value retorna maior dos valores de cada mancha
Predicado 1:
Percorre célula a célula
Encontra lugar 0
FloodFill para obter novo GameState, Guarda Posição X-Y para depois retornar e chama mesmo predicado
com novo GameState
Dá append a X-Y á lista de Return de ter chamado o predicado e dá return da nova lista
Caso Base: Chegou ao final do Board e Retorna Lista Vazia.
Return do Predicado: Lista da forma [X-Y,X1-Y1, ..] que contem posições por onde começar para fazer floodfill de uma mancha
Terá sempre pelo menos 1 elemento, já que avalia o board da próxima jogada. Mesmo que fosse o primeiro a jogar já abriria 1 spot vazio
Predicado 2:
Percorre cada posição da lista de cima
Faz floodfill e forma-se um board com 1 mancha
verifica quantos caracteres de fill há em cada coluna e põe numa lista [4,3,4,3,0,0]
vai row a row numa coluna Y e conta os caracteres de fill, retorna esse numero
vê qual é a maior sequencia de numeros seguidos diferentes de 0: [4,3,4,3,0,0] -> 4
Chama predicado com resto da lista
Append do Resultado a uma lista de return
Caso Base: Chegou ao final da Lista de Pontos e Retorna Lista Vazia.
Return do predicado: Uma lista de valores [X, Y, Z] com o value de cada mancha
Value retorna o maior dos values
clear
, acho que assim está bom o uso (clear no inicio de menu principal e antes de cada display do board)X, Y
para X-Y
nos lugares possíveis, por exemplo, na linha 17 de logic.pl
tem um comentário para o predicado choose_piece
logic.pl
simplificar aquilo
- Não submeteram imagens
- Regras podiam estar um pouco mais claras (caminhos/lados)
- representação ok
- Visualização poderia ficar melhor sem separação nas coordenadas, e com + nas interseções de linhas em vez de |
- predicados de visualização podia ser flexível para diferentes tamanhos de tabuleiro
- row e check... podiam ser mais declarativos
Tabuleira está vazio, falta trocar os 0's por 1 ou 2 e definir a orientação do Tabuleiro
initial_board([
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0]
]).
% códigos das peças na list
code(0, ' ').
code(1, 'X').
code(2, '+').
position_direction(1, 'up').
position_direction(2, 'right').
position_direction(3, 'down').
position_direction(4, 'left').
Sentido dos ponteiros do relógio
Preciso para agora (select_spot):
:-use_module(library(lists)).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.