Osoba pisząca tą grę wymyśliła sobie problem rysowania mapy w ten sposób, że każda mapa była rysowana oddzielną procedurą. Okey... ale skąd brano topologie mapy? No jasne, że z palca! Każda linia mapy była pisana z palca, znak w znak. W zasadzie procedury rysujące mapy różniły się jedynie sekwencją znaków, a nie samym działaniem. Koszmar :/
Podrzuciłem pomysł rysowania mapy w Excelu. Tak, tak.. w tym arkuszu kalkulacyjnym. Tutaj pokaże to samo używają OpenOffice / LibreOffice Calc, aczkolwiek w Excel też zadziała.
Moja gra będzie oparta na scenariuszu chodzenia po mapie przypominającej labirytnt. Zakładam, że ściany będę oznaczał symbolem "x", podczas gdy punkt startowy gracza oznaczę "@", a punkt docelowy przez "&". Okey, a co ma do tego Excel?
Zaznaczam wszystkie wiersze i kolumny ( przycisk nad wierszem 1, na lewo od kolumny A ), ustalam szerokość kolumny na 0,8 ( zlokalizowane arkusze kalkulacyjne używają przecinka jako separatora części ułamkowej ).
Teraz cały arkusz wygląda mniej-więcej, jakby był złożony z kwadratów. Chciałbym, aby po wstawieniu w komórkę znaku x ta komórka się zaczerniła. Dzięki temu będę lepiej widział jak wygląda rysowana mapa. Aby nie kolorować ręcznie, użyję formatowania warunkowego.
Ustalam 3 reguły:
- czarne tło dla znaku x
- zielone tło dla znaku startu @
- czerwone dla końca &
[ LOffice Calc sprytnie zauważy, że czarny tekst na czarnym tle jest średnio widoczny, więc automatycznie wypełnione na czarno komórki będą miały kolor czcionki zmieniony na biel ]
Mapa wyświetlana na terminalu Windows ma domyślnie 80x25 znaków, czyli plansza w Excel zaczyna się na komórce (A,1) a kończy na (CB, 25). Postawiłem ramkę wokół tego obszaru + zmieniłem domyślne tło na niebieski. Dzięki temu nie przedobrzę z obszarem rysowania.
Tak oto za pomocą stawiania x-ów, jednego startu i jednego końca namalowałem mapę. Tutaj jest ona dużo węższa, niż szerokość terminala, ale to w niczym nie przeszkadza.
Ważne, że to co widać w Excel będzie wiernie odwzorowane na ekranie gracza. Tak zrobioną mapę zapisuję do formatu CSV ( comma separate values ). Jako separator ustawiam średnik ( ; ). Urok formatu CSV polega na tym, że w wypadku danych numerycznych obsługuje go każdy cywilizowany program obliczeniowy - począwszy od R przez Matlaby, MathCADy, Mathematica, Octave, NumPy a kończywszy na Excel i Calc. Dodatkowo ten format jest idealny do parsowania. Prościej się nie da.
Po obejrzeniu tego pliku w dowolnym edytorze tekstowym powinien on wyglądać mniej więcej tak:
Puste komórki zostały pominięte, czyli zapis ;; oznacza, że dana komórka nie miała wartości. Obraz może wydawać się "rozjechany", ale bezproblemowo można go poskładać, tj. usunąć znak separatora, a puste pola zamienić na spację. Terminale używają czcionek monospace, dzięki czemu całość pięknie wyrówna się na ekranie.
Na szybko napisałem funkcję, która realizuje wyświetlenie takiego pliku mapy w formacie CSV na konsoli. Kod:
#include <iostream> #include <fstream> using namespace std; inline void parseLine(string s) { char c; char delim=';', fill=' '; size_t pos=-1; if (s.empty()) return; do { pos = s.find(delim, pos+1); if ( pos != string::npos ) { if ( pos==0 || s[pos-1]==delim) cout << fill; else cout << s[pos-1]; } } while (pos != string::npos); cout << ( c=s[s.size()-1],c == delim ? fill : c ) << endl; } int main() { ifstream mapa("mapa.csv"); string s; if (!mapa) { perror("Blad ladowania mapy"); return -1; } while ( !mapa.eof() && mapa ) { getline(mapa, s); parseLine(s); } mapa.close(); return 0; }
W rezultacie całość wygląda w konsoli tak:
Przy tak prostych aplikacjach wysilanie się na własny edytor map jest przerostem formy nad treścią. Bardzo zachęcam do korzystania np. z Calc/Excela w takich sytuacjach.