C++ gra halma

0

Zaczynam tworzyć prostą grę w c++ i pojawił się pewien problem. Program kompiluje się, ale potem przestaje działać. Błąd jest najprawdopodobniej w plansza::StanPlanszy, która powinna wyświetlać ile pionków poszczególnych graczy doszło do pól wygranych. Bardzo proszę o pomoc.

#include <iostream> 
#include<iomanip>

using namespace std;

/////////////////////////////////////////////////////////
class pionek  //klasa bazowa pionkow kazdego z graczy
{
private:
	const char znak;
public:
	pionek* nast;
	friend class pole;
	friend class plansza;
	pionek(const char znak):znak(znak), nast(NULL){}
	virtual bool WPolu() {return true;};
};
//////////////////////////////////////////////////////////
class gracz : private pionek //klasa gracza, bazujaca na klasie pionek
{
private:
	int x, y; //wspolrzedne pionka na planszy
public:
	gracz(const char znak='*'):pionek(znak){};
	
	bool WPolu(){
		if(x>12 && y>12) return true;
		else return false;
	}
};
//////////////////////////////////////////////////////////
class komputer : private pionek //klasa komputera, bazujaca na klasie pionek
{
private:
	int x, y; //wspolrzedne pionka na planszy
public:
	friend void StanPlanszy();
	komputer(const char znak='o'):pionek(znak){};
	
	bool WPolu(){
		if(x<5 && y<5) return true;
		else return false;
	}
};
////////////////////////////////////////////////////////
class pole  // klasa pol planszy
{
public:
  char symbol;
  int typ; // 0 - wolne, 1 - zajete
  pole() : symbol(' '), typ(0) {} // konstruktor, na poczatku nie ma na nim pionkow, wiec pole jest puste
  pole(char symbol1, int typ1)
	  :
	symbol(symbol1),
		typ(typ1){}
  void wyswietl() {
	  cout << " ";
	  cout << symbol << " ";
  }
};
///////////////////////////////////////////////////////////
class plansza
{
public:
	pole  ***wsk;  // wskaznik do wskaznika na wskaznik
	plansza(){  // konstruktor planszy
		wsk=new pole**[18];   // plansza jest 2-wymiarowa tablica wskaznikow do pol
		for(int i=0; i<18; i++){  // rozmiar 18 a plansza 16x16, zeby nie bylo przekroczenia zakresu
			wsk[i]=new pole*[18]; 
			for(int j=0; j<18; j++){
				wsk[i][j]=new pole();  // pojedyncze pole
			}
		}
	}
	void usunPion(pionek* p, int x, int y){
		wsk[x][y]->symbol=' ';
		wsk[x][y]->typ=0;
	}
	void postawPion(pionek* p, int x, int y){
		wsk[x][y]->symbol=p->znak;
		wsk[x][y]->typ=1;
	}


	~plansza(){  // destruktor planszy, wykonuje sie kiedy plansza jest niszczona czyli po zakonczeniu gry
		cout << "Niszcze plansze - jestem destruktorem." << endl;  // sprawdza, czy destruktor zadzialal
		for(int i=0; i<18; i++){   // zwolnienie zaalokowanej pamieci
			for(int j=0; j<18; j++){
				delete wsk[i][j];  // usuwa pola po kolei
		}
		delete wsk[i];  // usuwa tablice pol
		}
		delete wsk;   // usuwa tablice tablic
	}

