jak zablokowac dalsze zmiany w tablicy?

0

Witam,

Pisze gre, która ma tablice NxN - polega na zamianie 0 na 1 i odwrotnie.
Jednym z przykladow jest zamiana podawanego pola + pola na gorze, dole, po prawej i po lewej.

ale jesli tablica jest 5x5 i podaje element [1][5] to zamienia sie takze element [2][1] bo program mysli ze jest to element po prawej stronie, a jest to po prostu element kolejny.

jak zablokowac to ifem by nie ruszalo tego elementu?

void mapa::ruch1(int x,int y){

	if(tab[x-1][y-1] == 1){
	   tab[x-1][y-1] = 0; // zmienia swoj stan
           tab[x-2][y-1] = 0; // gora
           tab[x][y-1] = 0; // dol
           tab[x-1][y] = 0; // prawo
           tab[x-1][y-2] = 0; // po lewej
       }

Dla zwizualizowania tego:

user image

0

Musisz po prostu sprawdzić przed każdą zmianą czy nie wykraczasz poza zakres wymiaru tablicy. Np. if(0 <= x-1 && x-1 < N && to_samo_dla_y) ...

0

ale to nie chodzi o rozmiar tablicy tylko rozmiar wiersza...

0
void mapa::ruch1(int x,int y){
 
        if(tab[x-1][y-1] == 1)
        {
           tab[x-1][y-1] = 0; // zmienia swoj stan
           if(x-1 != 0) tab[x-2][y-1] = 0; // gora
           if(x-1 != 4) tab[x][y-1] = 0; // dol
           if(y-1 != 4) tab[x-1][y] = 0; // prawo
           if( y-1 !=0 )tab[x-1][y-2] = 0; // po lewej
       }
0

dzieki wielkie !

0
kkk123 napisał(a):

ale to nie chodzi o rozmiar tablicy tylko rozmiar wiersza...

Dlatego napisałem wymiar, a nie rozmiar. Poza tym w swoim kodzie wykraczasz poza tablicę. Np. dla x i y = 1 lub 5.

@mto9: prawie dobrze, poza tym, że dla innych wymiarów tablicy się posypie ;) i brakuje walidacji poprawnych danych wejściowych.

void mapa::ruch1(int x, int y)
{
    x--;
    y--;

    if(x < 0 || x >= N || y < 0 || y >= N)
    {
        //obsługa błędu
        return;
    }

    if(tab[x][y] == 1)
    {
        tab[x][y] = 0;
        if(x != 0) tab[x-1][y] = 0; //lewo
        if(y != 0) tab[x][y-1] = 0; //góra
        if(x < N-1) tab[x+1][y] = 0; //prawo
        if(y < N-1) tab[x][y+1] = 0; //dół

        //z tego co widzę masz chyba inaczej ustawione wiersze/kolumny, ale nie mogę tego rozkminić z Twojego kodu
    }
}
0

No tak, ale to chyba logiczne :) napisałem kod tylko dla powyższego przykładu, uważając, iż autor tematu zrozumie o co chodzi.

0

no dobra, a teraz mam taki problem bo chce zrobic poziomy trudnosci 1. latwy (5x5), 2. sredni(8x8), 3. trudny(10x10), wiec nie moge uzywac define do N.

pytam wiec uzytkownika:

void mapa::poziomtrudnosci(){

    int wybor2;

    cout <<"Wybierz poziom trudnosci:" << endl;
    cout <<"1. latwy" << endl;
    cout <<"2. sredni" << endl;
    cout <<"3. trudny" << endl;

    cin >> wybor2;
}


// i dalej w funkcji rysujacej losowa mape na start:

    if (wybor2==1){
    a=5; b=5;
    }

    if (wybor2==2){
    a=8; b=8;
    }

    if (wybor2==3){
    a=10; b=10;
    }

for(int i=0;i<a;i++){
     for(int j=0;j<b;j++){
         tab[i][j]=(rand()%2)+0;
      }
}

for(int i=0;i<a;i++){
      for(int j=0;j<b;j++){
          cout << tab[i][j] << ' ';
      }
       cout << endl;
}

tylko dana wybor2 nie chce wylapywac informacji z funkcji zapisanej wyzej(frienda nie umiem zbytnio zastosowac, wykrzaczaja sie, ale niewiem czy by pomogl)/

jak inaczej to rozwiazac? :<

0
enum Difficulty { EASY = 5, MEDIUM = 8, HARD = 10};

