TProcuraAdversa
Algoritmos de procura adversa
Loading...
Searching...
No Matches
JogoDoGalo.cpp
Go to the documentation of this file.
1#include "JogoDoGalo.h"
2#include <stdio.h>
3
7
11
13{
14 CJogoDoGalo* clone = new CJogoDoGalo;
15 if (clone != NULL)
16 clone->Copiar(this);
17 else
18 memoriaEsgotada = true;
19 return clone;
20}
21
23{
24 tabuleiro = ((CJogoDoGalo*)objecto)->tabuleiro;
25 minimizar = ((CJogoDoGalo*)objecto)->minimizar;
26}
27
29{
31 minimizar = true;
33 for (int i = 0; i < 9; i++)
34 tabuleiro[i] = '.';
35 tamanhoCodificado = 1; // 9 posições, 2 bits cada, 18 bits cabe em 64 bits
36}
37
39{
40 CJogoDoGalo* novo;
41 if (!SolucaoCompleta()) {
42 for (int i = 0; i < 9; i++)
43 if (tabuleiro[i] == '.') {
44 sucessores.Add(novo = (CJogoDoGalo*)Duplicar());
46 return;
47 novo->minimizar = !minimizar;
48 novo->tabuleiro[i] = (minimizar ? 'x' : 'o');
49 }
51 }
52}
53
55{
56 // verificar se há três em linha
57 for (int i = 0; i < 3; i++) // verificar todas as linhas
58 if (tabuleiro[Indice(i, 0)] != '.' &&
59 tabuleiro[Indice(i, 0)] == tabuleiro[Indice(i, 1)] &&
60 tabuleiro[Indice(i, 2)] == tabuleiro[Indice(i, 1)])
61 return true;
62 for (int i = 0; i < 3; i++) // verificar todas as colunas
63 if (tabuleiro[Indice(0, i)] != '.' &&
64 tabuleiro[Indice(0, i)] == tabuleiro[Indice(1, i)] &&
65 tabuleiro[Indice(2, i)] == tabuleiro[Indice(1, i)])
66 return true;
67 // verificar diagonais
68 if (tabuleiro[Indice(0,0)] != '.' &&
69 tabuleiro[Indice(0, 0)] == tabuleiro[Indice(1, 1)] &&
70 tabuleiro[Indice(1, 1)] == tabuleiro[Indice(2, 2)])
71 return true;
72 if (tabuleiro[Indice(0, 2)] != '.' &&
73 tabuleiro[Indice(0, 2)] == tabuleiro[Indice(1, 1)] &&
74 tabuleiro[Indice(1, 1)] == tabuleiro[Indice(2, 0)])
75 return true;
76 // verificar se há espaço para mais jogadas
77 for (int i = 0; i < 9; i++)
78 if (tabuleiro[i] == '.')
79 return false; // podem ser feitas mais jogadas
80 return true; // nao ha hipotese de mais jogadas
81}
82
83const char* CJogoDoGalo::Acao(TProcuraConstrutiva* sucessor) {
84 static char str[20];
85 CJogoDoGalo* suc = (CJogoDoGalo*)sucessor;
86 int diferenca = -1;
87 // verificar que há uma só diferença
88 for (int i = 0; i < 9; i++)
89 if (tabuleiro[i] != suc->tabuleiro[i]) {
90 if (diferenca == -1)
91 diferenca = i;
92 else // duas diferenças
93 return "Inv";
94 }
95 sprintf(str, "%c%d", 'a' + diferenca % 3, 1 + diferenca / 3);
96 return str;
97}
98
100{
101 NovaLinha(); // cabeçalho
102 printf(" ");
103 for (int i = 0; i < 3; i++)
104 printf(" %c", 'A' + i);
105 for (int i = 0; i < 3; i++) {
106 NovaLinha();
107 printf("%d", i + 1);
108 for (int j = 0; j < 3; j++)
109 printf(" %c", tabuleiro[i * 3 + j]);
110 printf(" %d ", i + 1);
111 }
112 NovaLinha(); // final
113 printf(" ");
114 for (int i = 0; i < 3; i++)
115 printf(" %c", 'A' + i);
116}
117
118void CJogoDoGalo::TesteManual(const char* nome)
119{
120 instancia = { NULL, 1,1,1, NULL, NULL };
122}
123
125{
126 heuristica = 0;
127
128 if (ExisteHeuritica())
129 return heuristica;
130
131 // jogo muito pequeno, fazer so o obrigatorio
132 // ver quem ganhou
133 for (int i = 0; i < 3; i++) // verificar todas as linhas
134 if (tabuleiro[i * 3] != '.' &&
135 tabuleiro[i * 3] == tabuleiro[i * 3 + 1] &&
136 tabuleiro[i * 3 + 2] == tabuleiro[i * 3 + 1])
137 heuristica = tabuleiro[i * 3] == 'x' ? -infinito : infinito;
138 for (int i = 0; i < 3; i++) // verificar todas as colunas
139 if (tabuleiro[i] != '.' &&
140 tabuleiro[i] == tabuleiro[i + 3] &&
141 tabuleiro[i + 6] == tabuleiro[i + 3])
142 heuristica = tabuleiro[i] == 'x' ? -infinito : infinito;
143 // verificar diagonais
144 if (tabuleiro[0] != '.' && tabuleiro[0] == tabuleiro[4] && tabuleiro[4] == tabuleiro[8])
145 heuristica = tabuleiro[0] == 'x' ? -infinito : infinito;
146 if (tabuleiro[2] != '.' && tabuleiro[2] == tabuleiro[4] && tabuleiro[4] == tabuleiro[6])
147 heuristica = tabuleiro[2] == 'x' ? -infinito : infinito;
148 // ninguem ganhou, retornar 0
150}
151
152// estados repetidos num nível podem ser obtidos por ordens distintas de movimentos, para além das simetrias
155 // obter o estado normalizado, para que os estados fiquem iguais a menos de operações de simetria
156 Normalizar(tabuleiro);
158 // codificar números de 2 bits: ".xo"
159 for (int i = 0, index = 0; i < 9; i++, index += 2)
160 estado[index >> 6] |= ((uint64_t)Codigo(tabuleiro[i])) << (index & 63);
161}
162
163// métodos de normalização de um estado
164// coloca em tabuleiro o estado normalizado
165void CJogoDoGalo::Normalizar(TVector<char>& tabuleiro) {
166 int peso, atual;
167 bool alterado;
169 // obter o tabuleiro de menor peso, mediante as 3 simetrias
170 peso = atual = PesoVersao(tabuleiro);
171 do {
172 alterado = false;
173 for (int i = 0; i < 3; i++) {
174 Simetria(tabuleiro, i);
175 atual = PesoVersao(tabuleiro);
176 if (atual < peso) {
177 peso = atual;
178 alterado = true;
179 }
180 else
181 Simetria(tabuleiro, i); // repor
182 }
183 } while (alterado);
184 // percorridas todas as simetrias e nada é melhor, escolher esta
185}
186
187// peso da versão do estado
188int CJogoDoGalo::PesoVersao(TVector<char>& tabuleiro) {
189 int peso = 0;
190 for (int i = 0; i < 3; i++)
191 for (int j = 0; j < 3; j++)
192 if (tabuleiro[Indice(i, j)] == 'x')
193 peso += Indice(i, j);
194 else if (tabuleiro[Indice(i, j)] == 'o')
195 peso += Indice(i, j) * 100;
196 return peso;
197}
198
199// aplica uma simetria
200void CJogoDoGalo::Simetria(TVector<char>& tabuleiro, int eixo) {
201 if (eixo == 0) { // simetria horizontal
202 for (int i = 0; i < 3; i++)
203 for (int j = 0; j < 1; j++)
204 Troca(tabuleiro[Indice(i, j)], tabuleiro[Indice(i, 2 - j)]);
205 }
206 else if (eixo == 1) { // simetria vertical
207 for (int i = 0; i < 1; i++)
208 for (int j = 0; j < 3; j++)
209 Troca(tabuleiro[Indice(i, j)], tabuleiro[Indice(2 - i, j)]);
210 }
211 else { // simetria diagonal
212 for (int i = 0; i < 3; i++)
213 for (int j = i + 1; j < 3; j++)
214 Troca(tabuleiro[Indice(i, j)], tabuleiro[Indice(j, i)]);
215 }
216}
217
218void CJogoDoGalo::Troca(char& a, char& b) {
219 char aux = a;
220 a = b;
221 b = aux;
222}
#define OBJETO_HASHTABLE
void Sucessores(TVector< TNo > &sucessores)
Coloca em sucessores a lista de estados sucessores.
TProcuraConstrutiva * Duplicar(void)
Cria um objecto que é uma cópia deste.
void TesteManual(const char *nome)
Inicializa a interação com o utilizador.
void Debug(void)
Mostra o estado no ecrã, para debug.
int Heuristica(void)
Função para calcular quanto falta para o final, o valor da heurística.
TVector< char > tabuleiro
Definition JogoDoGalo.h:22
bool SolucaoCompleta(void)
Verifica se o estado actual é objectivo (é uma solução completa)
void Codifica(uint64_t estado[OBJETO_HASHTABLE])
Codifica o estado para um vetor de inteiros de 64 bits.
void SolucaoVazia(void)
Coloca o objecto no estado inicial da procura.
~CJogoDoGalo(void)
Definition JogoDoGalo.cpp:8
const char * Acao(TProcuraConstrutiva *sucessor)
void Copiar(TProcuraConstrutiva *objecto)
CJogoDoGalo(void)
Definition JogoDoGalo.cpp:4
bool minimizar
o jogador actual deve minimizar o custo (ou maximizar caso tenha o valor falso)
int Heuristica(void)
chamar após calcular a heurística (grava o valor, dependendo da parametrização)
bool ExisteHeuritica(void)
static int infinito
valor de infinito (vitoria/derrota), omissao 1000
Representa um estado no espaço de estados.
void NovaLinha(bool tudo=true)
void Add(Item a)
Definition TVector.h:54
int Count()
Definition TVector.h:70
virtual void Sucessores(TVector< TNo > &sucessores)
Coloca em sucessores a lista de estados sucessores.
virtual void SolucaoVazia(void)
Coloca o objecto no estado inicial da procura.
virtual void TesteManual(const char *nome)
Inicializa a interação com o utilizador.
virtual void Codifica(uint64_t estado[OBJETO_HASHTABLE])
Codifica o estado para um vetor de inteiros de 64 bits.
int heuristica
Estimativa para o custo até um estado objetivo, se disponível.
static bool memoriaEsgotada
Flag indicando problemas de memória esgotada.
static int tamanhoCodificado
Número de inteiros de 64 bits utilizados para codificar um objeto (≤ OBJETO_HASHTABLE).
static TParametro instancia
ID da instância atual, a ser utilizado em SolucaoVazia().