	void wyswietl(){ // wyswietlanie planszy
		system("cls"); // czyszczenie ekranu
		for(int i=1; i<=16; i++){  // wyswietlenie 16 wierszy
			cout << setw(2) << i << " ";  // rowne odstepy miedzy polami
			for(int j=1; j<=16; j++)
				wsk[i-1][j-1]->wyswietl(); // wyswietlanie 16 kolumn
			cout  << endl;
		}
		cout << "    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16\n\n";
	}
	**void StanPlanszy(){
		int graczowe=0;
		int kompowe=0;
		pole **pole_gracza, **pole_kompa;
		int a=5;
		for(int i=0;i<19;i++){
			for(int j=0; j<5; j++){ //wybieranie odpowiednich pol na pola gracza, czyli pola do ktorych ma dojsc
				if(j>1)--a;
				for(int k=0; k<a; k++){
					pole_gracza[i]=new pole();
					pole_gracza[i]=wsk[16-k-1][16-j-1];
				}
			}
		}
		int b=5;
		for(int i=0;i<19;i++){
			for(int j=0; j<5; j++){ //wybieranie odpowiednich pol na pola komputera, czyli pola, do ktorych ma dojsc
				if(j>1)--b;
				for(int k=0; k<b; k++){
					pole_kompa[i]=new pole();
					pole_kompa[i]=wsk[k][j];
				}
			}
		}
		for(int i=0;i<17;i++){
			for(int j=0;j<17;j++){
				for(int k=0;k<19;k++){
					if(wsk[i][j]->typ==1 && wsk[i][j]->symbol==('*')){  //sprawdzanie, czy na polach gracza znajduje sie jego pionek
						if(wsk[i][j]==pole_gracza[k]) graczowe++;}
					else if(wsk[i][j]->typ==1 && wsk[i][j]->symbol==('o')){  //sprawdzanie, czy na polach komputera znajduje sie jego pionek
						if(wsk[i][j]==pole_kompa[k]) kompowe++;}
				}
			}
		}
		cout << graczowe << " pionkow w polu gracza." << endl;
		cout << kompowe << " pionkow w polu komputera." <<endl;
	};**
};

int main(){
	plansza halma;
	gracz *nowy_gracza;
	komputer *nowy_kompa;
	int a=5; //zmienna okreslajaca ilosc pionkow w danym rzedzie
	for(int i=0; i<20; i++){ //tworzenie pionkow graczy
		nowy_gracza = new gracz();
		nowy_kompa = new komputer();
	}
	for(int j=0; j<5; j++){ //wstawianie pionkow w odpowiednie pola
		if(j>1)--a;
		for(int k=0; k<a; k++){
			halma.postawPion((pionek*)nowy_gracza, k, j);
			halma.postawPion((pionek*)nowy_kompa, 16-k-1,16-j-1);
		}
	}
	
	halma.wyswietl();
	**halma.StanPlanszy(); //problem jest chyba tu, bo jak to wykomentuje, to dziala**


	return 0;
}
4

Use the debugger, Luke, and may the compiler be with you!


Pierwszy błąd jaki widzę, to odwoływanie się do niezaalokowanej pamięci w metodzie `StanPlanszy` (`pole_gracza` oraz `pole_kompa`).
0

Przepisz ten kod od nowa. Tym razem jak normalny człowiek. Ten się nie nadaje do niczego. Kod ma być czytelny dla człowieka, w twoim absolutnie nie wiadomo co się dzieje.

0
class plansza
{
public:
        pole  mapa[18][18];
...
0

Całość wyglądda makabrycznie i nie chodzi tylko o formatowanie.
Poprawiłem klasę plansza starając się zachować ile się dało z Twojego kodu (również formatowanie).

class plansza
{
public:
        pole  mapa[16][16];<--- zgodnie ze słuszną sugestią _13th_Dragon
        pole *pole_gracza[19], *pole_kompa[19];
        plansza(){
            for(int i=0, a=0, k=0;i<5;i++){
                 if(i>1)++a;
                 for(int j=0; j<5-a; j++, ++k){
                    pole_gracza[k]=&mapa[16-i-1][16-j-1];
                    pole_kompa[k]=&mapa[i][j];
                 }
            }
        }

        void usunPion(pionek* p, int x, int y){
                mapa[x][y].symbol=' ';
                mapa[x][y].typ=0;//<--- przydałby się typ wyliczeniowy
        }
        void postawPion(pionek* p, int x, int y){
                mapa[x][y].symbol=p->znak;
                mapa[x][y].typ=1;
        }

