Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Tworzenie nowej tablicy na podstawie innej przez sumowanie poszczególnych wartości

Ostatnio zmodyfikowano 2019-02-27 20:09
Autor Wiadomość
rafallauterbach
» 2019-01-27 16:07:23
Ta linijka daje tej tablicy wartości losowo 1 albo 0, ale jak ją po prostu usuniesz to ttablicanie będzie miała w sobie żadnych wartości. Powinnaś wrzucić losowe wartości do pierwszej tablicy ale w innym miejscu, a nie w display array.
P-173717
4neta
Temat założony przez niniejszego użytkownika
» 2019-01-27 16:50:10
Oczywiście... Wybaczcie, że tak wolno kojarzę.

Wrzuciłam to po prostu do początku funkcji main:
C/C++
#include <iostream>
#include <cstdlib>

using namespace std;

void countNextArray( int firstArray[ 10 ][ 10 ], int secondArray[ 10 ][ 10 ] )
{
    int sum[ 10 ][ 10 ];
    for( int i = 0; i < 10; i++ ) {
        for( int j = 0; j < 10; j++ ) {
            sum[ i ][ j ] = 0;
            int temp = 0;
           
            //            cout << "(" << i << ", " << j  << "): ";
           
            for( int k = - 1; k <= 1; k++ ) {
                for( int l = - 1; l <= 1; l++ ) {
                    temp = firstArray[( 10 + i + k ) % 10 ][( 10 + j + l ) % 10 ];
                    //                    cout << temp << " ";
                    sum[ i ][ j ] += temp;
                }
            }
            //            cout << "\n";
           
            sum[ i ][ j ] -= firstArray[ i ][ j ]; // suma sasiadow = suma 9 komorek - srodkowa
           
            int cell = firstArray[ i ][ j ];
            int sumOfNeighbours = sum[ i ][ j ];
           
            if( cell == 0 && sumOfNeighbours == 3 )
                 secondArray[ i ][ j ] = 1;
            else if( cell == 0 && sumOfNeighbours != 3 )
                 secondArray[ i ][ j ] = 0;
            else if( cell == 1 &&( sumOfNeighbours == 2 || sumOfNeighbours == 3 ) )
                 secondArray[ i ][ j ] = 1;
            else
                 secondArray[ i ][ j ] = 0;
           
           
           
        }
    }
   
    cout << "\n array of sum: \n";
    for( int i = 0; i < 10; i++ ) {
        for( int j = 0; j < 10; j++ ) {
            cout << sum[ i ][ j ] << ".";
        }
        cout << endl;
    }
    cout << "\n";
}

void displayArray( int array[ 10 ][ 10 ] ) {
    for( int i = 0; i < 10; i++ ) {
        for( int j = 0; j < 10; j++ ) {
            if( array[ i ][ j ] == 0 )
                 cout << "_";
            else
                 cout << "X";
           
        }
        cout << endl;
    }
    cout << endl;
}

int main()
{
    int evenArray[ 10 ][ 10 ], oddArray[ 10 ][ 10 ];
   
    for( int i = 0; i < 10; i++ ) {
        for( int j = 0; j < 10; j++ ) {
            evenArray[ i ][ j ] = rand() % 2;
        }
    }
   
    cout << "evenArray: \n";
    displayArray( evenArray );
   
    countNextArray( evenArray, oddArray );
   
    cout << "oddArray: \n";
    displayArray( oddArray );
   
    return 0;
}

Konsolka:
evenArray:
XX__X_____
XXXXXXX_X_
X__X__X__X
X_X_X_XXX_
XX_XX_XXX_
X__XXXXXX_
_X________
_X_X___XX_
XX______X_
_X_XX___XX


 array of sum:
5.5.6.6.5.5.2.3.3.5.
5.5.4.4.4.4.2.3.1.5.
4.6.5.5.5.6.4.6.4.5.
4.5.3.5.3.5.4.6.4.6.
3.4.4.5.5.7.6.8.5.6.
3.4.4.3.4.4.4.5.3.4.
3.2.4.3.4.3.4.5.4.3.
4.3.4.0.1.0.1.2.2.3.
4.3.5.3.3.1.1.4.4.5.
6.4.4.2.2.2.0.2.2.4.

oddArray:
_______XX_
______XX__
__________
__X_X_____
X_________
X__X____X_
XX_X_X___X
_X_____XXX
_X_XX_____
___XX___X_

Wygląda na to, że wszystko dobrze liczy. Dziękuję bardzo. :)
P-173718
rafallauterbach
» 2019-01-27 17:26:20
Jak działa, to dobra robota :) temat mnie zainteresowal bo 2 lata temu miałem projekt na studiach dot game of life. Miałem łatwo konfigurowalną zmianę wielkości mapy i reguł gry, ale też pare rzeczy bym teraz inaczej napisał niż wtedy.

[spoiler]
C/C++
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

void pomoc( const bool & a ) { // &a -> 0-help request 1-error
    if( a )
         cout << "Podales bledne dane, uzyj przelacznika -h aby uzyskac pomoc.";
    else
         cout << "Do programu nalezy podac dokladnie 2 argumenty poprzedzone odpowiednim przelacznikiem : \n 1. -i \"<sciezka pliku wejsciowego>\"\n 2. -p  <liczba pokolen>";
   
}

bool Sprawdz_Sciezke( const char * sprawdz, fstream & plik ) { //check -i data
    plik.open( sprawdz );
    if( plik.good() == true )
         return 0;
    else
         cout << "Nie mozna otworzyc pliku : " << sprawdz << endl;
   
    return 1;
}

bool Sprawdz_Pokolenia( const int & sprawdz ) { //check -p data
    if( sprawdz < 0 ) {
        cout << "Liczba pokolen musi byc wieksza badz rowna zeru." << endl;
        return 1;
    }
    return 0;
}

string intostring( int a ) {
    stringstream ss;
    ss << a;
    return ss.str();
}

int string_to_int( const string & a ) {
    stringstream ss;
    int liczba;
    ss << a;
    ss >> liczba;
   
    return liczba;
   
}

bool string_to_bool( const string & a ) { //returning false for "0" and true for anything else
    if( a == "0" )
         return 0;
    else
         return 1;
   
}

string gen_name( const char * input, const int & n ) { //generate filename
    string extension = ""; //backwards...
    int j;
    for( j = string( input ).length() - 1; input[ j ] != '.'; j-- ) //reading extension
    if( j == 0 )
         break;
    else
         extension += input[ j ];
   
    extension += input[ j ]; // -- reading extension
    string result = "";
    for( int i = 0; i < string( input ).length(); i++ ) // reading name and writing new name
    if( i == j )
         break;
    else
         result += input[ i ];
   
    result += '-';
    result += intostring( n );
    for( int i = 1; i <= extension.length(); i++ )
         result += extension[ extension.length() - i ];
   
    return result;
}

void gra( fstream & INPUT, const int & LICZBA_POKOLEN, const char * input ) {
    const char ZNAK_KOMORKA_ZYWA = '*';
    const char ZNAK_KOMORKA_MARTWA = '.';
    const unsigned long WYSOKOSC_MAPY = 22; //20x20 with 1 width frame
    const unsigned long SZEROKOSC_MAPY = 22;
    bool reguly[ 18 ] = {
        0, //survive when 0 neighbors
        0, //survive when 1 neighbor
        1, //survive when 2 neighbors
        1, //survive when 3 neighbors
        0, //survive when 4 neighbors
        0, //survive when 5 neighbors
        0, //survive when 6 neighbors
        0, //survive when 7 neighbors
        0, //survive when 8 neighbors
        0, //reproduce when 0 neighbors
        0, //reproduce when 1 neighbor
        0, //reproduce when 2 neighbors
        1, //reproduce when 3 neighbors
        0, //reproduce when 4 neighbors
        0, //reproduce when 5 neighbors
        0, //reproduce when 6 neighbors
        0, //reproduce when 7 neighbors
        0 //reproduce when 8 neighbors
    };
   
    cout << "Init..." << endl;
    char mapa1[ WYSOKOSC_MAPY * SZEROKOSC_MAPY ];
    char mapa2[ WYSOKOSC_MAPY * SZEROKOSC_MAPY ];
    for( int i = 0; i < WYSOKOSC_MAPY * SZEROKOSC_MAPY; i++ )
    {
        mapa1[ i ] = 0;
        mapa2[ i ] = 0;
    }
   
    cout << "Odczyt..." << endl;
    string znak; //temp string
    for( int i = 1; i < WYSOKOSC_MAPY - 1; i++ )
    for( int j = 1; j < SZEROKOSC_MAPY - 1; j++ ) {
        INPUT >> znak;
        if( string_to_bool( znak ) ) //anything else than 0 is 1
             mapa1[ SZEROKOSC_MAPY * i + j ] = 1;
        else
             mapa1[ SZEROKOSC_MAPY * i + j ] = 0;
       
    }
    znak.erase();
    INPUT.close(); //after read never need it again
   
   
    ofstream output;
    cout << "Konwertowanie pliku wejsciowego: " << endl;
    for( int i = 1; i < WYSOKOSC_MAPY - 1; i++ ) {
        for( int j = 1; j < SZEROKOSC_MAPY - 1; j++ )
        if(( bool ) mapa1[ SZEROKOSC_MAPY * i + j ] )
             cout << ZNAK_KOMORKA_ZYWA;
        else
             cout << ZNAK_KOMORKA_MARTWA;
       
        cout << endl;
    }
   
    cout << "Zapis zerowej generacji " << endl;
    output.open( gen_name( input, 0 ).c_str() );
    for( int i = 1; i < WYSOKOSC_MAPY - 1; i++ ) {
        for( int j = 1; j < SZEROKOSC_MAPY - 1; j++ )
        if(( bool ) mapa1[ SZEROKOSC_MAPY * i + j ] )
             output << ZNAK_KOMORKA_ZYWA << " ";
        else
             output << ZNAK_KOMORKA_MARTWA << " ";
       
        output << endl;
    }
    output.close();
   
    unsigned long long pos; //current position in array         long^2 because max is (long)width*(long)height
    char * nowa, * mapa; //current new and old map
    for( int n = 1; n < LICZBA_POKOLEN + 1; n++ ) {
        cout << "Zapisywanie generacji nr : " << n << endl;
        //making generation
        if( n % 2 == 0 ) { // swapping array pointer, to remember only 1 last generation
            nowa = mapa1;
            mapa = mapa2;
        }
        else {
            nowa = mapa2;
            mapa = mapa1;
        }
        for( int i = 1; i < WYSOKOSC_MAPY - 1; i++ )
        for( int j = 1; j < SZEROKOSC_MAPY - 1; j++ ) { // checking all but no 1-width frame
            pos =( SZEROKOSC_MAPY * i ) + j; //  current position
            if( mapa[ pos ] ) //  was 1
            if( reguly[ mapa[ pos - SZEROKOSC_MAPY - 1 ] +
            mapa[ pos - SZEROKOSC_MAPY ] +
            mapa[ pos - SZEROKOSC_MAPY + 1 ] +
            mapa[ pos - 1 ] + mapa[ pos + 1 ] +
            mapa[ pos + SZEROKOSC_MAPY - 1 ] +
            mapa[ pos + SZEROKOSC_MAPY ] +
            mapa[ pos + SZEROKOSC_MAPY + 1 ] ] )
                 nowa[ pos ] = 1; // rules let him exist
            else
                 nowa[ pos ] = 0; // rules let him die
            else //  was 0
            if( reguly[ 9 + mapa[ pos - SZEROKOSC_MAPY - 1 ] +
            mapa[ pos - SZEROKOSC_MAPY ] +
            mapa[ pos - SZEROKOSC_MAPY + 1 ] +
            mapa[ pos - 1 ] + mapa[ pos + 1 ] +
            mapa[ pos + SZEROKOSC_MAPY - 1 ] +
            mapa[ pos + SZEROKOSC_MAPY ] +
            mapa[ pos + SZEROKOSC_MAPY + 1 ] ] )
                 nowa[ pos ] = 1; // rules let him spawn
            else
                 nowa[ pos ] = 0; // not let him spawn
           
        }
       
        output.open( gen_name( input, n ).c_str() );
        for( int i = 1; i < WYSOKOSC_MAPY - 1; i++ ) {
            for( int j = 1; j < SZEROKOSC_MAPY - 1; j++ )
            if(( bool ) nowa[ SZEROKOSC_MAPY * i + j ] )
                 output << ZNAK_KOMORKA_ZYWA << " ";
            else
                 output << ZNAK_KOMORKA_MARTWA << " ";
           
            output << endl;
        }
        output.close();
    }
    cout << "Koniec.";
}

int main( int argc, char * argv[] ) {
   
    fstream plik; //input file
    const string P_INPUT = "-i"; //switch names
    const string P_POKOLENIA = "-p";
    const string P_POMOC = "-h"; // ------------
    bool i_podane = 0; //input flag
    bool p_podane = 0; //generations flag
    int liczba_pokolen = 0; //store -p data
    char * input; //store -i data
   
    if( argc > 1 && argv[ 1 ] == P_POMOC ) { //checking if first argument is help if exist
        pomoc( 0 );
        return 0;
    }
    if( argc != 5 ) {
        pomoc( 1 );
        return 0;
    }
    else
    for( int i = 1; i < 5; i++ ) {
        if( argv[ i ] == P_INPUT ) {
            input = argv[ ++i ];
            if( !( i_podane || Sprawdz_Sciezke( input, plik ) ) ) {
                i_podane = 1;
            }
        }
        else if( argv[ i ] == P_POKOLENIA ) {
            liczba_pokolen = string_to_int(( string ) argv[ ++i ] );
            if( !( p_podane || Sprawdz_Pokolenia( liczba_pokolen ) ) ) {
                p_podane = 1;
            }
        }
    }
    if( p_podane && i_podane ) {
        gra( plik, liczba_pokolen, input );
    }
    else
         pomoc( 1 );
   
    return 0;
}
[/spoiler]
P-173720
4neta
Temat założony przez niniejszego użytkownika
Kontynuacja
» 2019-02-27 09:25:25
Nie jestem pewna, czy mogę założyć nowy temat, gdy problem dotyczy tego samego programu, więc na razie piszę tutaj.

Programik już działa. Pomijając niuanse, czy lepszy sposób organizacji kodu, mam jeden problem. Ustawiłam go tak, by za każdym razem losował układ wejściowej tablicy funkcją rand()%2. Niestety, zapamiętuje ten jeden wylosowany układ i mimo prób wyzerowania (funkcje memset lub wpisywanie zer w macierz), przy każdej kompilacji działa na tej samej tablicy. Ktoś na innym forum doradzał ustawienie zmiennych jako globalne, to miało rozwiązać problem, niestety również nie przynosi rezultatów.

C/C++
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <windows.h>

using namespace std;

#define N 10
#define M 20
#define ITERATIONS 50

int evenArray[ N ][ M ], oddArray[ N ][ M ], firstArray[ N ][ M ];

void countNextArray( int firstArray[ N ][ M ], int secondArray[ N ][ M ] )
{
    int sum[ N ][ M ];
    for( int i = 0; i < N; i++ ) {
        for( int j = 0; j < M; j++ ) {
            sum[ i ][ j ] = 0;
            int temp = 0;
           
            for( int k = - 1; k <= 1; k++ ) {
                for( int l = - 1; l <= 1; l++ ) {
                    temp = firstArray[( N + i + k ) % N ][( M + j + l ) % M ];
                    sum[ i ][ j ] += temp;
                }
            }
           
            sum[ i ][ j ] -= firstArray[ i ][ j ]; // suma sasiadow = suma 9 komorek - srodkowa
           
            int cell = firstArray[ i ][ j ];
            int sumOfNeighbours = sum[ i ][ j ];
           
            if( cell == 0 && sumOfNeighbours == 3 )
                 secondArray[ i ][ j ] = 1;
            else if( cell == 0 && sumOfNeighbours != 3 )
                 secondArray[ i ][ j ] = 0;
            else if( cell == 1 &&( sumOfNeighbours == 2 || sumOfNeighbours == 3 ) )
                 secondArray[ i ][ j ] = 1;
            else
                 secondArray[ i ][ j ] = 0;
           
           
           
        }
    }
}

void displayArray( int array[ N ][ M ] ) {
    for( int i = 0; i < N; i++ ) {
        for( int j = 0; j < M; j++ ) {
            if( array[ i ][ j ] == 0 )
                 cout << " ";
            else
                 cout << "X";
           
        }
        cout << endl;
    }
    cout << endl;
}

int main()
{
    for( int i = 0; i < N; i++ ) {
        for( int j = 0; j < M; j++ ) {
            evenArray[ i ][ j ] = rand() % 2;
        }
    }
   
    for( int i = 0; i < ITERATIONS; i++ ) {
        cout << "Iteration number " << 2 * i + 1 << endl;
        displayArray( evenArray );
        Sleep( 40 ); // sleep for n miliseconds
        memset( oddArray, 0, N * M * sizeof( int ) );
        countNextArray( evenArray, oddArray );
        system( "cls" ); // czyszczenie kosolki
       
        cout << "Iteration number " << 2 * i + 2 << endl;
        displayArray( oddArray );
        Sleep( 40 );
        memset( evenArray, 0, N * M * sizeof( int ) ); // czyszczenie macierzy
        countNextArray( oddArray, evenArray );
        system( "cls" );
    }
   
    return 0;
}

Przy wymiarach N=10 i M=20 ostatnie tablice zawsze wyglądają tak (układ stały):
Iteration number 100
                 XX


 X
X X
XX    XX
      XX
                 XX
                X  X
                X  X

Gdzie tkwi błąd?
P-174076
Monika90
» 2019-02-27 09:58:29
Rand generuje za każdym razem ten sam ciąg liczb, żeby mieć różne ciągi trzeba inicjalizować generator różnymi ziarnami. Bardzo prymitywny ale wystarczający tutaj sposób to dopisać
srand( time( 0 ) );
 na początku funkcji main i dodać
#include <ctime>
 na początku pliku.
P-174077
4neta
Temat założony przez niniejszego użytkownika
» 2019-02-27 20:09:35
Działa, dziękuję. :)
P-174080
1 « 2 »
Poprzednia strona Strona 2 z 2