class mapa
{
// ..
Difficulty myDifficulty;
// ..
public:
void poziomtrudnosci();
// ..
};

void mapa::poziomtrudnosci()
{
    int wybor;
 
    cout <<"Wybierz poziom trudnosci:" << endl;
    cout <<"1. latwy" << endl;
    cout <<"2. sredni" << endl;
    cout <<"3. trudny" << endl;
 
    cin >> wybor;
    if(wybor==1) myDifficulty = EASY
    else if(wybor==2) myDifficulty = MEDIUM;
    else if(wybor==3) myDifficulty = HARD;
}
 
 
// i dalej w funkcji rysujacej losowa mape na start:
 
for(int i=0;i<myDifficulty;i++){
     for(int j=0;j<myDifficulty ;j++){
         tab[i][j]=(rand()%2)+0;
      }
}
 
for(int i=0;i<myDifficulty ;i++){
      for(int j=0;j<myDifficulty ;j++){
          cout << tab[i][j] << ' ';
      }
       cout << endl;
}
0

A dlaczego mapa pyta o poziom trudności użytkownika? Mapa powinna dostać info w konstruktorze o rozmiarze jaki powinna używać. A co do błędu u Ciebie to jest klasyczny problem gdy przy nauce nadużywało się zmiennych globalnych. Powinno to być zabronione i surowo karane. wybor2 jest zmienną lokalną i ma zasięg metody poziomtrudnosci, dlatego nie jest i nie będzie widoczna w metodzie rysującej.

Rozmiar tablicy zadeklaruj jako pola klasy i inicjalizuj w konstruktorze.

0

dziekuje mto, zaraz zobacze jak to bedzie wygladac u mnie w programie, jestem wdzieczny!

0

ale zastanów się nad tym co napisał @Sarrus bo ma rację, źle zaprojektowałeś program.

0

Instrukcja:

srand(time(NULL));

Powinna być uruchamiana na początku programu tylko raz, najlepiej zaraz na początku funkcji main()

0

no dobra, a co jesli wczytuje z pliku i tam powiedzmy jest tablica 8x8, jak on ma zliczyc elementy w tablicy (wystarczy ze zliczy elementy pierwszego wiersza). wklejam co obecnie mam - tam podana jest "5", ale chcialbym wrzucic dana ktora najpierw zliczy mi wiersze...

zwyklym forem to zrobic i do czasu az napotka "\n"?
tylko jak on to sobie bedzie liczyl 1,2,3,4,5?...

void mapa::wczytaj(){

    cout << "Podaj nazwe pliku do wczytania (wraz z .txt):" << endl;
    char *nazwapliku;
    cin >> nazwapliku;

    fstream plik;

    plik.open(nazwapliku, ios::in);
        if( plik.good() == true ){
            cout << "Plik zostal otwarty!" << endl << endl;
        }
        else cout << "Pliku nie otwarto - nie istnieje." << endl << endl ;

        for(int i=0;i<5;i++){ // wczytywanie z pliku danych do tablicy
            for(int j=0;j<5;j++){
                plik >> tab[i][j];
            }
        }
    plik.close();
}

prosze o pomoc, dziekuje !

0
void mapa::wczytaj(){

    cout << "Podaj nazwe pliku do wczytania (wraz z .txt):" << endl;
    char *nazwapliku;
    cin >> nazwapliku;

    fstream plik;

    plik.open(nazwapliku, ios::in);

        if( plik.good() == true ){
            cout << "Plik zostal otwarty!" << endl << endl;
        }
        else cout << "Pliku nie otwarto - nie istnieje." << endl << endl ;

     int licznik=0;
     string nazwa;

     while(getline(plik, nazwa)){ // liczenie wierszy (taka sama bedzie liczba kolumn bo tablica NxN)
        licznik++;
     }
    plik.close();

     cout << "Plik posiada "<< licznik << " wierszy, zatem tablica jest [" << licznik << "]" << "["<< licznik << "]." << endl;

    plik.open(nazwapliku, ios::in);

    for(int i=0;i<licznik;i++){ // wczytywanie z pliku danych do tablicy
        for(int j=0;j<licznik;j++){
            plik >> tab[i][j];
        }
    }
    plik.close();


    cout << "Wczytana tablica:" << endl << endl;
        for(int i=0;i<licznik;i++){ // wypisywanie wczytanej z pliku tablicy
            for(int j=0;j<licznik;j++){
                cout << tab[i][j] << ' ';
            }
        cout << endl;
        }
}

