![]() |
![]() ![]()
Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2010 mgr
Jerzy Wałaszek |
Pomoce:
Biblioteka procedur obsługi konsoli znakowej - newconio
Gra w Życie (ang. Game of Life) została
wynaleziona około roku 1970 przez Johna Conwaya i opisana w czasopiśmie
"American Scientific". Gra pozwala symulować życie, rozwój oraz śmierć
żywych organizmów i rozgrywana jest na nieskończonym polu komórek. Każda komórka
posiada dokładnie 8 przyległych do niej sąsiadów. W komórce może żyć organizm
lub nie. Nowe pokolenie organizmów powstaje wg następujących reguł:
Organizm umiera z samotności, jeśli w przyległych do niego komórkach jest mniej niż dwóch żywych sąsiadów. Organizm umiera z przeludnienia, jeśli w przyległych do niego komórkach jest więcej niż 3 żywych sąsiadów. Zatem śmierć następuje w przypadku, gdy otaczające organizm komórki zawierają 0,1,4,5,6,7 lub 8 organizmów.
Jeśli w otaczających organizm komórkach jest dwóch lub trzech żywych sąsiadów, organizm przeżywa do następnego pokolenia.
Jeśli pusta komórka posiada dokładnie trzech żywych sąsiadów, to rodzi się w niej nowy organizm.
Komórki zajęte przez organizmy tworzą różne wzory geometryczne zmieniające się w każdym pokoleniu. Niektóre układy organizmów powodują wymarcie kolonii, inne z kolei dają w efekcie cykliczny rozwój żywych komórek. Badanie tych układów może być bardzo ciekawym zajęciem.
W naszej implementacji zrezygnujemy z nieskończonego pola gry, które raczej trudno uzyskać w skończonej pamięci komputera. Plansza będzie złożona z matrycy komórek ułożonych w 49 wierszy po 80 kolumn. Taka matryca zmieści się bez problemów w okienku konsoli znakowej.
Chociaż pole nie będzie nieskończone, to jednak jego krawędź górna zostanie połączona z dolną, a prawa z lewą. Dzięki temu, każda komórka zawsze będzie posiadała 8 sąsiadów.
W pamięci plansza gry zostanie zrealizowana w formie tablicy łańcuchów znakowych. Ponieważ nowe pokolenie powstaje na podstawie sytuacji istniejącej w pokoleniu poprzednim, zatem musimy posiadać dwie takie tablice - z pokoleniem aktualnym oraz drugą, w której utworzymy następną generację żywych organizmów. Po tej operacji dane z drugiej tablicy przenosimy do pierwszej i wyświetlamy w okienku konsoli.
Program będzie interaktywny. W trakcie gry użytkownik może tworzyć w wybranych komórkach nowe organizmy lub usuwać je z komórek. Przyjmiemy następujący schemat klawiszy sterowania grą:
klawisz | funkcja |
---|---|
strzałki | przemieszczanie aktywnej komórki po planszy gry |
ESC | zakończenie rozgrywki |
spacja | jeśli aktywna komórka jest pusta, to wprowadzamy tam nowy organizm. Jeśli natomiast w aktywnej komórce już jest organizm, to usuwamy go. |
Enter | przejście do następnego pokolenia |
A | powoduje automatyczną generację nowych pokoleń organizmów aż do momentu powtórnego naciśnięcia klawisza innego klawisza. |
B | powoduje wygenerowanie 100 nowych komórek w przypadkowych miejscach na planszy |
C | usunięcie wszystkich organizmów z planszy gry. |
// Automaty komórkowe - Gra Life // (C)2010 ILO w Tarnowie // KOŁO INFORMATYCZNE //----------------------- #include <iostream> #include <string> #include "newconio.h" #include <cstdlib> #include <time.h> using namespace std; // zmienne globalne string pole1[49],pole2[49]; // przestrzenie życiowe organizmów int cx,cy; // pozycja kursora int np; // numer pokolenia // zeruje przestrzeń życiową pole1 // ustawia kursor na środku pola gry // zeruje numer pokolenia void zeruj() { string s; int i; s = ""; for(i = 0; i < 80; i++) s += " "; for(i = 0; i < 49; i++) pole1[i] = pole2[i] = s; cx = 39; cy = 24; np = 0; } // wyświetla zawartość pole1 //-------------------------- void wyswietlaj() { int i; gotoxy(0,0); textattr(0x1f); for(i = 0; i < 49; i++) { cout << pole1[i]; if(i == cy) putattrxy(0x4e,cx,cy); } gotoxy(31,49); textattr(YELLOW); cout << "Pokolenie: " << np << " "; } // wylicza współrzędną x w obrębie pola gry //----------------------------------------- int wx(int x) { if(x > 79) x = 0; if(x < 0) x = 79; return x; } // wylicza współrzędną y w obrębie pola gry //----------------------------------------- int wy(int y) { if(y > 48) y = 0; if(y < 0) y = 48; return y; } // wylicza nowe pokolenie organizmów w pole2 // przenosi pole2 do pole1 //------------------------------------------ void pokolenie() { int i,j,k,l,ls; for(i = 0; i < 49; i++) for(j = 0; j < 80; j++) { ls = 0; // obliczamy w ls liczbę sąsiadów komórki [i,j] for(k = -1; k < 2; k++) for(l = -1; l < 2; l++) if(((k != 0) || (l != 0)) && (pole1[wy(i + k)][wx(j + l)] == 'O')) ls++; // sprawdzamy reguły przeżycia komórki lub narodzin nowej if(pole1[i][j] == 'O') { if((ls == 2) || (ls == 3)) pole2[i][j] = 'O'; else pole2[i][j] = ' '; } else { if(ls == 3) pole2[i][j] = 'O'; else pole2[i][j] = ' '; } } // przenosimy pole2 do pole1 for(i = 0; i < 49; i++) pole1[i] = pole2[i]; np++; } // wypełnia w pole1 100 komórek organizmami //----------------------------------------- void wypelnij() { int x,y,i; for(i = 0; i < 100; i++) { x = rand() % 80; y = rand() % 48; pole1[y][x] = 'O'; } } // generuje kolejne pokolenia organizmów aż do // naciśnięcia klawisza A //-------------------------------------------- void generuj() { do { wyswietlaj(); pokolenie(); delay(100); } while(!kbhit()); } // ********************** // *** PROGRAM GŁÓWNY *** // ********************** int main() { int kl; bool gra_w_toku = true; srand(time(NULL)); _cinit(); fullscreen(true); cursoroff(); zeruj(); while(gra_w_toku) { wyswietlaj(); if(kbhit()) { while(!(kl = getch())); switch(kl) { case 13: pokolenie(); break; case 27: gra_w_toku = false; break; case 32: if(pole1[cy][cx] == ' ') pole1[cy][cx] = 'O'; else pole1[cy][cx] = ' '; break; case 72: cy = wy(cy - 1); break; case 77: cx = wx(cx + 1); break; case 80: cy = wy(cy + 1); break; case 75: cx = wx(cx - 1); break; case 'a': generuj(); break; case 'b': wypelnij(); break; case 'c': zeruj(); break; } } } fullscreen(false); cursoron(); textattr(7); clrscr(); return 0; } |
![]() | I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe