3
* \brief Impl�mentation des classes symbole_morpion et etat_morpion.
10
template<> const int claw::ai::game::game_state<int>::s_min_score = -100;
11
template<> const int claw::ai::game::game_state<int>::s_max_score = 100;
13
//*********************** symbole_morpion ************************************
15
/*--------------------------------------------------------------------------*/
17
* \brief Constructeur.
19
symbole_morpion::symbole_morpion()
23
} // symbole_morpion() [constructeur]
25
/*--------------------------------------------------------------------------*/
27
* \brief Constructeur avec un symbole.
29
symbole_morpion::symbole_morpion(symbole symb)
33
} // symbole_morpion(s) [constructeur]
35
/*--------------------------------------------------------------------------*/
37
* \brief Op�rateur d'�galit�.
39
bool symbole_morpion::operator==(const symbole_morpion& symb) const
44
/*--------------------------------------------------------------------------*/
46
* \brief Op�rateur de diff�rence.
48
bool symbole_morpion::operator!=(const symbole_morpion& symb) const
50
return !(s == symb.s);
53
/*--------------------------------------------------------------------------*/
55
* \brief Symbole oppos�.
57
symbole symbole_morpion::operator!() const
61
case EM_CROIX : return EM_ROND;
62
case EM_ROND : return EM_CROIX;
63
default : return EM_RIEN;
67
/*--------------------------------------------------------------------------*/
69
* \brief Forme textuelle.
70
* \param os Flux sur lequel �crire.
71
* \param symb symbole � �crire.
73
std::ostream& operator<<(std::ostream& os, const symbole_morpion& symb)
77
case EM_CROIX : os << "X"; break;
78
case EM_ROND : os << "O"; break;
79
case EM_RIEN : os << "."; break;
87
//************************** etat_morpion ************************************
90
symbole_morpion etat_morpion::s_symbole_ordi;
92
/*--------------------------------------------------------------------------*/
94
* \brief Affiche un �tat sur un flux.
95
* \param os Flux sur lequel �crire.
96
* \param e Damier � afficher.
98
std::ostream& operator<<(std::ostream& os, const etat_morpion& e)
102
os << "symbole : " << e.m_symbole << std::endl;
122
/*--------------------------------------------------------------------------*/
124
* \brief Constructeur.
125
* \param symb symbole du prochain joueur.
127
etat_morpion::etat_morpion( symbole symb /*= EM_RIEN*/ )
128
: m_symbole(symb), m_cases(9, EM_RIEN)
131
} // etat_morpion() [constructeur]
133
/*--------------------------------------------------------------------------*/
135
* \brief Joue le symbole en cours dans une case et passe au symbole suivant.
136
* \param c Indice de la case.
138
bool etat_morpion::jouer( int c )
141
m_cases[c] = m_symbole;
143
ret = gagne( m_symbole );
145
m_symbole = !m_symbole;
150
/*--------------------------------------------------------------------------*/
152
* \brief Indique si le jeu est plein.
154
bool etat_morpion::plein() const
158
std::vector<symbole_morpion>::const_iterator it;
160
for (it = m_cases.begin(); (it!=m_cases.end() && ret); ++it)
161
ret = *it != EM_RIEN;
166
/*--------------------------------------------------------------------------*/
168
* \brief Affecte la valeur du symbole de l'ordi.
169
* \param symb Le nouveau symbole de l'ordi.
171
void etat_morpion::symbole_ordi( const symbole_morpion& symb )
173
s_symbole_ordi = symb;
176
/*--------------------------------------------------------------------------*/
178
* \brief Indique si l'�tat actuel est gagnant pour un symbole.
179
* \param symb Symbole qui pourrait avoir gagn�.
181
bool etat_morpion::gagne( const symbole_morpion& symb ) const
183
// lignes passant par le centre
184
if ( m_cases[4] == symb )
186
if ( (m_cases[0] == symb ) && (m_cases[8] == symb ) )
188
else if ( ( m_cases[1] == symb ) && (m_cases[7] == symb) )
190
else if ( ( m_cases[2] == symb ) && (m_cases[6] == symb) )
192
else if ( ( m_cases[3] == symb ) && (m_cases[5] == symb) )
196
// lignes partant du coin haut gauche, sauf diagonale
197
if ( m_cases[0] == symb )
199
if ( (m_cases[1] == symb ) && (m_cases[2] == symb ) )
201
else if ( ( m_cases[3] == symb ) && (m_cases[6] == symb) )
205
// lignes partant du coin bas droit, sauf diagonale
206
if ( m_cases[8] == symb )
208
if ( (m_cases[6] == symb ) && (m_cases[7] == symb ) )
210
else if ( ( m_cases[2] == symb ) && (m_cases[5] == symb) )
217
/*--------------------------------------------------------------------------*/
219
* \brief R�cup�re les valeurs des cases.
221
const std::vector<symbole_morpion>& etat_morpion::cases() const
226
/*--------------------------------------------------------------------------*/
228
* \brief Effectuer une action.
229
* \param a L'action a effectuer.
230
* \return L'�tat r�sultant de cette action.
232
etat_morpion::state* etat_morpion::do_action( const int& a ) const
234
etat_morpion* em = new etat_morpion(*this);
236
em->m_cases[a] = em->m_symbole; // on marque la case
237
em->m_symbole = !em->m_symbole; // on passe la main
242
/*--------------------------------------------------------------------------*/
244
* \brief Indique si la partie est termin�e.
246
bool etat_morpion::final() const
248
if ( gagne( m_symbole ) )
250
else if ( gagne( !m_symbole ) )
256
/*--------------------------------------------------------------------------*/
258
* \brief Calcule la liste des actions jouables depuis l'�tat actuel.
259
* \param l (sortie) Liste des coups jouables.
261
void etat_morpion::nexts_actions( std::list<int>& l ) const
263
for (int i=0; i!=9; ++i)
264
if ( m_cases[i] == EM_RIEN )
268
/*--------------------------------------------------------------------------*/
270
* Evalue l'�tat actuel, du point de vue de l'ordinateur.
272
int etat_morpion::evaluate() const
276
if ( gagne( s_symbole_ordi ) )
278
if ( gagne( !s_symbole_ordi ) )
283
else if ( gagne( !s_symbole_ordi ) )
290
score_ligne = poids_des_symboles(0, 1, 2);
291
score += score_ligne * 4;
293
score_ligne = poids_des_symboles(3, 4, 5);
294
score += score_ligne * 4;
296
score_ligne = poids_des_symboles(6, 7, 8);
297
score += score_ligne * 4;
299
score_ligne = poids_des_symboles(0, 3, 6);
300
score += score_ligne * 4;
302
score_ligne = poids_des_symboles(1, 4, 7);
303
score += score_ligne * 4;
305
score_ligne = poids_des_symboles(2, 5, 8);
306
score += score_ligne * 4;
308
score_ligne = poids_des_symboles(0, 4, 8);
309
score += score_ligne * 4;
311
score_ligne = poids_des_symboles(2, 4, 6);
312
score += score_ligne * 4;
318
/*--------------------------------------------------------------------------*/
320
* Calcule la sup�riorit� du symbole de l'ordinateur sur son contraire sur trois cases.
321
* \param a indice de la premi�re case.
322
* \param b indice de la deuxi�me case.
323
* \param c indice de la troisi�me case.
325
int etat_morpion::poids_des_symboles(int a, int b, int c) const
328
symbole_morpion contraire = !s_symbole_ordi;
330
if ( m_cases[a] == s_symbole_ordi)
332
else if ( m_cases[a] == contraire )
335
if ( m_cases[b] == s_symbole_ordi)
337
else if ( m_cases[b] == contraire )
340
if ( m_cases[c] == s_symbole_ordi)
342
else if ( m_cases[c] == contraire )
346
} // poids_des_symboles()