        void wyswietl(){ // wyswietlanie planszy
                system("cls"); // czyszczenie ekranu
                for(int i=1; i<=16; i++){  // wyswietlenie 16 wierszy
                        cout << setw(2) << i << " ";  // rowne odstepy miedzy polami
                        for(int j=1; j<=16; j++)
                                mapa[i-1][j-1].wyswietl(); // wyswietlanie 16 kolumn <--- jedyna zmiana w tej funkcji
                        cout  << endl;
                }
                cout << "    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16\n\n";
        }
        void StanPlanszy(){
                int graczowe=0;
                int kompowe=0;

                for(int k=0;k<19;k++){
                        if(pole_gracza[k]->typ==1 && pole_gracza[k]->symbol==('*'))graczowe++;
                        if(pole_kompa[k]->typ==1 && pole_kompa[k]->symbol==('o'))kompowe++;
                }
                cout << graczowe << " pionkow w polu gracza." << endl;
                cout << kompowe << " pionkow w polu komputera." <<endl;
        }
}; 

I jeszcze jedna zmiana (w mainie).

gracz nowy_gracza;
        komputer nowy_kompa;
        int a=5; //zmienna okreslajaca ilosc pionkow w danym rzedzie
        for(int j=0; j<5; j++){ //wstawianie pionkow w odpowiednie pola
                if(j>1)--a;
                for(int k=0; k<a; k++){
                        halma.postawPion((pionek*)&nowy_gracza, k, j);//<--- tyle zachodu, żeby przekazać  '*'!
                        halma.postawPion((pionek*)&nowy_kompa, 16-k-1,16-j-1);
                }
        } 

Powino działać. Chyba, że coś przeoczyłem (te formatowanie).

0

Tym razem treść programu i formatowanie całkowicie zmienione. Program kompiluje się, ale potem wyłącza. Potrzebuję pomocy ze znalezieniem i zrozumieniem błędu.

#include <iostream> 
#include<iomanip>
#include <list>
using namespace std;


enum RodzajPionka {
	kolko, gwiazdka
};
/////////////////////////////////////////////////////////
class Pole;

class Pionek  //klasa bazowa pionkow kazdego z graczy
{
private:
	RodzajPionka rodzaj;
	Pole *pole;
public:
	Pionek(RodzajPionka rodzaj):rodzaj(rodzaj){ }
	char getSymbol() {
		if(rodzaj == kolko) {
			return 'o';
		} else {
			return '*';
		}
	}
	bool czyNaPoluWygrywajacym() {

		return false;
	}

	void postawNa(Pole* p);
	virtual bool WPolu() {return true;};
	friend class Pole;
};
////////////////////////////////////////////////////////
class Pole {
protected:
	int x, y;
	Pionek *pionek;
	friend class Pionek;
	friend class Plansza;
public:
	Pole(int x, int y) : x(x), y(y), pionek(NULL) { }
	Pole(int x, int y, Pionek& pionek) : x(x), y(y), pionek(&pionek) { }
	char getSymbol( ) {
		if (pionek == NULL) {
			return ' ';
		} else {
			return pionek->getSymbol();
		}
	}
	
};

void Pionek::postawNa(Pole* p) {
	pole->pionek = NULL;
	pole = p;
	pole->pionek = this;
}
struct Wspolrzedne {
	int x;
	int y;
};
struct Ruch {
	Wspolrzedne skad;
	Wspolrzedne dokad;
};
class Plansza {
private:
	Pole **pola;

public:
	Plansza(Pionek **pionkiGracza1, Pionek **pionkiGracza2) {
		int a=5,b=0;
		pola = new Pole*[256];
		int postawionychPionkowGracza1 = 0;
		int postawionychPionkowGracza2 = 0;
		for(int x=0; x<16; x++) {
			if(x>1)--a;
			if(x>9 && b<5) ++b;
			
			for(int y=0; y<16; y++) {
				if(y<a && x<5) { // warunek na x y czy stoi gwiazdka
					pola[x*16+y] = new Pole(x,y, *pionkiGracza1[postawionychPionkowGracza1]);
					postawionychPionkowGracza1++;
				} else if(y>16-b-1 && x>10) { // warunek na x y czy stoi kolko
					pola[x*16+y] = new Pole(x, y, *pionkiGracza2[postawionychPionkowGracza2]);
					postawionychPionkowGracza2++;
				} else {
					pola[x*16+y] = new Pole(x, y);
				}
			}
		}
	}



