Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C++] Automate cellulaire et monde d'affichage

Sujet résolu
18 juillet 2014 à 11:24:51

Bonjour!

J'ai terminé la création (plutôt la reproduction ^^) de l'automate cellulaire "le jeu de la vie" de conway en C++. Il marche parfaitement, seulement, je tourne sur un monde de 153*274 carrés de 5px, et j'aimerais m'amuser a faire 1366*768 carrés de 1 px pour voir toutes les évolutions de plusieurs milliers de cellules en même temps. Mon monde est en fait un tableau bidimensionnel, qui contient des 0 et des 1 (1 pour cellule vivante.). Mais problème de mémoire, dès que mon tableau devient plus gros, dès qu'on débute le checking de chaque cellule du tableau, Paf, ça crash... Du coup, je me dis que les tableaux pour les mondes ne doivent pas être une bonne habitude pour ce genre de choses. Mais je ne sais vraiment pas comment faire autrement.

Merci d'avance.

  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 11:29:17

Lu'!

Sujet déjà traité ici : http://fr.openclassrooms.com/forum/sujet/c-tableaux-2d-trop-gros.

Comme on l'a déjà dit 1366*768 c'est rien du tout. Ca tient dans un tableau dès lors qu'il est alloué dynamiquement.

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

18 juillet 2014 à 11:35:14

Et bien après vérification, non! La compilation a cette fois bien lieu, mais l'erreur est plus loin maintenant, lors du premier tour de boucle sur le tableau, tout plante. Merci.

-
Edité par AnselmeClergeot 18 juillet 2014 à 11:41:01

  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 11:37:00

Peux-tu m'expliquer comment les déclarer dynamiquement SANS boost qui est une galère à installer? Et aussi comment parcourir ce tableau si il faut utiliser une manière différente?
  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 11:50:15

Stp
  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 11:55:17

http://fr.wikibooks.org/wiki/Programmation_C%2B%2B/Les_tableaux

C'était si difficile de chercher ?

  • Partager sur Facebook
  • Partager sur Twitter
18 juillet 2014 à 11:59:31

Crois-tu que je n'ai pas terminé le tuto C++? Crois-tu qu'avant de m'embeter à écrire ce sujet je n'ai pas googlé des heures dans toutes les langues possibles? Crois-tu que ta réponse m'est vraiment utile? D'autant plus que le site sur lequel tu m'as vulgairement envoyé ne contient AUCUNE information sur ce que je cherche. La prochaine fois, abstient toi de ce genre de réponses inutiles à souhait.

-
Edité par AnselmeClergeot 18 juillet 2014 à 12:05:07

  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 12:06:43

Si tu ne sais pas instancier dynamiquement un tableau en deux dimensions après avoir "googlé des heures", poses toi quelques questions. Soit dit en passant, la page que je viens de t'envoyer contient un exemple complet et extrêmement bien documenté d'allocation dynamique.
  • Partager sur Facebook
  • Partager sur Twitter
18 juillet 2014 à 12:09:29

Salut.
Comment par  lire  ca: une deque est ce qui te permet de gérer dynamiquement un tableau à une dimension
http://www.cplusplus.com/reference/deque/deque/

Ensuite, comme tu veux un tableau à deux dimension (L lignes et C colones), tu crée une deque de L*C éléments

Tu accèdes à l'élément ligne l, colonne c, en prenant lélément à l'index l*C + c de ta deque.

Et voila c'est tout.

  • Partager sur Facebook
  • Partager sur Twitter
18 juillet 2014 à 12:10:33

Merci beaucoup! Je vais essayer tout ça. :)
  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 12:13:02

@IAmJohn tu lien est obsolète on est en C++ les tableaux style-C c'est moche, regarde std::array.

