%%%------------------------------------------------------------ %%% Gerenciador de campeonato %%% %%% Modificado em 14/09/99 para executar um campeonato simplificado %%% envolvendo apenas um jogador contra todos %%% os outros e vice-versa (By Z.) %%% %%% Modificado em 08/09/99 para Prolog - jogo da velha modif. %%% usamos SWI Prolog %%% Modificado em 11/08/99 para jogo de OPOSICAO %%% Modificado em 07/09/97 havia um erro que impedia que a %%% funcao GATO-INICIA fosse chamada %%% Modificado em 22/08/97 para jogo de GATOS E RATO %%% %%% Predicado principal: chama-se campeonato %%% %%% campeonato(Jogadores). %%% %%% Recebe uma lista de nomes de pacotes e promove um campeonato %%% entre os ditos cujos. Cada pacote devera' possuir as funcoes %%% necessarias para promover partidas entre os pacotes. %%% Todos jogam contra todos. %%% %%% Cada par de jogadores joga duas partidas para que cada %%% jogador tenha a chance de jogar tanto como X quanto como %%% O . O X sempre comeca. %%% Recebe lista de jogadores, executa campeonato campeonato(Jogadores) :- carrega_modulos(Jogadores), member(Jog1, Jogadores), member(Jog2, Jogadores), Jog1 \= Jog2, % carrega(Jog1), % carrega(Jog2), nl, write(Jog1), write(' versus '), write(Jog2), nl, % partida e' um predicado que nunca pode falhar da primeira vez, % mas deve sempre falhar ao ser re-satisfeita partida([0,[],[]],Jog1,Jog2,_,Result), write(Result), nl, fail. % repete ate' acabar campeonato(_) :- nl, write('Campeonato encerrado.'), nl. %%% Recebe um Jogador e uma lista de jogadores, executa campeonato campeonato(Jogador,Jogadores) :- carrega_modulos(Jogadores), member(Jog, Jogadores), Jog \= Jogador, % carrega(Jog), % carrega(Jogador), nl, write(Jogador), write(' versus '), write(Jog), nl, % partida e' um predicado que nunca pode falhar da primeira vez, % mas deve sempre falhar ao ser re-satisfeita partida([0,[],[]],Jogador,Jog,_,Result), write(Result), nl, fail. campeonato(Jogador,Jogadores) :- % carrega_modulos(Jogadores), member(Jog, Jogadores), Jog \= Jogador, % carrega(Jog), % carrega(Jogador), nl, write(Jog), write(' versus '), write(Jogador), nl, partida([0,[],[]],Jog,Jogador,_,Result), write(Result), nl, fail. % repete ate' acabar campeonato(_,_) :- nl, write('Campeonato encerrado.'), nl. %%%------------------------------------------------------------ %%% Placar-inicial: tudo zerado %%%------------------------------------------------------------ %%% Funcao registra: atualiza o placar com o resultado de uma %%% partida. Entrada: jog1 jog2 resultado placar. Saida: %%% nao importa. O importante e' o efeito colateral na variavel %%% placar. %%% Possiveis resultados: veja comentario na funcao PARTIDA %%% -------------------------------------------------- %%% Modulo gerenciador de jogo %%% Rotinas para executar uma partida % globais %%% A funcao partida recebe quatro funcoes (branco-inicia do primeiro jogador, %%% branco-responde do primeiro jogador, preto-inicia do segundo jogador, %%% preto-responde do segundo jogador) e executa uma partida entre os dois. %%% O valor retornado e' um dos seguintes: %%% [desclassificado, x ] ---> se o primeiro jogador fez invalida %%% [desclassificado, o ] ---> se o segundo jogador fez invalida %%% [vitoria, x ] ---> se o primeiro jogador ganhou %%% [vitoria, o ] ---> se o segundo jogador ganhou %%% [empate] ---> se empatar partida(Posicao, _, _, _, Result) :- decidiu(Posicao, Result), !. partida([N,X,O], Modulo_X, Modulo_O, Ultima_Jogada, Result) :- pega_vez(N, Vez), % jogo e' um predicado que nunca pode falhar % o argumento Vez deve sempre estar instanciado com x ou o jogo(Vez, N, Modulo_X, Modulo_O, Ultima_Jogada, Nova_Jogada), !, N1 is N + 1, write(N1), write('. '), write(Vez), write(' '), write(Nova_Jogada), nl, % determina_result nunca pode falhar na primeira, e % sempre deve falhar ao ser re-satisfeito determina_result([N,X,O], Modulo_X, Modulo_O, Nova_Jogada, Vez, Result). % Predicado decidiu verifica apenas se houve vitoria ou % empate. Desclassificacao fica a cargo de outros predicados. decidiu(Posicao, [vitoria, Vez]) :- ganhou(Posicao, Vez). decidiu(Posicao, [empate]) :- empatou(Posicao). ganhou([_,X,_], x) :- fez_linha(X). ganhou([_,_,O], o) :- fez_linha(O). fez_linha(Lista) :- sort(Lista, Sorted), member(Sorted, [ [1,2,3], [4,5,6], [7,8,9], [1,4,7], [2,5,8], [3,6,9], [1,5,9], [3,5,7] ]). empatou([N,_,_]) :- N >= 30. % Recebe posicao, retorna vez de quem e' pega_vez(N, x) :- 0 is N mod 2. pega_vez(N, o) :- 1 is N mod 2. % Efetua jogada. Se predicado chamado do outro modulo % falhar, instancia Nova_Jogada com o atomo 'falhou'. jogo(x, N, Modulo_X, _, _, Nova_Jogada) :- primeira_vez(N), Term =.. [x_inicia,Nova_Jogada], call(Modulo_X:Term). jogo(x, _, Modulo_X, _, Ultima_Jogada, Nova_Jogada) :- Term =.. [x_responde,Ultima_Jogada,Nova_Jogada], call(Modulo_X:Term). jogo(o, N, _, Modulo_O, Ultima_Jogada, Nova_Jogada) :- primeira_vez(N), Term =.. [o_inicia,Ultima_Jogada,Nova_Jogada], call(Modulo_O:Term). jogo(o, _, _, Modulo_O, Ultima_Jogada, Nova_Jogada) :- Term =.. [o_responde,Ultima_Jogada,Nova_Jogada], call(Modulo_O:Term). jogo(_,_,_,_,_,'falhou'). % Determina_result e' o responsavel por verificar se houve % jogada invalida ou se a partida pode prosseguir. determina_result(Posicao, Modulo_X, Modulo_O, Jogada, Vez, Result) :- valida(Posicao,Jogada,Vez), !, % atualiza nunca pode falhar na primeira chamada, % e sempre deve falhar ao ser re-satisfeito atualiza(Posicao, Jogada, Nova_Posicao), partida(Nova_Posicao, Modulo_X, Modulo_O, Jogada, Result). determina_result(_, _, _, _, Vez, [desclassificado, Vez]). %%%------------------------------------------------------------ %%% Predicado carrega: carrega o pacote de um jogador carrega_modulos(Jogadores) :- member(Jog, Jogadores), carrega(Jog), fail. carrega_modulos(_). carrega(Jogador) :- concat_atom([Jogador,'.prolog'],Filename), consult(Filename). %%%------------------------------------------------------------ %%% Os que faltam % Primeira_vez: se neste numero de posicao sera' feita % a primeira jogada do jogador de quem e' a vez primeira_vez(N) :- N =< 1. % Valida: testa se a jogada (arg.2) 'e valida na posicao (arg.1) valida([N,X,O],Jogada,Vez) :- N =< 5, !, valida_poe(X,O,Jogada,Vez). valida([_,X,O],Jogada,Vez) :- valida_move(X,O,Jogada,Vez). valida_poe(X,O,Jogada,_) :- integer(Jogada), dentro(Jogada), append(X,O,Ocupadas), \+ member(Jogada,Ocupadas). dentro(Jogada) :- 1 =< Jogada, Jogada =< 9. valida_move(X,O,[Origem,Destino],Vez) :- integer(Origem), integer(Destino), dentro(Origem), dentro(Destino), append(X,O,Ocupadas), \+ member(Destino,Ocupadas), vizinhos([Origem,Destino]), (Vez = x -> member(Origem,X) ; member(Origem,O)). vizinhos(Pair) :- sort(Pair,Sorted), member(Sorted, [[1,2],[1,4],[1,5],[2,3],[2,4],[2,5],[2,6],[3,5],[3,6], [4,5],[4,7],[4,8],[5,6],[5,7],[5,8],[5,9],[6,8],[6,9], [7,8],[8,9]]). % Atualiza: constroi nova posicao a partir da antiga e da jogada atualiza([N,X,O], Jogada, Nova_Posicao) :- N =< 5, !, atualiza_poe([N,X,O],Jogada,Nova_Posicao). atualiza(Posicao, Jogada, Nova_Posicao) :- atualiza_move(Posicao, Jogada, Nova_Posicao). atualiza_poe([N,X,O],Jogada,[N1,[Jogada|X],O]) :- 0 is N mod 2, N1 is N + 1. atualiza_poe([N,X,O],Jogada,[N1,X,[Jogada|O]]) :- 1 is N mod 2, N1 is N + 1. atualiza_move([N,X,O],[Origem,Destino],[N1,[Destino|X1],O]) :- 0 is N mod 2, N1 is N + 1, delete(X,Origem,X1). atualiza_move([N,X,O],[Origem,Destino],[N1,X,[Destino|O1]]) :- 1 is N mod 2, N1 is N + 1, delete(O,Origem,O1).