Poprawione funkcje sprawdzające możliwości ruchów i bić
This commit is contained in:
@@ -69,6 +69,9 @@ public:
|
|||||||
// Czy bicie z danej pozycji jest możliwe
|
// Czy bicie z danej pozycji jest możliwe
|
||||||
bool isPossibleBeating(Vector position);
|
bool isPossibleBeating(Vector position);
|
||||||
|
|
||||||
|
// Czy istnieje możliwe bicie dla danego koloru
|
||||||
|
bool arePossibleGlobalBeatings(Color color);
|
||||||
|
|
||||||
// Kontener możliwych bić
|
// Kontener możliwych bić
|
||||||
std::list<Movement> getPossibleBeatings(Vector position);
|
std::list<Movement> getPossibleBeatings(Vector position);
|
||||||
|
|
||||||
@@ -76,7 +79,10 @@ public:
|
|||||||
std::list<Movement> getPossibleMovements(Vector position);
|
std::list<Movement> getPossibleMovements(Vector position);
|
||||||
|
|
||||||
// Pobierz możliwe ruchy wszystkich pionków danego koloru
|
// Pobierz możliwe ruchy wszystkich pionków danego koloru
|
||||||
std::list<Movement> getPossibleMovements(Color color);
|
std::list<Movement> getPossibleGlobalMovements(Color color);
|
||||||
|
|
||||||
|
// Pobierz możliwe bicia wszystkich pionków danego koloru
|
||||||
|
std::list<Movement> getPossibleGlobalBeatings(Color color);
|
||||||
|
|
||||||
// Usuń pionek z określonej pozycji
|
// Usuń pionek z określonej pozycji
|
||||||
Pawn deletePawn(Vector position);
|
Pawn deletePawn(Vector position);
|
||||||
|
|||||||
@@ -22,16 +22,13 @@ private:
|
|||||||
// Funkcja zwraca kolor kolejnego gracza z drzewa minimaks
|
// Funkcja zwraca kolor kolejnego gracza z drzewa minimaks
|
||||||
Color getColorFromDepth(int depth);
|
Color getColorFromDepth(int depth);
|
||||||
|
|
||||||
// Funkcja wyceniająca na zasadzie trzech obszarów
|
// Funkcja heurystyczna
|
||||||
int f1(Board& board, const Color& color);
|
int evaluate(Board& board, const Color& color);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Konstruktor przyjmuje parametry: maksymalna głębokość algorytmu MiniMaks oraz kolor pionków
|
// Konstruktor przyjmuje parametry: maksymalna głębokość algorytmu MiniMaks oraz kolor pionków
|
||||||
// sztucznej inteligencji
|
// sztucznej inteligencji
|
||||||
MiniMax(int depth_max, Color ai_color) : DEPTH_MAX(depth_max), AI_COLOR(ai_color) {}
|
MiniMax(int depth_max, Color ai_color) : DEPTH_MAX(depth_max), AI_COLOR(ai_color) {}
|
||||||
|
|
||||||
// Funkcja heurystyczna
|
|
||||||
int evaluate(Board& board, const Color& color) { return f1(board, color); }
|
|
||||||
|
|
||||||
// Algorytm MiniMax z cięciem alfa-beta (funkcja zwraca wartość najlepszego ruchu, natomiast
|
// Algorytm MiniMax z cięciem alfa-beta (funkcja zwraca wartość najlepszego ruchu, natomiast
|
||||||
// poprzez referencję zwraca najlepszy ruch best_movement
|
// poprzez referencję zwraca najlepszy ruch best_movement
|
||||||
|
|||||||
253
src/board.cpp
253
src/board.cpp
@@ -17,6 +17,14 @@ void Board::initBoard()
|
|||||||
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-1), CL_WHITE);
|
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-1), CL_WHITE);
|
||||||
for(int i=1; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-2), CL_WHITE);
|
for(int i=1; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-2), CL_WHITE);
|
||||||
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-3), CL_WHITE);
|
for(int i=0; i<TILES_COUNT; i=i+2) createPawn(Vector(i, TILES_COUNT-3), CL_WHITE);
|
||||||
|
|
||||||
|
createPawn(Vector(5, 4), CL_WHITE);
|
||||||
|
// createPawn(Vector(4, 4), CL_BLACK);
|
||||||
|
// createPawn(Vector(5, 3), CL_BLACK);
|
||||||
|
// createPawn(Vector(6, 4), CL_BLACK);
|
||||||
|
// createPawn(Vector(5, 5), CL_BLACK);
|
||||||
|
board[5][4]->upgrade();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pawn* Board::createPawn(Vector position, Color color)
|
Pawn* Board::createPawn(Vector position, Color color)
|
||||||
@@ -145,56 +153,15 @@ Pawn* Board::selectPawn(Vector position)
|
|||||||
|
|
||||||
bool Board::isPossibleBeating(Vector position)
|
bool Board::isPossibleBeating(Vector position)
|
||||||
{
|
{
|
||||||
// Pobieramy wskaźnik do pionka znajdującego się na zadanej pozycji
|
return getPossibleBeatings(position).size();
|
||||||
Pawn* position_pawn = getPawn(position);
|
|
||||||
|
|
||||||
// Jeżeli go tam nie ma, zwracamy false
|
|
||||||
if(!position_pawn) return false;
|
|
||||||
|
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
|
||||||
if((getPawn(position)->getPosition().x > 1 &&
|
|
||||||
getPawn(position)->getPosition().y > 1) &&
|
|
||||||
(getPawn(position)->getPosition().x < TILES_COUNT-1 &&
|
|
||||||
getPawn(position)->getPosition().y < TILES_COUNT-1))
|
|
||||||
|
|
||||||
// Jeżeli na polu przesuniętym o wektor [1,1] jest pionek, i jest on koloru przeciwnego
|
|
||||||
// a za pole zanim jest puste, zwracamy true
|
|
||||||
if(getPawn(position+Vector(1, 1)) &&
|
|
||||||
(getPawn(position+Vector(1, 1))->getColor() != position_pawn->getColor()) &&
|
|
||||||
(!getPawn(position+Vector(2, 2)))) return true;
|
|
||||||
|
|
||||||
// ... analogicznie w pozostałych kierunkach
|
|
||||||
|
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
|
||||||
if((getPawn(position)->getPosition().x > 1 &&
|
|
||||||
getPawn(position)->getPosition().y > 1) &&
|
|
||||||
(getPawn(position)->getPosition().x < TILES_COUNT-1 &&
|
|
||||||
getPawn(position)->getPosition().y < TILES_COUNT-1))
|
|
||||||
|
|
||||||
if(getPawn(position+Vector(1, -1)) &&
|
|
||||||
(getPawn(position+Vector(1, -1))->getColor() != position_pawn->getColor()) &&
|
|
||||||
(!getPawn(position+Vector(2, -2)))) return true;
|
|
||||||
|
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
|
||||||
if(getPawn(position)->getPosition().x > 1 &&
|
|
||||||
getPawn(position)->getPosition().y > 1)
|
|
||||||
|
|
||||||
if(getPawn(position+Vector(-1, 1)) &&
|
|
||||||
(getPawn(position+Vector(-1, 1))->getColor() != position_pawn->getColor()) &&
|
|
||||||
(!getPawn(position+Vector(-2, 2)))) return true;
|
|
||||||
|
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
|
||||||
if(getPawn(position)->getPosition().x > 1 &&
|
|
||||||
getPawn(position)->getPosition().y > 1)
|
|
||||||
|
|
||||||
if(getPawn(position+Vector(-1, -1)) &&
|
|
||||||
(getPawn(position+Vector(-1, -1))->getColor() != position_pawn->getColor()) &&
|
|
||||||
(!getPawn(position+Vector(-2, -2)))) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Board::arePossibleGlobalBeatings(Color color)
|
||||||
|
{
|
||||||
|
return getPossibleGlobalBeatings(color).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::list<Movement> Board::getPossibleBeatings(Vector position)
|
std::list<Movement> Board::getPossibleBeatings(Vector position)
|
||||||
{
|
{
|
||||||
// Tworzymy nowy kontener na pozycje
|
// Tworzymy nowy kontener na pozycje
|
||||||
@@ -206,28 +173,69 @@ std::list<Movement> Board::getPossibleBeatings(Vector position)
|
|||||||
// Jeżeli go tam nie ma, zwracamy pusty kontener
|
// Jeżeli go tam nie ma, zwracamy pusty kontener
|
||||||
if(!position_pawn) return beatings;
|
if(!position_pawn) return beatings;
|
||||||
|
|
||||||
// Jeżeli na polu przesuniętym o wektor [1,1] jest pionek, i jest on koloru przeciwnego
|
//// Bicie normalnymi pionkami
|
||||||
// a za pole zanim jest puste, dorzucamy tą pozycję do kontenera
|
|
||||||
if(position.x < TILES_COUNT-1 && position.y < TILES_COUNT-1)
|
|
||||||
if(getPawn(position+Vector(1, 1)) &&
|
|
||||||
(getPawn(position+Vector(1, 1))->getColor() != position_pawn->getColor()) &&
|
|
||||||
(!getPawn(position+Vector(2, 2)))) beatings.push_back(Movement(position, position+Vector(2, 2)));
|
|
||||||
|
|
||||||
// ... analogicznie w pozostałych kierunkach
|
// Bicie o wektor [-2, -2]
|
||||||
if(position.x < TILES_COUNT-1 && position.y > 1)
|
if((position.x >= 2 && position.y >= 2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
if(getPawn(position+Vector(1, -1)) &&
|
(getPawn(position+Vector(-1, -1))) && // Jeżeli istnieje bity pionek
|
||||||
(getPawn(position+Vector(1, -1))->getColor() != position_pawn->getColor()) &&
|
(getPawn(position+Vector(-1, -1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
(!getPawn(position+Vector(2, -2)))) beatings.push_back(Movement(position, position+Vector(2, -2)));
|
(!getPawn(position+Vector(-2, -2)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(-2, -2))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
if(position.x > 1 && position.y < TILES_COUNT-1)
|
// Bicie o wektor [-2, 2]
|
||||||
if(getPawn(position+Vector(-1, 1)) &&
|
if((position.x >= 2 && position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
(getPawn(position+Vector(-1, 1))->getColor() != position_pawn->getColor()) &&
|
(getPawn(position+Vector(-1, 1))) && // Jeżeli istnieje bity pionek
|
||||||
(!getPawn(position+Vector(-2, 2)))) beatings.push_back(Movement(position, position+Vector(-2, 2)));
|
(getPawn(position+Vector(-1, 1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(-2, 2)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(-2, 2))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
if(position.x > 1 && position.y > 1)
|
// Bicie o wektor [2, 2]
|
||||||
if(getPawn(position+Vector(-1, -1)) &&
|
if((position.x < TILES_COUNT-2 && position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
(getPawn(position+Vector(-1, -1))->getColor() != position_pawn->getColor()) &&
|
(getPawn(position+Vector(1, 1))) && // Jeżeli istnieje bity pionek
|
||||||
(!getPawn(position+Vector(-2, -2)))) beatings.push_back(Movement(position, position+Vector(-2, -2)));
|
(getPawn(position+Vector(1, 1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(2, 2)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(2, 2))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
|
// Bicie o wektor [2, -2]
|
||||||
|
if((position.x < TILES_COUNT-2 && position.y >= 2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
|
(getPawn(position+Vector(1, -1))) && // Jeżeli istnieje bity pionek
|
||||||
|
(getPawn(position+Vector(1, -1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(2, -2)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(2, -2))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
|
//// Bicie damkami
|
||||||
|
|
||||||
|
// Jeżeli pionek jest damką posiada dodatkowe możliwości bicia
|
||||||
|
if(getPawn(position)->isQueen())
|
||||||
|
{
|
||||||
|
// Bicie o wektor [-2, 0]
|
||||||
|
if((position.x >= 2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
|
(getPawn(position+Vector(-1, 0))) && // Jeżeli istnieje bity pionek
|
||||||
|
(getPawn(position+Vector(-1, 0))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(-2, 0)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(-2, 0))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
|
// Bicie o wektor [0, 2]
|
||||||
|
if((position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
|
(getPawn(position+Vector(0, 1))) && // Jeżeli istnieje bity pionek
|
||||||
|
(getPawn(position+Vector(0, 1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(0, 2)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(0, 2))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
|
// Bicie o wektor [2, 0]
|
||||||
|
if((position.x < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
|
(getPawn(position+Vector(1, 0))) && // Jeżeli istnieje bity pionek
|
||||||
|
(getPawn(position+Vector(1, 0))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(2, 0)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(2, 0))); // Dorzuć ruch do listy
|
||||||
|
|
||||||
|
// Bicie o wektor [0, -2]
|
||||||
|
if((position.y < TILES_COUNT-2) && // Jeżeli bicie nie wyjdzie poza planszę
|
||||||
|
(getPawn(position+Vector(0, -1))) && // Jeżeli istnieje bity pionek
|
||||||
|
(getPawn(position+Vector(0, -1))->getColor() != position_pawn->getColor()) && // Jeżeli jest to pionek przeciwnego koloru
|
||||||
|
(!getPawn(position+Vector(0, -2)))) // Jeżeli pole docelowe jest puste
|
||||||
|
beatings.push_back(Movement(position, position+Vector(0, -2))); // Dorzuć ruch do listy
|
||||||
|
}
|
||||||
|
|
||||||
// Zwracamy kontener
|
// Zwracamy kontener
|
||||||
return beatings;
|
return beatings;
|
||||||
@@ -243,46 +251,105 @@ std::list<Movement> Board::getPossibleMovements(Vector position)
|
|||||||
|
|
||||||
// Jeżeli pionek nie istnieje, zwróć pustą listę
|
// Jeżeli pionek nie istnieje, zwróć pustą listę
|
||||||
if(!getPawn(position)) return movements;
|
if(!getPawn(position)) return movements;
|
||||||
|
|
||||||
// Jeżeli to ruch czarnego pionka
|
// Jeżeli pionek jest damką
|
||||||
if(getPawn(position)->getColor() == CL_BLACK)
|
if(getPawn(position)->isQueen())
|
||||||
{
|
{
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
|
||||||
if(getPawn(position)->getPosition().x > 0 &&
|
// Jeżeli ruch w górę-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
getPawn(position)->getPosition().y > 0)
|
if(position.x >= 1 && position.y >= 1)
|
||||||
|
if(!getPawn(position+Vector(-1, -1))) movements.push_back(Movement(position, position+Vector(-1, -1)));
|
||||||
// Jeżeli miejsce 1 jest wolne, wrzuć do listy
|
|
||||||
|
// Jeżeli ruch w górę-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x < TILES_COUNT-1 && position.y >= 1)
|
||||||
|
if(!getPawn(position+Vector(1, -1))) movements.push_back(Movement(position, position+Vector(1, -1)));
|
||||||
|
|
||||||
|
// Jeżeli ruch w dół-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x >= 1 && position.y < TILES_COUNT-1)
|
||||||
|
if(!getPawn(position+Vector(-1, 1))) movements.push_back(Movement(position, position+Vector(-1, 1)));
|
||||||
|
|
||||||
|
// Jeżeli ruch w dół-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x < TILES_COUNT-1 && position.y < TILES_COUNT-1)
|
||||||
if(!getPawn(position+Vector(1, 1))) movements.push_back(Movement(position, position+Vector(1, 1)));
|
if(!getPawn(position+Vector(1, 1))) movements.push_back(Movement(position, position+Vector(1, 1)));
|
||||||
|
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
// Jeżeli ruch w górę jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
if(getPawn(position)->getPosition().x > 0 &&
|
if(position.y >= 1)
|
||||||
getPawn(position)->getPosition().y > 0)
|
if(!getPawn(position+Vector(0, -1))) movements.push_back(Movement(position, position+Vector(0, -1)));
|
||||||
|
|
||||||
// Jeżeli miejsce 2 jest wolne, wrzuć do listy
|
// Jeżeli ruch w dół jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
if(!getPawn(position+Vector(-1, 1))) movements.push_back(Movement(position, position+Vector(-1, 1)));
|
if(position.y < TILES_COUNT-1)
|
||||||
|
if(!getPawn(position+Vector(0, 1))) movements.push_back(Movement(position, position+Vector(0, 1)));
|
||||||
|
|
||||||
|
// Jeżeli ruch w lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x >= 1)
|
||||||
|
if(!getPawn(position+Vector(-1, 0))) movements.push_back(Movement(position, position+Vector(-1, 0)));
|
||||||
|
|
||||||
|
// Jeżeli ruch w prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x < TILES_COUNT-1)
|
||||||
|
if(!getPawn(position+Vector(1, 0))) movements.push_back(Movement(position, position+Vector(1, 0)));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jeżeli to ruch białego pionka
|
// Jeżeli jest to zwykły pionek
|
||||||
if(getPawn(position)->getColor() == CL_WHITE)
|
else
|
||||||
{
|
{
|
||||||
// Zabezpieczenie przed przekroczeniem indeksów
|
// Jeżeli to ruch białego pionka
|
||||||
if(getPawn(position)->getPosition().x > 1 &&
|
if(getPawn(position)->getColor() == CL_WHITE)
|
||||||
getPawn(position)->getPosition().y > 1)
|
{
|
||||||
|
// Jeżeli ruch w górę-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
// Jeżeli miejsce 1 jest wolne, wrzuć do listy
|
if(position.x >= 1 && position.y >= 1)
|
||||||
if(!getPawn(position+Vector(-1, -1))) movements.push_back(Movement(position, position+Vector(-1, -1)));
|
if(!getPawn(position+Vector(-1, -1))) movements.push_back(Movement(position, position+Vector(-1, -1)));
|
||||||
|
|
||||||
|
// Jeżeli ruch w górę-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x < TILES_COUNT-1 && position.y >= 1)
|
||||||
|
if(!getPawn(position+Vector(1, -1))) movements.push_back(Movement(position, position+Vector(1, -1)));
|
||||||
|
}
|
||||||
|
|
||||||
// Jeżeli miejsce 2 jest wolne, wrzuć do listy
|
// Jeżeli to ruch czarnego pionka
|
||||||
if(position.y > 1)
|
else
|
||||||
if(!getPawn(position+Vector(1, -1))) movements.push_back(Movement(position, position+Vector(1, -1)));
|
{
|
||||||
|
// Jeżeli ruch w dół-lewo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x >= 1 && position.y < TILES_COUNT-1)
|
||||||
|
if(!getPawn(position+Vector(-1, 1))) movements.push_back(Movement(position, position+Vector(-1, 1)));
|
||||||
|
|
||||||
|
// Jeżeli ruch w dół-prawo jest możliwy (jest puste miejsce) dorzuć ruch do listy
|
||||||
|
if(position.x < TILES_COUNT-1 && position.y < TILES_COUNT-1)
|
||||||
|
if(!getPawn(position+Vector(1, 1))) movements.push_back(Movement(position, position+Vector(1, 1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return movements;
|
return movements;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Movement> Board::getPossibleMovements(Color color)
|
std::list<Movement> Board::getPossibleGlobalBeatings(Color color)
|
||||||
{
|
{
|
||||||
std::list<Movement> movements;
|
std::list<Movement> movements;
|
||||||
|
|
||||||
|
// Dla każdych pionków
|
||||||
|
for(int x = 0; x < TILES_COUNT; ++x)
|
||||||
|
for(int y = 0; y < TILES_COUNT; ++y)
|
||||||
|
{
|
||||||
|
// Jeżeli to jest pionek
|
||||||
|
if(board[x][y])
|
||||||
|
{
|
||||||
|
// Jeżeli jest to pionek o który nam chodzi
|
||||||
|
if(board[x][y]->getColor() == color)
|
||||||
|
|
||||||
|
// Dodaj wszystkie jego możliwe ruchy do listy ruchów
|
||||||
|
for(auto m: getPossibleBeatings(Vector(x, y))) movements.push_back(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return movements;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<Movement> Board::getPossibleGlobalMovements(Color color)
|
||||||
|
{
|
||||||
|
std::list<Movement> movements;
|
||||||
|
|
||||||
|
// Jeżeli istnieją bicia zwracamy tylko je
|
||||||
|
if(arePossibleGlobalBeatings(color)) return getPossibleGlobalBeatings(color);
|
||||||
|
|
||||||
// Dla każdych pionków
|
// Dla każdych pionków
|
||||||
for(int x = 0; x < TILES_COUNT; ++x)
|
for(int x = 0; x < TILES_COUNT; ++x)
|
||||||
for(int y = 0; y < TILES_COUNT; ++y)
|
for(int y = 0; y < TILES_COUNT; ++y)
|
||||||
|
|||||||
@@ -129,8 +129,8 @@ void Game::executePlayerRound(sf::Vector2f mouse_position)
|
|||||||
// Pobieramy informacje o pionku(lub jego braku) z interesującego nas pola
|
// Pobieramy informacje o pionku(lub jego braku) z interesującego nas pola
|
||||||
Pawn* ptr = board.getPawn(position);
|
Pawn* ptr = board.getPawn(position);
|
||||||
|
|
||||||
// Jeżeli tura należy do gracza, pionek istnieje i należy do gracza oraz ruch nie został jeszcze rozpoczęty:
|
// Jeżeli tura należy do gracza, pionek istnieje i należy do gracza
|
||||||
if((round == getPlayerColor()) && ptr && (ptr->getColor() == getPlayerColor()) && (!movements_sequence))
|
if((round == getPlayerColor()) && ptr && (ptr->getColor() == getPlayerColor()))
|
||||||
{
|
{
|
||||||
// Zaznaczamy pionek i pobieramy do niego wskaźnik
|
// Zaznaczamy pionek i pobieramy do niego wskaźnik
|
||||||
ptr = board.selectPawn(Vector(position));
|
ptr = board.selectPawn(Vector(position));
|
||||||
@@ -228,7 +228,7 @@ void Game::eventHandler()
|
|||||||
|
|
||||||
// Wykonaj turę gracza
|
// Wykonaj turę gracza
|
||||||
executePlayerRound(sf::Vector2f(event.mouseButton.x, event.mouseButton.y));
|
executePlayerRound(sf::Vector2f(event.mouseButton.x, event.mouseButton.y));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "../inc/minimax.hh"
|
#include "../inc/minimax.hh"
|
||||||
|
|
||||||
|
|
||||||
int MiniMax::f1(Board& board, const Color& color)
|
int MiniMax::evaluate(Board& board, const Color& color)
|
||||||
{
|
{
|
||||||
// Wycena
|
// Wycena
|
||||||
int value = 0, tmp_value;
|
int value = 0, pawn_value;
|
||||||
|
|
||||||
// Wskaźnik na aktualnie oceniany pionek
|
// Wskaźnik na aktualnie oceniany pionek
|
||||||
Pawn* ptr = NULL;
|
Pawn* ptr = NULL;
|
||||||
@@ -19,27 +19,36 @@ int MiniMax::f1(Board& board, const Color& color)
|
|||||||
if(ptr)
|
if(ptr)
|
||||||
{
|
{
|
||||||
// Jeżeli pionek jest damką:
|
// Jeżeli pionek jest damką:
|
||||||
if(ptr->isQueen()) tmp_value = 10;
|
if(ptr->isQueen()) pawn_value = 10;
|
||||||
else tmp_value = 1;
|
else pawn_value = 1;
|
||||||
|
|
||||||
// Jeżeli pionek należy do obszaru III -- waga 3
|
/*** ZASADA TRZECH OBSZARÓW ***/
|
||||||
if(((ptr->getPosition().x >= 3) && (ptr->getPosition().y >= 3)) &&
|
{
|
||||||
((ptr->getPosition().x < (TILES_COUNT-3)) && (ptr->getPosition().y < (TILES_COUNT-3))))
|
// Jeżeli pionek należy do obszaru III -- waga 1
|
||||||
tmp_value *= 3;
|
if(((ptr->getPosition().x >= 3) && (ptr->getPosition().y >= 3)) &&
|
||||||
|
((ptr->getPosition().x < (TILES_COUNT-3)) && (ptr->getPosition().y < (TILES_COUNT-3))))
|
||||||
|
; // więc nie ruszamy
|
||||||
|
|
||||||
|
// Jeżeli pionek należy do obszaru II -- waga 2
|
||||||
|
else if(((ptr->getPosition().x >= 2) && (ptr->getPosition().y >= 2)) &&
|
||||||
|
((ptr->getPosition().x < (TILES_COUNT-2)) && (ptr->getPosition().y < (TILES_COUNT-2))))
|
||||||
|
pawn_value *= 2;
|
||||||
|
|
||||||
|
// W przeciwnym wypadku, zostaje waga 1
|
||||||
|
else
|
||||||
|
pawn_value *= 3;
|
||||||
|
|
||||||
// Jeżeli pionek należy do obszaru II -- waga 2
|
}
|
||||||
else if(((ptr->getPosition().x >= 2) && (ptr->getPosition().y >= 2)) &&
|
|
||||||
((ptr->getPosition().x < (TILES_COUNT-2)) && (ptr->getPosition().y < (TILES_COUNT-2))))
|
|
||||||
tmp_value *= 2;
|
|
||||||
|
|
||||||
// W przeciwnym wypadku, zostaje waga 1
|
|
||||||
|
|
||||||
|
/*** MOŻLIWOŚĆ BICIA ***/
|
||||||
|
if(board.isPossibleBeating(ptr->getPosition())) pawn_value += 5;
|
||||||
|
|
||||||
// Jeżeli NIE jest to pionek należący do gracza zdefiniowanego kolorem color
|
// Jeżeli NIE jest to pionek należący do gracza zdefiniowanego kolorem color
|
||||||
// przemnażamy przez -1
|
// przemnażamy przez -1
|
||||||
if(ptr->getColor() != color) tmp_value *= -1;
|
if(ptr->getColor() != color) pawn_value *= -1;
|
||||||
|
|
||||||
// Dodajemy tmp_value do wyceny
|
// Dodajemy pawn_value do wyceny
|
||||||
value += tmp_value;
|
value += pawn_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +82,7 @@ int MiniMax::alphabeta(Board board, int depth, int alpha, int beta, Movement& be
|
|||||||
if(color != AI_COLOR)
|
if(color != AI_COLOR)
|
||||||
{
|
{
|
||||||
// Dla każdego potomka
|
// Dla każdego potomka
|
||||||
for(auto& m: board.getPossibleMovements(color))
|
for(auto& m: board.getPossibleGlobalMovements(color))
|
||||||
{
|
{
|
||||||
// Tworzymy nowy stan gry
|
// Tworzymy nowy stan gry
|
||||||
Board new_board(board);
|
Board new_board(board);
|
||||||
@@ -93,7 +102,7 @@ int MiniMax::alphabeta(Board board, int depth, int alpha, int beta, Movement& be
|
|||||||
else
|
else
|
||||||
|
|
||||||
// Dla każdego potomka
|
// Dla każdego potomka
|
||||||
for(auto& m: board.getPossibleMovements(color))
|
for(auto& m: board.getPossibleGlobalMovements(color))
|
||||||
{
|
{
|
||||||
// Tworzymy nowy stan gry
|
// Tworzymy nowy stan gry
|
||||||
Board new_board(board);
|
Board new_board(board);
|
||||||
|
|||||||
Reference in New Issue
Block a user