Sinon la matrix de Ksass (http://fr.openclassrooms.com/forum/sujet/c-tableaux-2d-trop-gros#message-86580617) ne fonctionne pas ?

  • Partager sur Facebook
  • Partager sur Twitter
18 juillet 2014 à 12:13:10

IAmJohn, COMME PRECISE plus haut, j'ai bien réussi à le déclarer dynamiquement, et j'ai EGALEMENT précisé ou ça bloque.
  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 12:13:45

Oprax, je ne comprends pas comment elle fonctionne... Ksass précise qu'il faut l'implémenter, mais rien qu'a voir la tête du .h, ça à l'air supeer dur. :(

-
Edité par AnselmeClergeot 18 juillet 2014 à 12:16:32

  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
18 juillet 2014 à 12:57:24

Oprax a écrit:

@IAmJohn tu lien est obsolète on est en C++ les tableaux style-C c'est moche, regarde std::array.


J'aimerais bien quelques arguments pour appuyer cette réponse un peu trop définitive.
  • Partager sur Facebook
  • Partager sur Twitter
18 juillet 2014 à 13:09:19

IAmJohn a écrit:

Oprax a écrit:

@IAmJohn tu lien est obsolète on est en C++ les tableaux style-C c'est moche, regarde std::array.

J'aimerais bien quelques arguments pour appuyer cette réponse un peu trop définitive.

Les arguments sont ressassés partout où l'on parle de vrai C++ depuis au moins 10 ans.

Très facile, l'exemple de wikipedia contient des fuites de mémoire potentielle. C++ est un langage à exceptions, dans lequel la gestion manuelle des ressources est une hérésie. Le concept central pour la gestion des ressources en C++, c'est le RAII et rien d'autre. En l'occurrence, l'allocation et désallocation de ressources à la main, c'est à bannir.

  • std::vector (et de manière générale, tous les conteneurs de la STL)
  • std::unique_ptr
  • std::shared_ptr/std::weak_ptr

(Dans le cas - rare - où C++11 n'est pas accessible, voir boost::scoped_ptr, boost::scoped_vector, boost::shared_ptr).

A noter : ce n'est pas valable que pour la mémoire. std::lock, std::ofstream et cie, sont d'autres bon exemples de capsule RAII.

AnselmeWindowsDev a écrit:

Ksass précise qu'il faut l'implémenter, mais rien qu'a voir la tête du .h, ça à l'air supeer dur. :(

Je suis sûr qu'en prenant ton mal en patience, tu t'en sortirais, ce n'est pas si compliqué que cela et j'ai bien commenté les fonctionnalités.

Mais bon, un exemple de code minimal pour une matrice comme conteneur simple (pas adapté pour les classes à sémantique d'entité non-polymorphes) :

template<class T>
class Matrix{
public:
  Matrix(std::size_t w, std::size_t h) : _w{w}, _h(h), _data{ new T[_w*_h] }{}
  Matrix(Matrix const& m) : _w{m._w}, _h{m._h}, _data{ new T[_w*_h] }{
    for(unsigned int i{}; i < _w*_h; ++i) _data[i] = m._data[i];
  }
  Matrix& operator=(Matrix const& m){
    Matrix copy{ m };
    swap(m);
    return *this;
  }
  
  Matrix(Matrix&& m) = default;
  Matrix& operator=(Matrix&& m) = default;
  
  void swap(Matrix& m){
    std::swap(_h, m._h);
    std::swap(_w, m._w);
    _data.swap(m._data);
  }
  
  T const& operator()(std::size_t x, std::size_t y) const {
    assert(x < _w && "Out of bound x");
    assert(y < _h && "Out of bound y");
      
    return _data[y*_w + x];
  }
  
  T & operator()(std::size_t x, std::size_t y) {
    assert(x < _w && "Out of bound x");
    assert(y < _h && "Out of bound y");
      
    return _data[y*_w + x];
  }
  
  std::size_t width() const{ return _w; }
  std::size_t height() const{ return _h; }
  
private:
  std::size_t _w;
  std::size_t _h;
  std::unique_ptr<T[]> _data;
};

Utilisation :

int main(){
  Matrix<int> m{ 12, 12 };
  for(unsigned y{}; y < m.height(); ++y)
    for(unsigned x{}; x < m.width(); ++x)
      m(x,y) = y*x;
  
  for(unsigned y{}; y < m.height(); ++y){
    for(unsigned x{}; x < m.width(); ++x)
      std::cout<<m(x,y)<<' ';
    std::cout<<std::endl;
  }
  
  return 0;
}

-
Edité par Ksass`Peuk 18 juillet 2014 à 13:16:38

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

18 juillet 2014 à 13:21:14

std::array est un conteneur implémentant un tableau de taille fixe, les arguments en sa faveur peuvent se résumer à: Parce que c'est ce qui justifie l'existence même du C++ (généricité, invariants,spécifications,encapsulation,SRP,RAII, Object as service provider...).
  • Partager sur Facebook
  • Partager sur Twitter
Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
18 juillet 2014 à 13:25:31

Pour std::array, on peut ajouter ça :

void foo(unsigned const n){
  int t[n];             //un warning éventuel avec pedantic
  std::array<int, n> a; //erreur
}

Et puis l'accès à la fonction std::array::size() avec inlining de la taille par typage.

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

18 juillet 2014 à 14:00:06

J'ai rien de plus à ajouter...
  • Partager sur Facebook
  • Partager sur Twitter
18 juillet 2014 à 17:44:43

Merci à tous, je pense que j'ai tous les outils en main pour régler mon problème...
  • Partager sur Facebook
  • Partager sur Twitter
It is not down on any map; true places never are.
10 novembre 2021 à 15:15:24

Considérons un langage imaginaire qui accepte n'accepte que des uns et des zéros. De plus, pour accepter la phrase, elle doit se terminer par + si elle était dans l'état zéro ou % si elle était dans l'état un. Pou langage sont décrits dans l'image suivante
DFA.h 
#ifndef DETERMINISTIC_FINITE_AUTOMATA_H 
#define DETERMINISTIC_FINITE_AUTOMATA_H 
#include <stdbool.h> 
/* Structs to represent State, Transition and the automata itself */ 
typedef struct DETERMINISTIC_FINITE_AUTOMATA DFA; 
typedef struct DETERMINISTIC_FINITE_AUTOMATA_STATE DFA_State; 
typedef struct DETERMINISTIC_FINITE_AUTOMATA_TRANSITION 
DFA_Transition; 
/* Define an automata transition */ 
struct DETERMINISTIC_FINITE_AUTOMATA_TRANSITION 
{ 
 DFA_State *origin_state; 
 DFA_State *destination_state; 
 char trigger_value; // The value that triggers the transition 
}; 
/* Define an automata state */ 
struct DETERMINISTIC_FINITE_AUTOMATA_STATE 
{ 
 int state_identifier; // Integer number to help end user identify the state 
 bool accept_state; // If this state is an accept state or not 
 int transitions_count; 
 DFA_Transition **transitions; 
}; 
/* Define the automata */ 
struct DETERMINISTIC_FINITE_AUTOMATA 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
{ 
 int states_count; 
 DFA_State **states; 
 DFA_State *current_state; 
 DFA_State *initial_state; 
}; 
/* ====== Functions ====== */ 
/* Automata state manipulation */ 
bool init_automata (DFA *automata); 
bool update_automata (char ch, DFA *automata); 
/* Automata abstraction of state updates */ 
bool belongs_to_language (char *string, DFA *automata); 
/* Alloc abstaction */ 
DFA_State* create_state (int state_identifier, bool accept_state, DFA *automata); 
DFA_Transition* create_transition (char trigger_value, DFA_State *origin_state, 
DFA_State *destination_state); 
DFA* create_automata (); 
/* Allow creation of several transitions simply */ 
bool generate_transitions(char *string, DFA_State *origin_state, DFA_State 
*destination_state); 
/* Dealloc abstraction */ 
bool free_automata (DFA *automata); 
/* ====== DEBUG FUNCTIONS ====== */ 
void describe_automata (DFA *automata); 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
#endif // DETERMINISTIC_FINITE_AUTOMATA_H 
DFA.c 
#include "dfa.h" 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
bool init_automata (DFA *automata) 
{ 
 if (!automata->initial_state) { 
 printf("[-] Error: Initial state of automata not set.\n"); 
 exit(1); 
 } 
 return (automata->current_state = automata->initial_state); 
} 
bool update_automata (char ch, DFA *automata) 
{ 
 DFA_State *state = automata->current_state; 
 bool made_transition = false; 
 for (int j = 0; j < state->transitions_count; j++) { 
 if (state->transitions[j]->trigger_value == ch) { 
 automata->current_state = state->transitions[j]->destination_state; 
 made_transition = true; 
 break; // Finite automata does not have 'choices'. If trigger_value matches, then the 
automata must not have another transition with the same value. 
 } 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
 } 
 if (!made_transition) { // Automata will always execute a transition if value is accepted. 
Even if the transition result in the same stage. 
 return false; 
 } 
 return true; 
} 
bool belongs_to_language (char *string, DFA *automata) 
{ 
 if (strlen(string) == 0) { 
 printf("[-] Error: Empty string sent to analyse in belongs_to_language.\n"); 
 exit(1); 
 } 
 init_automata(automata); 
 for (int i = 0; i < strlen(string); i++) { 
 if (!update_automata(string[i], automata)) { 
 return false; 
 } 
 } 
 return automata->current_state->accept_state; 
} 
bool set_transition_to_state (DFA_Transition **transition, DFA_State *origin_state) 
{ 
 DFA_Transition **tmp = realloc(origin_state->transitions, (origin_state-
>transitions_count + 1) * sizeof(DFA_Transition)); 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
 if (tmp == NULL) { 
 printf("[-] Error during reallocation of state transitions. Trying again.\n"); 
 tmp = realloc(origin_state->transitions, (origin_state->transitions_count + 1) * 
sizeof(DFA_Transition)); 
 if (tmp == NULL) { 
 printf("[-] Error during reallocation of state transitions.\n"); 
 exit(1); 
 } 
 } 
 origin_state->transitions = tmp; 
 origin_state->transitions[origin_state->transitions_count] = *transition; // Add new 
transitions to array of transitions 
 origin_state->transitions_count += 1; 
 return true; 
} 
bool set_state_to_automata (DFA_State **state, DFA *automata) 
{ 
 automata->states = realloc(automata->states, (automata->states_count + 1) * 
sizeof(DFA_State)); 
 if (!automata->states) { 
 printf("[-] Error during reallocation of automata states.\n"); 
 exit(1); 
 } 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
 automata->states[automata->states_count] = *state; // Add new state to the final of the 
array 
 automata->states_count += 1; 
 return true; 
} 
DFA_State* create_state (int state_identifier, bool accept_state, DFA *automata) 
{ 
 DFA_State *state = malloc(sizeof(DFA_State)); 
 if (!state) { 
 printf("[-] Error during allocation of state.\n"); 
 exit(1); 
 } 
 state->accept_state = accept_state; 
 state->transitions_count = 0; 
 state->state_identifier = state_identifier; 
 state->transitions = NULL; 
 set_state_to_automata(&state, automata); 
 return state; 
} 
DFA_Transition* create_transition (char trigger_value, DFA_State *origin_state, 
DFA_State *destination_state) 
{ 
 DFA_Transition *transition = malloc(sizeof(DFA_Transition)); 
 if (!transition) { 
 printf("[-] Error during allocation of transition.\n"); 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
 exit(1); 
 } 
 transition->trigger_value = trigger_value; 
 transition->origin_state = origin_state; 
 transition->destination_state = destination_state; 
 set_transition_to_state(&transition, origin_state); 
 return transition; 
} 
bool generate_transitions (char *string, DFA_State *origin_state, DFA_State 
*destination_state) 
{ 
 for (int i = 0; i < strlen(string); i++) { 
 if (!create_transition(string[i], origin_state, destination_state)) { 
 return false; 
 } 
 } 
 return true; 
} 
DFA* create_automata () 
{ 
 DFA *automata = malloc(sizeof(DFA)); 
 if (!automata) { 
 printf("[-] Error during allocation of automata.\n"); 
 exit(1); 
 } 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
 automata->states_count = 0; 
 automata->initial_state = NULL; 
 automata->states = NULL; 
 return automata; 
} 
bool free_automata (DFA *automata) 
{ 
 for (int i = 0; i < automata->states_count; i++) { 
 for (int j = 0; j < automata->states[i]->transitions_count; j++) { 
 free(automata->states[i]->transitions[j]); 
 } 
 free(automata->states[i]); 
 } 
 free(automata); 
 return true; 
} 
/* ========== DEBUG FUNCTIONS ========== */ 
void describe_transition (DFA_Transition *transition) 
{ 
 printf("------ Origin state: %p\n", transition->origin_state); 
 printf("------ Destination state: %p\n", transition->destination_state); 
 printf("------ Trigger value: %c\n", transition->trigger_value); 
} 
void describe_state (DFA_State *state) 
Université Sidi Mohamed Ben Abdellah 
Faculté des Sciences dhar el mahraz Fes Compilation 
{ 
 printf("--- Accept state: %d\n", state->accept_state); 
 if (state->transitions_count > 0) { 
 printf("--:: Transitions dump (%d):\n", state->transitions_count); 
 for (int i = 0; i < state->transitions_count; i++) { 
 printf("------ Transition %d\n", i); 
 describe_transition(state->transitions[i]); 
 } 
 } else { 
 printf("--:: State has no transitions to dump.\n"); 
 } 
} 
void describe_automata (DFA *automata) 
{ 
 printf("Automata dump:\n"); 
 if (automata->states_count > 0) { 
 printf(":: States dump (%d):\n", automata->states_count); 
 for (int i = 0; i < automata->states_count; i++) { 
 printf(":: State %d\n", i); 
 describe_state(automata->states[i]); 
 } 
 } else { 
 printf("--- Automata has no states to dump.\n"); 
 } 
} 
Écrire le programme principale main.c pour vérifie ces 2 expression régulière  a-aaaa--0101%  100101011
  • Partager sur Facebook
  • Partager sur Twitter
10 novembre 2021 à 15:29:43

Déterrage + langage C dans un forum C++ : GG
  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
10 novembre 2021 à 15:40:31

@mmoradaamraouy Bonjour, merci de ne pas déterrer d'ancien sujet résolu.

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter