#include #include #include #include "perustoiminnot.hh" #include "bonustoiminnot.hh" using std::cin; using std::cout; using std::endl; /* Alustaa pelilaudan alkutilanteeseen */ void alustalauta(Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO]) { for (int x=0; x < LAUDAN_KOKO; x++) { for (int y=0; y < LAUDAN_KOKO; y++) { pelilauta[x][y] = TYHJA; } } const int n = LAUDAN_KOKO - 1; pelilauta[0][0] = VALKOINEN; pelilauta[n][n] = VALKOINEN; pelilauta[0][n] = MUSTA; pelilauta[n][0] = MUSTA; } /* Tulostaa pelilaudan tilanteen näytölle */ void tulostalauta(const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO]) { cout << " 1 2 3 4 5 6 7" << endl; for (int y=0; y < LAUDAN_KOKO; y++) { cout << y + 1 << " "; for (int x=0; x < LAUDAN_KOKO; x++) { switch (pelilauta[x][y]) { case VALKOINEN: cout << "@ "; break; case MUSTA: cout << "O "; break; default: cout << ". "; } } cout << endl; } } /* Luetaan siirto käyttäjältä. Palautetaan false jos käyttäjä tahtoo lopettaa pelin, muutoin true. */ bool luesiirto(const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO], Nappula vuoro, Siirto &tulos) { do { cout << "Anna lähtöruudun koordinaatit (x y): "; cin >> tulos.alkuX >> tulos.alkuY; if (tulos.alkuX < 0) // lopetuspyyntö return false; cout << "Anna kohderuudun koordinaatit (x y): "; cin >> tulos.loppuX >> tulos.loppuY; // Muutetaan taulukkoindekseiksi tulos.alkuX -= 1; tulos.alkuY -= 1; tulos.loppuX -= 1; tulos.loppuY -= 1; } while (!tarkistasiirto(pelilauta, vuoro, tulos)); return true; } /* Tarkistetaan siirron laillisuus */ bool tarkistasiirto(const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO], Nappula vuoro, const Siirto &siirto) { if (!tarkistakoordinaatit(siirto.alkuX, siirto.alkuY) || !tarkistakoordinaatit(siirto.loppuX, siirto.loppuY)) { cout << "Virhe: Laittomat koordinaatit." << endl; return false; } if (pelilauta[siirto.alkuX][siirto.alkuY] == TYHJA) { cout << "Virhe: Ruudussa ei ole nappulaa." << endl; return false; } if (pelilauta[siirto.alkuX][siirto.alkuY] != vuoro) { cout << "Virhe: Ruudussa oleva nappula ei kuulu vuorossa " \ "olevalle pelaajalle." << endl; return false; } if (pelilauta[siirto.loppuX][siirto.loppuY] != TYHJA || siirronpituus(siirto) > 2) { cout << "Virhe: Laiton siirto." << endl; return false; } return true; } /* Tarkistetaan koordinaattien kuuluminen laudalle. */ bool tarkistakoordinaatit(int x, int y) { if (x < 0 || x >= LAUDAN_KOKO) return false; if (y < 0 || y >= LAUDAN_KOKO) return false; return true; } /* Lasketaan siirron pituus, 1 = kloonaus, 2 = hyppy, muut = laiton */ int siirronpituus(const Siirto &siirto) { int xero = abs(siirto.alkuX - siirto.loppuX); int yero = abs(siirto.alkuY - siirto.loppuY); if (yero > xero) return yero; else return xero; } /* Toteutetaan siirto pelilauta-taulukkoon. */ void toteutasiirto(Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO], const Siirto &siirto) { Nappula vari = pelilauta[siirto.alkuX][siirto.alkuY]; pelilauta[siirto.loppuX][siirto.loppuY] = vari; if (siirronpituus(siirto) == 2) pelilauta[siirto.alkuX][siirto.alkuY] = TYHJA; /* Tutkitaan 3x3 neliö kohdepaikan ympäriltä ja vaihdetaan värit. */ for (int x = siirto.loppuX - 1; x <= siirto.loppuX + 1; x++) { for (int y = siirto.loppuY - 1; y <= siirto.loppuY + 1; y++) { // Reunapaikoissa vierekkäisiä paikkoja ei välttämättä ole. if (!tarkistakoordinaatit(x,y)) continue; if (pelilauta[x][y] != TYHJA) pelilauta[x][y] = vari; } } } /* Tarkistetaan pelin loppuminen: - pelilauta täysi - vain yhden pelaajan nappuloita tai - ei mahdollisia siirtoja vuorossaolevalla (bonus) */ bool peliloppu(Nappula vuoro, const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO]) { std::vector temp; if (mahdollisetsiirrot(temp, vuoro, pelilauta) == 0) return true; int mustia = 0, valkoisia = 0, tyhjia = 0; for (int x=0; x < LAUDAN_KOKO; x++) { for (int y=0; y < LAUDAN_KOKO; y++) { switch(pelilauta[x][y]) { case MUSTA: mustia++; break; case VALKOINEN: valkoisia++; break; default: tyhjia++; } if (mustia > 0 && valkoisia > 0 && tyhjia > 0) { return false; } } } return true; } /* Lasketaan valkoisten/mustien nappuloiden määrä laudalla, ja tallennetaan tulos referenssien kautta. */ void laskepisteet(int &valkoinen, int &musta, const Nappula pelilauta[LAUDAN_KOKO][LAUDAN_KOKO]) { valkoinen = 0; musta = 0; for (int x=0; x < LAUDAN_KOKO; x++) { for (int y=0; y < LAUDAN_KOKO; y++) { switch(pelilauta[x][y]) { case MUSTA: musta++; break; case VALKOINEN: valkoinen++; break; default: break; } } } }