wczytuje tablice wyswietla ja w konsoli i wyskakuje debugger.

jak moge uzyc "licznik" w

 void mapa::rysuj(){

	srand(time(NULL));

	    for(int i=0;i<myDifficulty;i++){
            for(int j=0;j<myDifficulty;j++){
                tab[i][j]=(rand()%2)+0;
            }
        }

        for(int i=0;i<myDifficulty;i++){
            for(int j=0;j<myDifficulty;j++){
                cout << tab[i][j] << ' ';
            }
            cout << endl;
        }
}

? prosze o pomoc

0

Skąd mam wiedzieć jak zapisujesz dane do pliku ? Piszesz nie zrozumiale. Piszesz program a z pierwszym lepszym problemem zwracasz się od razu na forum. Na tym polega większość pracy programisty (wyłapywaniu i naprawianiu błędów), czasem dojście samemu, kombinowanie nauczy Cię o wiele więcej niżeli proszenie o gotowca na forach.

0

to byl glupi blad, ale uzywanie "licznika" w innych funkcjach to juz wyzsze schody, nie mam pojecia jak tego uzyc, zfriendowac funkcje czy co?

0

nie mam pojecia jak dane "licznik" uzyc gdzies indziej, skoro ta funkcja "lapie" tylko licznik w wczytaj();
...

0

Nie!

Wystarczy napisać odpowiednią funkcję do zapisu i odczytu. A nie bawić się jakoś na około.
Przykładowo struktura zapisu pliku powinna wyglądać tak:

EASY
0 0 1 0 1
1 0 1 0 1
1 0 0 0 1
1 0 1 1 1

Wtedy funkcja do odczytu po wczytaniu bd wiedzieć ile wierszy/kolumn ma plansza. Na podstawie pierwszej linii wiadomo jaką wartość będzie miała zmienna myDifficulty, a wtedy funkcja rysuj() już ładnie wyrysuję planszą. Ogólnie to narobiłeś niezłego syfu z tym kodem.

0

oczywiscie ze masz racje! to znacznie ulatwi program! masz leb gosciu :)

0
void mapa::wczytaj(){

    cout << "Podaj nazwe pliku do wczytania (wraz z .txt):" << endl;
    char *nazwapliku;
    cin >> nazwapliku;

    fstream plik;

    plik.open(nazwapliku, ios::in);

        if( plik.good() == true ){
            cout << "Plik zostal otwarty!" << endl << endl;
        }
        else cout << "Pliku nie otwarto - nie istnieje." << endl << endl ;

    int licznik=0;

    while(!plik.peek()==' '){
    plik >>licznik;
    licznik = myDifficulty;
    }


    plik.close();

    ///////////////

    plik.open(nazwapliku, ios::in);

    for(int i=0;i<myDifficulty;i++){ // wczytywanie z pliku danych do tablicy
        for(int j=0;j<myDifficulty;j++){
            plik >> tab[i][j];
        }
    }
    plik.close();

    cout << "Wczytana tablica:" << endl << endl;
        for(int i=0;i<myDifficulty;i++){ // wypisywanie wczytanej z pliku tablicy
            for(int j=0;j<myDifficulty;j++){
                cout << tab[i][j] << ' ';
            }
        cout << endl;
        }
}

debugger krzyczy :(:(

0
    char *nazwapliku; // wskaźnik nie zainicjalizowany, wskazuje np na "jądro systemu"
    cin >> nazwapliku; // wczytujesz pod ten wskaźnik = próbujesz zmienić kod "jadra systemu"

Nic dziwnego że krzyczy.

Powinno to wyglądać mniej więcej tak:

bool mapa::wczytaj(istream &plik) // możesz użyć do wczytania z konsoli
  {
   int size=0;
   if((plik>>size)&&(5<=size)&&(size<=20)) // wczytany size w granicach 5..20
     {
      int max=size*size;
      short *tb=new short[max];
      for(int i=0;i<max;++i) plik>>tb[i];
      if(plik) // jeżeli wszystko wczytano poprawnie, to wpisujemy do klasy
        {
         myDifficulty=size;
         for(int y=0,i=0;y<size;++y) for(int x=0;x<size;++x,++i) tab[y][x]=tb[i];
        }
      else size=0;
      delete[] tb;
     }
   return size;
  }

bool mapa::wczytaj(const char *plik)
  {
   ifstream fs(plik);
   bool ret=wczytaj(fs);
   fs.close();
  }
  
int main()
  {
   mapa m;
   cout<<"podaj nazwe: ";
   char buf[1024];
   cin.getline(buf,1024);
   if(!m.wczytaj(buf)) cout<<"wczytywanie nie powiodlo sie"<<endl;
   
   return 0;
  }

Sama mapa nie powinna nic pisać na ekran, tym ma się zajmować interfejs z użytkownikiem.
Jeżeli chcesz rozróżniać błędy, co innego brak pliku a co innego plik jest nieodpowiednio skonstruowany to lepiej pobaw się wyjątkami.

0

czlowiek slepy i takie bledy robi, dzieki :)

jak juz Was mecze to mam jeszcze jedno pytanie:

  1. mam napisanych kilka sposobow na zmiany pol
  2. chce zainicjowac tablice 5x5 zapelniona jedynkami
  3. i losowo uzyc po dwa razy z kazdego krokow na zmiane (kazdy krok to metoda)
    jak to zrobic randem?
0

Ad 2. for(int y=0;y<5;++y) for(int x=0;x<5;++x) tab[y][x]=rand()&1;
Pozostałe punkty proszę przetłumaczyć na jakiś przyzwoity język, np na polski.

0
  1. to wiedzialem jak zrobic:P

mam trzy funkcje krok1,krok2,krok3 - kazdy polega na czyms innym np. krok1 zmienia liczbe przeciwna na gorze i na dole podanej, krok2 po przekatnej, krok3 tylko na dole

chcialbym wywolac ja na poczatku programu, losowo powiedzmy w roznych schematach, krok3,krok2,krok1, gdzie kazda jest funkcja.

PYTANIE: jak zaczac czytanie z pliku do tablicy pomijajac pierwsza linie?

0

"Na podstawie pierwszej linii wiadomo jaką wartość będzie miała zmienna myDifficulty, a wtedy funkcja rysuj() już ładnie wyrysuję planszą. "

tylko Difficulty to enum, nie moge zmieniac/przypisywac wartosci... zapisywac do pliku owszem, i ladnie to wychodzi, ale na odwrot juz cienko

2

Wychodzi cienko ponieważ brak ci umiejętności.. albo trochę pomysłowości.. znowu chcesz gotowca ?

0

nieeee, nakierowanie! :)

0
kkk123 napisał(a):

nieeee, nakierowanie! :)

Ale Ty oczekujesz, że instruktor prawa jazdy będzie Ci cisnął na pedały i zmieniał biegi, a Ty będziesz tylko kręcić kierownicą

0

ale czy to az tak duzo Was kosztuje(Wy widzicie rozwiazanie po kilku sekundach), zeby pomoc? nie chce gotowego kodu, tylko samej wskazowki jak mozna zmienna "licznik" uzyc/przypisac do myDifficulty, zeby dalej ja uzywac..

void mapa::wczytaj(){

    cout << "Podaj nazwe pliku do wczytania (wraz z .txt):" << endl;
    string nazwapliku;
    cin >> nazwapliku;

    fstream plik;
    plik.open(nazwapliku.c_str(), ios::in);

        if( plik.good() == true ){
            cout << "Plik zostal otwarty!" << endl << endl;
        }
        else cout << "Pliku nie otwarto - nie istnieje." << endl << endl;

    int licznik;
    plik >> licznik;

    cout << "Licznik wierszy/kolumn: " << licznik << ". " << endl;

    for(int i=0;i<licznik;i++){ // wczytywanie z pliku danych do tablicy
        for(int j=0;j<licznik;j++){
            plik >> tab[i][j];
        }
    }
    plik.close();

    cout << "Wczytana tablica:" << endl << endl;
        for(int i=0;i<licznik;i++){ // wypisywanie wczytanej z pliku tablicy
            for(int j=0;j<licznik;j++){
                cout << tab[i][j] << ' ';
            }
        cout << endl;
        }
}
void mapa::zapisz(){ // chcialbym uzyc tutaj zmiennej licznik jako myDifficulty, ale przypisanie nie dziala...


    ofstream plik1("zapis_gry.txt");
    plik1 << myDifficulty << endl;

    for(int i=0;i<myDifficulty;i++){ // wczytywanie z pliku danych do tablicy
        for(int j=0;j<myDifficulty;j++){
            plik1 << tab[i][j] << ' ';
        }
        plik1 << endl;
    }

    plik1.close();
    cout <<"Aktualny stan gry zapisany w 'zapis_gry.txt'."<< endl;
}

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