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