Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <stdio.h>
- #include <windows.h>
- #include <string>
- #include <vector>
- #include <ctime>
- #include <cstdlib>
- #include <conio.h>
- using namespace std;
- const int ROW = 18;
- const int COL = 32;
- const int ENEMIES = 3; //liczba wrogow
- char map[ROW][COL]; //mapa glowna do ktorej trzeba skopiowac wzorzec
- char map_easy[ROW][COL] = { //wzorzec mapy o łatwym poziomie trudności
- "+#############################+",
- "| |",
- "| |##### ### ## | | |",
- "| ###### ########## |",
- "| |",
- "|# ### #### ### #######|",
- "| |",
- "| ###### ########## |",
- "| |",
- "| |##### ### ## | | |",
- "| ###### ########## |",
- "| |",
- "|# ### #### ### #######|",
- "| |",
- "| |##### ### ## | | |",
- "| ###### ########## |",
- "| |",
- "+#############################+"
- };
- char map_normal[ROW][COL] = { //wzorzec mapy o średnim poziomie trudności
- "+#############################+",
- "| || | ##### || | |",
- "| |",
- "|### ## #### # | | |",
- "| |",
- "| || | ##### || | |",
- "| ### # || # ## ##|",
- "|### ## #### # | | |",
- "| |",
- "| |##### ### ## | | |",
- "| | ###### ##########|",
- "| || ## |",
- "|# ### #### | ### ######|",
- "| || | ##### || | |",
- "| |",
- "|### ## #### # | | |",
- "| | || | # # |",
- "+#############################+"
- };
- char map_hard[ROW][COL] = { //wzorzec mapy o trudnym poziomie trudności
- "+#############################+",
- "| || | ##### || | |",
- "| ### # |# || # ## ##|",
- "|### ## #### # || | |",
- "| || | ##### || | |",
- "| ### # || # ## ##|",
- "|### ## #### # | # | |",
- "| || | ##### || | |",
- "| ### # || # ## ##|",
- "|### ## #### # | # | |",
- "| || | ##### || | |",
- "| ### # || # ## ##|",
- "|### ## #### # | | |",
- "| || | ##### || | ||",
- "| ### # || # ## ##|",
- "|### ## #### # | | |",
- "| || # | |## |",
- "+#############################+"
- };
- void ShowMap() //funckja do wyswietlania mapy
- {
- for (int i = 0; i < 18; i++) //petla
- {
- cout << (string(map[i]) + "\n"); //wyswietlenie jednego wiersza
- }
- }
- void setMap(char mapToSet[ROW][COL]) //funckja do skopiowania wzorca do mapy
- {
- for (int i = 0; i < 18; i++)//petla
- for (int j = 0; j < 32; j++)
- {
- map[i][j] = mapToSet[i][j]; //kopiowanie
- }
- }
- void gotoxy(short x, short y) //ustawienie kursora przy postaci //w danych kordyantach
- {
- HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- COORD position = { x, y };
- SetConsoleCursorPosition(hStdout, position);
- }
- void setDots() //ulozenie kropek na planszy
- {
- // % to reszta z dzielenia. np. 4%3 = 1
- for (int i = 0; i < ROW; i++)
- for (int j = 0; j < COL; j++) //w podwojnej petlni przechodzimy cala mape
- if (map[i][j] == ' ' && (rand() % 15) == 0) // jesli jest pole na mapie puste i wylosuje nam liczbe podzielna prrzez 15 -> pokrycie 1/15 planszy
- {
- map[i][j] = '.'; // jesli warunek spelniony to wpisujemy w mape punkt
- }
- }
- void setEnemiesCords(int *ex, int *ey, int numOfEnemies) //funkcja ktora wyznaczy kordynaty poczatkowe przeciwnikow
- {
- for (int i = 0; i < numOfEnemies; i++) //dla kazdego przeciwnika:
- {
- do { //losujemy tak dlugo kordynaty az pole pod kordynatami bedzie puste -> do skutku
- ex[i] = rand() % COL;
- ey[i] = rand() % ROW;
- } while (map[ey[i]][ex[i]] != ' ');
- }
- }
- bool isEndOfGame() //funkcja do sprawdzania czy gra sie zakonczyla. gra sie konczy gdy nie ma kropek
- {
- bool result = true; //zakladamy ze to koniec gry
- for (int i = 0; i < ROW; i++)
- for (int j = 0; j < COL; j++) //przechodizmy cala mape
- if (map[i][j] == '.') // jesli sie pojawi kropka gdziekolwiek to nie koniec czyli zmienimy wynik na false
- {
- result = false;
- }
- return result;
- }
- struct Point { //struktura sluzaca do tego by zwrocic kordynaty przy sztucznej inteligencjjii
- int x;
- int y;
- };
- void fill(int binaryMap[ROW][COL], int distanceArray[ROW][COL], int x, int y, int currentDistance) //wypelnia tablice tymczasowa, zaczyna w punkcie (x,y) i wywoluje samą siebie dla sąsiadów //drugi etap sztucznej inteligencji
- {
- distanceArray[x][y] = currentDistance;
- if (x + 1 < ROW && binaryMap[x + 1][y] == 1 && (distanceArray[x + 1][y] == 0 || distanceArray[x + 1][y] > currentDistance + 1))
- fill(binaryMap, distanceArray, x + 1, y, currentDistance + 1);
- if (x - 1 >= 0 && binaryMap[x - 1][y] == 1 && (distanceArray[x - 1][y] == 0 || distanceArray[x - 1][y] > currentDistance + 1))
- fill(binaryMap, distanceArray, x - 1, y, currentDistance + 1);
- if (y + 1 < COL && binaryMap[x][y + 1] == 1 && (distanceArray[x][y + 1] == 0 || distanceArray[x][y + 1] > currentDistance + 1))
- fill(binaryMap, distanceArray, x, y + 1, currentDistance + 1);
- if (y - 1 >= 0 && binaryMap[x][y - 1] == 1 && (distanceArray[x][y - 1] == 0 || distanceArray[x][y - 1] > currentDistance + 1))
- fill(binaryMap, distanceArray, x, y - 1, currentDistance + 1);
- }
- Point findNextStep(int tmp[ROW][COL], int startX, int startY, int x, int y) //funckaj zwracajaca jaki kolejny krok musi wykonac przeciwnik by dojsc do gracza ////trzeci etap sztucznej inteligencji
- {
- int currentDist = tmp[x][y];
- if (x + 1 < ROW && tmp[x + 1][y] == currentDist - 1)
- if (x + 1 == startX && y == startY)
- return Point{ x, y };
- else
- return findNextStep(tmp, startX, startY, x + 1, y);
- else if (x - 1 >= 0 && tmp[x - 1][y] == currentDist - 1)
- if (x - 1 == startX && y == startY)
- return Point{ x, y };
- else
- return findNextStep(tmp, startX, startY, x - 1, y);
- else if (y + 1 < COL && tmp[x][y + 1] == currentDist - 1)
- if (x == startX && y + 1 == startY)
- return Point{ x, y };
- else
- return findNextStep(tmp, startX, startY, x, y + 1);
- else if (y - 1 >= 0 && tmp[x][y - 1] == currentDist - 1)
- if (x == startX && y - 1 == startY)
- return Point{ x, y };
- else
- return findNextStep(tmp, startX, startY, x, y - 1);
- }
- void mapToBinary(int array[ROW][COL]) //funkcja do konwertowania mapy na binarny labirynt //pierwszy etap sztucznej inteligencji, tylko na poczatku gry poniewaz mapa sie nie zmienia pod wzgedem przeszkod
- {
- for (int i = 0; i < ROW; i++)
- for (int j = 0; j < COL; j++)
- if (map[i][j] == ' ' || map[i][j] == '.')
- array[i][j] = 1;
- else
- array[i][j] = 0;
- }
- Point getNextStep(int binaryMap[ROW][COL], int ex, int ey, int x, int y) //funckja ktora wywola etap 2 i 3 sztucznej intelgiencji i zwroci nastepmny krok
- {
- int distanceArray[ROW][COL]; //tablica tymczasowa o takiej samej wielkosci wypelniona tylko zerami
- for (int i = 0; i < ROW; i++)
- for (int j = 0; j < COL; j++)
- distanceArray[i][j] = 0;
- fill(binaryMap, distanceArray, ex, ey, 1); //wypelnia tablice dystansami
- Point nextStep = findNextStep(distanceArray, ex, ey, x, y); //pobieramy jaki trzeba wykonac nastepny krok
- return nextStep; //zwracamy nastepny krok
- }
- int main()
- {
- srand(time(0));
- int x = 15; //poczatkowae wspolrzedne x bohatera
- int y = 16; //poczatkowae wspolrzedne y bohatera
- cout << "Pacman by Sliwa\n";
- cout << "H -> Hard\nN -> Normal\nE -> Easy\n\nInput : ";
- char level; //wczytujemy od uzytkownika poziom na jakim chce grac E/N/H
- cin >> level;
- int speedmod; //szybkosc gry
- if (level == 'E')
- {
- speedmod = 3;
- setMap(map_easy);
- }
- else if (level == 'N')
- {
- speedmod = 2;
- setMap(map_normal);
- }
- else {
- speedmod = 1;
- setMap(map_hard);
- }
- setDots();
- //kazdy wrog potrzebuje kordynaty //np. jesli 3 wrogow to tablica z kordynatami x musi byc wielkosci 3
- int enemiesX[ENEMIES]; //tworzenie tablic w ktorej beda wspolrzedne wrogow
- int enemiesY[ENEMIES];
- int enemiesSpeeds[ENEMIES]; //tablica z predkscia dla kazdego wroga
- setEnemiesCords(enemiesX, enemiesY, ENEMIES);
- for (int i = 0; i < ENEMIES; i++) //wylosowanie predkosci dla wrogow
- {
- enemiesSpeeds[i] = speedmod + rand() % 5; // (rand() % 5) moze dac wartosc 0,1,2,3,4
- }
- system("cls"); //czysczenie ekranu
- ShowMap();//wyswieltenie mapy
- int binaryMap[ROW][COL]; //binarny labirynt
- mapToBinary(binaryMap);
- gotoxy(x, y);
- cout << "H"; //ustawienie bohateraa w pocztakowej pozycji
- int frame = 0; //licznik petli gry //sluzy tylko do tego jak czesto maja sie poruszac wrogowie
- int score = 0; //punkty
- _getch(); //pobierz jeden znak przed gra by nie uruchomilo sie od razu
- bool running = true; //zeby dzialala petla
- while (isEndOfGame() == false && running == true) { //glowna petla gry // ona trwa dopoki sa kropki oraz dopoki running jest true
- gotoxy(x, y); //na poczatku petli usuwamy poprzednia pozycje bohatera
- cout << " ";
- if (GetAsyncKeyState(VK_UP)) { //jesli nacisnieto w gore
- if (map[y - 1][x] == '.') {
- y--; score++; map[y][x] = ' '; //jesli nad graczem jest kropka to dodaj punkt i zamien na spacje i zrob ruch
- }
- else
- if (map[y - 1][x] == ' ') y--; //jesli nad graczem pusta przestrzen to zrob ruch
- }
- if (GetAsyncKeyState(VK_DOWN)) {
- if (map[y + 1][x] == '.') {
- y++; score++; map[y][x] = ' ';
- }
- else
- if (map[y + 1][x] == ' ') y++;
- }
- if (GetAsyncKeyState(VK_LEFT)) {
- if (map[y][x - 1] == '.') { x--; score++; map[y][x] = ' '; }
- else
- if (map[y][x - 1] == ' ') x--;
- }
- if (GetAsyncKeyState(VK_RIGHT)) {
- if (map[y][x + 1] == '.') {
- x++; score++; map[y][x] = ' ';
- }
- else
- if (map[y][x + 1] == ' ') x++;
- }
- //w tym momencie wiemy jaka bedzie pozycja bohatera w kolejnej petli
- gotoxy(x, y);
- cout << "H";//wyswietlenie bohatera w nowej pozycji
- for (int i = 0; i < ENEMIES; i++) //usun kazdego przeciwnika ze starej pozycji
- {
- gotoxy(enemiesX[i], enemiesY[i]);
- cout << " ";
- }
- //sztuczna inteligencja
- //1. uzyskujemy binarna mape/labirynt
- //2. tworzymy tablice z dystansami
- //3. znajdujemy kolejny krok dla przeciwnika
- //algorytm inspirowany BFS - przeszukiwanie grafu wszerz
- for (int i = 0; i < ENEMIES; i++) //sztuczna inteligencja - znajdz nastepne pole dla przeciwnikow
- if (frame%enemiesSpeeds[i] == 0) //przeciwnik moze sie ruszyc tylko co iles iteracji //im trudniej tym czesciej moze sie ruszac
- {
- Point p = getNextStep(binaryMap, enemiesY[i], enemiesX[i], y, x);
- enemiesX[i] = p.y;
- enemiesY[i] = p.x;
- if (map[enemiesY[i]][enemiesX[i]] == '.') //przeciwnik moze zjesc punkt/kropke
- map[enemiesY[i]][enemiesX[i]] = ' ';
- }
- //w tym momencie wiemy jaka beda pozycje przeciwnikow w kolejnej petli/iteracji
- for (int i = 0; i < ENEMIES; i++) //zrob ruch kazdym przeciwnikiem
- {
- gotoxy(enemiesX[i], enemiesY[i]);
- cout << "E";
- if (enemiesX[i] == x && enemiesY[i] == y) //sprawdzanie czy przegrasmy (przegralismy jest nowe kordynaty przeciwnika beda takie same jak boahtera)
- {
- running = false;
- }
- }
- gotoxy(32, 18);//wyrzuc kursor poza plansze
- gotoxy(32, 1); cout << score;//wyswietl punkty
- Sleep(100); //czekaj 100ms
- frame++; //licznik iteracji + 1
- }
- system("cls");
- if (isEndOfGame() == true)
- {
- cout << "Wygrales!\nLiczba punktow:" << score;
- }
- if (running == false)
- {
- cout << "Przegrales!";
- }
- Sleep(5000);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement