Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Järkevä koodirakenne taulukkomaiseen peliin

punppis [12.10.2013 10:17:43]

#

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

Metabolix [12.10.2013 14:18:28]

#

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';
}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta