IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Valeurs aléatoires dans un tableau C++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut Valeurs aléatoires dans un tableau C++
    Bonjour tout le monde,
    Voilà, je suis en ce moment en projet où je dois créer un pacman.
    Pour l'instant je veux pouvoir afficher aléatoirement 2 fruits lors d'une partie (un niveau).
    Voici ce que je veux pouvoir faire :
    - Je tire un chiffre au hasard (entre 0 et 20)
    - Ce chiffre sera le nombre de secondes au bout duquel mon fruit apparaîtra
    - Le fruit doit apparaître pendant un temps donné
    - J'ai 2 fruits par niveau

    Voici mon code pour le moment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    #include <iostream>
    #include <stdlib.h>
    #include <time.h>
     
    using namespace std;
    int rdtsc()
    {
        __asm__ __volatile__("rdtsc"); //Permet d'obtenir le nombre de cycles utilisés par le processeur depuis le démarrage du programme
    }
     
    int main()
    {
        srand(rdtsc());
        int nb_un =  rand()%20;
        srand(rdtsc());
        int nb_deux = (rand()%20)+20;
        cout << nb_un << endl << nb_deux;
     
        //int i; //Je déclare ma variable i
        //for(i=0; i<2; i++)//Pour i allant de 0 à 2 en décroissant
        //    {
        //        srand(rdtsc());//Amorçage de rand()
        //        cout << (rand()%20) << endl;//Affiche 2 chiffres aléatoires compris entre 0 et 20
        //    }
     
     
     
     
        return 0;
    }
    Le truc c'est que je préfèrerai utiliser mon code en commentaire (la boucle for) afin que le jeu soit plus évolutif (par exemple je veux qu'il y ait 5 fruits par niveau au lieu de 2). Là où je suis bloquée c'est :
    - Comment faire en sorte que mon 2ème fruit apparaisse au bout d'un temps +20secondes de la première apparition du fruit ?
    - Comment récupérer mes valeurs aléatoires dans ma boucle fort afin de pouvoir les stocker ?
    - Comment je peux afficher mon fruit au bout du temps de cette valeur aléatoire ?

    Merci d'avance !

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Ne JAMAIS appeler srand() deux fois dans le même programme, tu risques des effets de bord assez infects. Je te conseille la lecture de cette discussion sur le sujet du rand/srand, avec de quoi faire quelque chose correct et portable...

    Donc, commence par n'avoir qu'un seul srand(), en début de programme. Après, pour le reste de tes questions :

    Citation Envoyé par 0nn2belle Voir le message
    - Comment faire en sorte que mon 2ème fruit apparaisse au bout d'un temps +20secondes de la première apparition du fruit ?
    Utiliser un timer. Vu les durées impliquées, tu peux faire ça avec sleep/alarm, ou alors tu vas un poil plus loin et tu utilises un thread dédié avec sémaphores et interrogation d'un timer haute précision (dépend de l'OS, mais t'as de quoi faire du portable dans la discussion précitée).

    Citation Envoyé par 0nn2belle Voir le message
    - Comment récupérer mes valeurs aléatoires dans ma boucle fort afin de pouvoir les stocker ?
    Tu crée simplement un vecteur (std::vector<int>), tu le dimensionne suivant le nombre de fruits à gérer (via sa méthode reserve()), puis tu affectes chaque cellule à la valeur calculée (via l'opérateur []).

    Citation Envoyé par 0nn2belle Voir le message
    - Comment je peux afficher mon fruit au bout du temps de cette valeur aléatoire ?
    Là encore, un timer fera l'affaire.

    En général, dans un jeu, tu as (presque) systématiquement un moteur qui tourne, et qui donne une base temporelle au jeu (ex : un déclenchement à chaque milliseconde, ou toutes les 10 ms, etc.). A chaque itération, tu envoies un "top" à des threads et/ou des machines à états de façon à faire évoluer le jeu.
    De façon non exhaustive, ces actions peuvent être :
    • Gestion des affichages.
    • IA des ennemis.
    • Gestion du chrono du jeu.
    • Prise en compte des déplacements du joueur.
    • Affichage du score.
    • Gestion du scénario (les fruits, dans ton cas).
    • etc.


    Pour le "top", on utilise en général des sémaphores pour les threads, ou un appel direct pour les machines à états. Tu as plusieurs tutos / cours sur les jeux sur cette page.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    - Je tire un chiffre au hasard (entre 0 et 20)
    - Ce chiffre sera le nombre de secondes au bout duquel mon fruit apparaîtra
    Pour avoir des valeur entre 0 et 20 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       nbrefruit = rand()*20 ;
    Le truc c'est que je préfèrerai utiliser mon code en commentaire (la boucle for) afin que le jeu soit plus évolutif (par exemple je veux qu'il y ait 5 fruits par niveau au lieu de 2). Là où je suis bloquée c'est :
    Pourquoi ne pas utiliser une variable globale.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut
    Bonjour, merci pour vos solutions, mais vu que je devais passer sous du sdl, j'ai fait quelques modifications.
    Ceci dit, j'ai bien utiliser un sleep, voici ce que j'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    #include <stdlib.h> //En-tête nécessaire pour l'utilisation de exit() et atexit()
    #include <stdio.h>
    #include <iostream>
    #include <windows.h>
    #include <time.h>
    #include <SDL\SDL.h> //En-tête nécessaire pour l'utilisation de la sdl
     
    ////////////////////////////////////////////////////////////////////////////////////////
     
    SDL_Surface *screen = NULL; //SDL_Surface est utilisé pour une surface d'écran
    SDL_Surface *fruit = NULL;
    SDL_Surface *fruiti = NULL;
    SDL_Surface *background = NULL;
     
    //Les attributs de notre écran
    const int SCREEN_WIDTH = 600;
    const int SCREEN_HEIGHT = 521;
    const int SCREEN_BPP = 32;
     
     
    //Fonction de chargement d'image
    SDL_Surface *load_image(std::string filename)
        {
            SDL_Surface* loadedImage = NULL; //Surface tampon qui nous servira pour charger l'image
            SDL_Surface* optimizedImage = NULL;//L'image optimisée qu'on va utiliser
            loadedImage = SDL_LoadBMP(filename.c_str());//Charge l'image au format bitmap et la met dans la variable tampon
     
            if (loadedImage != NULL) //Si le chargement se passe bien
                {
                    optimizedImage = SDL_DisplayFormat( loadedImage ); //Création de l'image optimisée dans le même format que l'écran
                    SDL_FreeSurface(loadedImage); //Libération de l'ancienne surface
                }
     
            return optimizedImage; //On retourne l'image optimisée
        }
    ////////////////////////////////////////////////////////////////////////////
     
    //Fonction de blitting
    void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination)
        {
            SDL_Rect offset;//SDL_BlitSurface() accepte seulement les offsets dans un SDL_RECT
            offset.x = x;
            offset.y = y;
            SDL_BlitSurface(source, NULL, destination, &offset); //On blitte la surface
    }
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    int main (int argc, char* args[])
    {
     
    	if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) //Initialisation de tous les sous-systèmes de SDL
                                                    //Si SDL ne peut pas initialiser il retourne -1
            {
                return EXIT_FAILURE; //EXIT_FAILURE termine le programme si erreur
            }
     
        screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE ); //Mise en place de l'écran
                                                                  //SDL_SWSURFACE crée la surface écran dans la mémoire système
        if( screen == NULL ) //Si il y a une erreur dans la création de l'écran
            {
                return EXIT_FAILURE;
            }
     
        SDL_WM_SetCaption( "Hello World", NULL ); //Mise en place de la barre caption (légende sur le haut de la fenêtre)
     
        //Chargement des images
    	fruit = load_image("fruita.bmp"); //On utilise la fonction load_image
    	fruiti = load_image("fruitb.bmp");
    	background = load_image("background.bmp");
     
        apply_surface(0, 0, background, screen); //On applique le fond sur l'écran
     
     
        time_t time_depart; //On crée la variable e qui contient le temps de départ
        time(&time_depart); //On récupère le temps
     
        srand(time(NULL));//Amorçage de rand() //(rdtsc())
        int nbcase = 2;
        int nbrand[nbcase];
        int i; //Je déclare ma variable i
     
        for(i=0; i<nbcase; i++)//Pour i allant de 0 à 2 en croissant
            {
     
                nbrand[i] = ((rand()%10)+(i*20));//Je crée un tableau de taille i contenant les valeurs aléatoires
                std::cout << nbrand[i] << std::endl;
            }
     
        while(true)
        {
            time_t time_actuel; //On crée une 2ème variable qui contient du temps
            time(&time_actuel); //On récupère le temps de la boucle en cours
            int d = time_actuel - time_depart; //La différence entre le temps actuel et le temps de départ
            if (d == nbrand[0])
                {
                    apply_surface(0, 1, fruit, screen); //On applique le message sur l'écran
     
                }
     
            if (d == nbrand[1])
                {
                    apply_surface(100, 100, fruiti, screen);
                    //Pour effacer on utilise SDL_FillRect
     
                }
            if(d == 40) break;
            if(SDL_Flip(screen) == -1 )//Mise à jour de l'écran
                {
                    return EXIT_FAILURE;
                }
            Sleep(100);//Fais une pause dans la boucle (1000 millisecondes)
     
        }
     
     
     
        SDL_Delay (5000);//On attends 5s
     
        //Libération des surfaces
    	SDL_FreeSurface (fruit);
    	SDL_FreeSurface (fruiti);
    	SDL_FreeSurface (background);
     
    	//On quitte SDL
    	SDL_Quit();
    }
    Donc ça, ça fonctionne nickel.
    La seule chose c'est que je n'arrive pas à "déblitter" l'image au bout de 7 secondes, à part le timer comment je peux faire pour effacer la surface ?

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par 0nn2belle Voir le message
    La seule chose c'est que je n'arrive pas à "déblitter" l'image au bout de 7 secondes, à part le timer comment je peux faire pour effacer la surface ?
    Pour ça, je ne saurais trop te conseiller d'aller demander sur le forum SDL... Ici, c'est plutôt propre au C++ lui-même, et non pas à une librairie en particulier.

    Côté C++, à part justement un timer qui s'occupe d'effacer l'image, il n'y a pas de solutions "native". Il y en a peut-être au niveau de SDL, par contre, mais je ne connais pas cette librairie et je ne peux donc pas te répondre.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    Tu utilise alors un thread.

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par kmaniche Voir le message
    Tu utilise alors un thread.
    Ce qui n'est que l'une des nombreuses manières d'implémenter un timer...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

Discussions similaires

  1. Recherche aléatoire dans un tableau
    Par Ykroxor dans le forum Excel
    Réponses: 1
    Dernier message: 11/04/2007, 09h58
  2. Réponses: 3
    Dernier message: 01/03/2007, 16h26
  3. [Tableaux] Valeur unique dans un tableau
    Par glsn dans le forum Langage
    Réponses: 6
    Dernier message: 06/12/2006, 11h18
  4. recherche de valeur identique dans un tableau
    Par jean tof dans le forum Langage
    Réponses: 9
    Dernier message: 20/06/2006, 13h33
  5. 2 valeurs distincts dans un tableau à 2 dimensions...
    Par toyyo dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 23/08/2005, 16h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo