#include // cstring:n memcpy:lle taulukon kopiointiin ei liene // järkevää c++:n vastinetta #include #include #include #include "bonustoiminnot.hh" #include "perustoiminnot.hh" /* Etsitään mahdolliset siirtovaihtoehdot pelaajalle vuoro. Jokaista nappulaa kohti tarkastellaan viereiset 5x5 nappulaa. */ int mahdollisetsiirrot(std::vector &siirrot, Nappula vuoro, const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO]) { int maara = 0; Siirto siirto = {0, 0, 0, 0}; bool kloonauskohteet[LAUDAN_KOKO][LAUDAN_KOKO] = {{false}}; int &alkuX = siirto.alkuX; // Lyhyemmät nimet, jolloin loopit int &alkuY = siirto.alkuY; // sijoittavat koordinaatit suoraan int &loppuX = siirto.loppuX; // structiin. int &loppuY = siirto.loppuY; for (alkuX = 0; alkuX < LAUDAN_KOKO; alkuX++) { for (alkuY = 0; alkuY < LAUDAN_KOKO; alkuY++) { if (pelilauta[alkuX][alkuY] != vuoro) { // Muu kuin oma nappula continue; } for (loppuX = alkuX - 2; loppuX <= alkuX + 2; loppuX++) { for (loppuY = alkuY - 2; loppuY <= alkuY + 2; loppuY++) { if (!tarkistakoordinaatit(loppuX, loppuY)) { // Ei laudalla continue; } if (pelilauta[loppuX][loppuY] != TYHJA) { // Ei tyhjä continue; } if (siirronpituus(siirto) == 1) { // Kloonaus if (kloonauskohteet[loppuX][loppuY]) { // Jo kloonattu tänne continue; } else { kloonauskohteet[loppuX][loppuY] = true; } } // Siirto ok siirrot.push_back(siirto); maara++; } } } } return maara; } void ai_etsisiirto(Siirto &tulos, Nappula vuoro, const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO]) { // int hyvyys = ai_rekursio(tulos, vuoro, pelilauta, 1, -99, 99); // int syvyys = 0; // if (hyvyys < -2) // syvyys = 6; // else if (hyvyys < 0) // syvyys = 5; // else if (hyvyys < 5) // syvyys = 4; // else // syvyys = 3; ai_rekursio(tulos, vuoro, pelilauta, 6, -99, 99); } int ai_rekursio(Siirto &tulos, Nappula vuoro, const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO], int syvyys, int alpha, int beta) { int paras = -99; std::vector siirrot; std::vector::const_iterator iter; Nappula uusilauta[LAUDAN_KOKO][LAUDAN_KOKO] = {{TYHJA}}; if (syvyys == 0 || mahdollisetsiirrot(siirrot, vuoro, pelilauta) == 0) { int oma = 0, toinen = 0; laskepisteet(oma, toinen, pelilauta); if (vuoro == OMA) return oma - toinen; else return toinen - oma; } int i = 0; if (syvyys > 5) { // std::cout << "Depth " << syvyys << ": " << i << "/" << siirrot.size() << std::endl; } for (iter = siirrot.begin(); iter < siirrot.end(); iter++) { i++; int hyvyys; Siirto temp; Nappula uusivuoro; if (vuoro == OMA) uusivuoro = TOINEN; else uusivuoro = OMA; memcpy(uusilauta, pelilauta, sizeof(Nappula)*LAUDAN_KOKO*LAUDAN_KOKO); toteutasiirto(uusilauta, *iter); hyvyys = - ai_rekursio(temp, uusivuoro, uusilauta, syvyys - 1, - beta, - alpha); if (hyvyys > paras) { paras = hyvyys; tulos = *iter; } if (paras > alpha) { alpha = paras; } if (paras > beta) { return paras; } if (syvyys > 5) { // std::cout << "Depth " << syvyys << ": " << i << "/" << siirrot.size() << std::endl; } } return paras; } int ai_multirekursio(std::vector &tulokset, Nappula vuoro, const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO], int syvyys) { int paras = -99; std::vector siirrot; std::vector::iterator iter; Nappula uusilauta[LAUDAN_KOKO][LAUDAN_KOKO] = {{TYHJA}}; if (syvyys == 0 || mahdollisetsiirrot(siirrot, vuoro, pelilauta) == 0) { int oma = 0, toinen = 0; laskepisteet(oma, toinen, pelilauta); if (vuoro == OMA) return oma - toinen; else return toinen - oma; } for (iter = siirrot.begin(); iter < siirrot.end(); iter++) { Siirto temp; Nappula uusivuoro; if (vuoro == OMA) uusivuoro = TOINEN; else uusivuoro = OMA; memcpy(uusilauta, pelilauta, sizeof(Nappula)*LAUDAN_KOKO*LAUDAN_KOKO); toteutasiirto(uusilauta, *iter); iter->hyvyys = - ai_rekursio(temp, uusivuoro, uusilauta, syvyys - 1, -99, 99); if (iter->hyvyys > paras) paras = iter->hyvyys; } for (iter = siirrot.begin(); iter < siirrot.end(); iter++) { if (iter->hyvyys == paras) { tulokset.push_back(*iter); } } return paras; }