Pöytälaatikkoon on ilmestynyt taas uusi ikuisuusprojekti ja toivoisin vinkkejä koodin suunnitteluun. Kyseessä on hyvin taulukkomainen peli, jossa yksiköt ovat pelikentällä Bejeweled-tyyliin.
Tässä on video, josta näkee hyvin miten pelin pitäisi toimia: http://www.youtube.com/watch?feature=player_detailpage&v=lFeqFZaX4g8#t=85. Yksiköitä voi siis siirtää ja poistaa, jolloin ylempänä olevat yksiköt tippuvat alaspäin. Pelissä pitää tarkastella myös tiettyjä yksiköistä muodostettuja kuvioita (esim. 3 rivissä tai 3 jonossa).
Koko peli pyörii hyvin pitkälti tuon taulukkorakenteen ympärillä ja olen pähkäillyt järkevää systeemiä tähän ongelmaan.
Olisiko järkevää tehdä vaikkapa siten, että kaikki yksiköt ovat listassa, joka järjestetään joka loopilla yksikön y-sijainnin mukaisesti. Tämä mahdollistaa helpon "painovoiman" laskemisen, kun ensin käydään läpi ruudukossa alimpana olevat yksiköt. Painovoiman jälkeen siirryttäisiin tarkastelemaan noita muodostelmia, jolloin voitaisiin kopioida pointterit jokaisesta yksiköstä 2-ulotteiseen taulukkoon ja tehdä tarvittavia asioita.
Vinkkejä otetaan vastaan :P
Jos ruudukko on tuollainen pienehkö, sitä on ehkä helpointa käsitellä todellakin joukkona taulukoita (esim. std::array<std::array<RUUTU,5>,3>). En ymmärrä, mitä mielestäsi saavuttaisit käyttämällä listoja ja osoitinkikkailua.
Taulukonkin voi helposti tiivistää:
for (int y = 0, y_vapaa = 0; y < y_max; ++y) { if (data[y] != VAPAA) { std::swap(data[y], data[y_vapaa]); ++y_vapaa; } }
Kannattaa myös hyödyntää C++:n standardikirjastoa, kun kerran sellainen on. Tässä on kaksi tapaa siirtää vapaat listan loppuun:
// C++98 std::fill(std::remove(data.begin(), data.end(), VAPAA), data.end(), VAPAA); // C++11 std::stable_partition(data.begin(), data.end(), [](TYYPPI& c) { return c != VAPAA; });
Tässä on vielä käytännön esimerkki merkkijonon tiivistämisestä:
#include <string> #include <algorithm> #include <iostream> int main() { std::string data = ".a..bcd...ef.g."; std::cout << data << '\n'; // Siirretään pisteet loppuun. (C++11) std::stable_partition(data.begin(), data.end(), [](char& c) { return c != '.'; }); std::cout << data << '\n'; // Siirretään pisteet alkuun. (C++98) std::fill(std::remove(data.rbegin(), data.rend(), '.'), data.rend(), '.'); std::cout << data << '\n'; }
Aihe on jo aika vanha, joten et voi enää vastata siihen.