	virtual ~Plansza() {
		for(int i=0; i<256; i++) {
			delete pola[i];
		}
		delete[] pola;
	}

	void wyswietl() {
		system("cls"); // czyszczenie ekranu
		for(int x=0; x<16; x++) {
			cout << setw(2) << x+1 << "|";
			
			for(int y=0; y<16; y++) {
				cout << " " << pola[x*16+y]->getSymbol()<< "|";
			}
			cout << endl;
		
		}
		cout << "    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16\n\n";
	}

	bool czyMozliwyRuch(Ruch r) {
		return true;
	}

	void wykonajRuch(Ruch r) {
		Pole *pole_skad = pola[r.skad.x*16 + r.skad.y];
		Pole *pole_dokad = pola[r.dokad.x*16 + r.dokad.y];
		pole_skad->pionek->postawNa(pole_dokad);
	}
};

//////////////////////////////////////////////////////////
class Gracz {
protected:
	Pionek **listaPionkow;
	string imie;
	Plansza *plansza;
	RodzajPionka rodzaj;
public:
	Gracz(const string &imie, RodzajPionka rodzaj) : imie(imie), rodzaj(rodzaj) {
		listaPionkow = new Pionek*[19];
		for(int i=0; i<19; i++) {
			listaPionkow[i] = new Pionek(rodzaj);
		}
	}

	Pionek** podajPionki() {
		return listaPionkow;
	}

	virtual const Ruch podajRuch() = 0;
};
class GraczKomputerowy : public Gracz {
public:
	GraczKomputerowy(const string& imie, RodzajPionka rodzaj) : Gracz(imie, rodzaj) { }

	const Ruch podajRuch() {
		cout << "Jestem " << imie.c_str() << " i teraz wykonuje ruch!!!" << endl;
		Ruch r;
		r.skad.x = 1;
		r.skad.y = 5;
		r.dokad.x = 7;
		r.dokad.x = 8;
		return r;
	}
};

////////////////////////////////////////////////////////
class Gra{
private:
	Gracz *gracz1;
	Gracz *gracz2;
	Plansza plansza;
	int czyjRuch;

	void wykonajKolejnyRuch() {
		if(czyjRuch == 0) {
			Ruch r = gracz1->podajRuch();
			plansza.czyMozliwyRuch(r);
			plansza.wykonajRuch(r);

		} else {
			Ruch r = gracz2->podajRuch();
			plansza.czyMozliwyRuch(r);
		}
		czyjRuch++;
		czyjRuch%=2;
	}

	bool czyKoniec() {
		return true;
	}

	bool czyWygralPierwszyGracz() {
		return false;
	}

	void wyswietlPlansze() {
		plansza.wyswietl();
	}


public:
	Gra(Gracz& gracz1, Gracz& gracz2): gracz1(&gracz1), gracz2(&gracz2), plansza(gracz1.podajPionki(), gracz2.podajPionki()), czyjRuch(0){};

	void graj() {
		wyswietlPlansze();
		do {
			wykonajKolejnyRuch();
		} while(!czyKoniec());
		if(czyWygralPierwszyGracz()) {
			cout << "Wygral gracz 1!" << endl;
		} else {
			cout << "Wygral gracz 2!" << endl;
		}
	}
};
int main(){
	GraczKomputerowy gracz1("Joanna", kolko);
	GraczKomputerowy gracz2("Krysia", gwiazdka);

	Gra gra(gracz1, gracz2);
	gra.graj();
	return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1