LINUX.ORG.RU

Зарандомить вектором?

 


0

1

Есть такой вот вектор,нужно зарандомить что-то вроде такого vectordrum[random]; где random from [0,vectordrum.size()]; чтобы не выходило за значения вектора.

vector<string>vectordrum;
vectordrum.push_back("str1");
vectordrum.push_back("str2");
vectordrum.push_back("str3");
vectordrum.push_back("str4");
int min=0,max=vectordrum.size(),random;

srand(time(0));
for(int__ i=0;i<countdrums;i++)
    {
        glPushMatrix();
        glRotatef(rotate[i],1,0,0);
        for(int__ j=0;j<counttextureondrums;j++)
        {
			random = ((int__)((float__)rand() / RAND_MAX*(max_ - min_) + min_));
			glBindTexture(GL_TEXTURE_2D,/*GetTexture(drum[i][j]-4)*/image->IndexTexture[FindTexture(vectordrum[random]/*"auto4"*/)]);
            EnableTexture(i,j);
        }
        glPopMatrix();
    }

Еще куда поместить вызов srand(time(0)); чтобы при вызове функции rand() в цикле получались разные числа, потому что у меня одинаковые

где random from [0,vectordrum.size()]
random = ((int__)((float__)rand() / RAND_MAX*(max_ - min_) + min_));

std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(0, INT_MAX);
…
for(…)
  {
	…
	int random = distribution(generator) % vectordrum.size();
  }
XMs ★★★★★ ()
Ответ на: комментарий от XMs

как мне определить вот смотри

/*Scene1.h*/
/*ref*/ class Scene1
{
	std::default_random_engine generator;
	 std::uniform_int_distribution<int>distribution;//(0, INT_MAX);
};
/*Scene1.cpp*/
Scene1::Scene1(void)
{
	distribution(0, INT_MAX);//тут ошибка
}
void__ Scene1::ShowDrum(int__ countdrums,float__*rotate_,int__ counttextureondrums,int__**drum,int__ credits,int__ win,int__ totalbet,const char__*line,int__ bet,bool__*lines,int__**ms,bool__*buttons)
{
	//glEnable(GL_ALPHA_TEST);
	//glEnable(GL_BLEND);
	//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_SRC_ALPHA,GL_ONE);
	//glAlphaFunc(GL_GREATER, 0.0f); 
	/*
	int__ numb = FindTexture("wild");
	glBindTexture(GL_TEXTURE_2D, image->IndexTexture[numb]);
	EnableTexture(image->TextureCoordinats[numb], image->VertexCoordinats[numb]);
	*/
	//glPushMatrix();
    //glRotatef(180,0,0,1);
	if(buttons[2])
		StartRotate();
	Rotate(/*startrotate*/);
	for(int__ i=0;i<countdrums;i++)
    {
        glPushMatrix();
        glRotatef(rotate[i],1,0,0);
        for(int__ j=0;j<counttextureondrums;j++)
        {
			random = distribution(generator) % vectordrum.size();// ((int__)((float__)rand() / RAND_MAX*(max_ - min_) + min_));
			glBindTexture(GL_TEXTURE_2D,/*GetTexture(drum[i][j]-4)*/image->IndexTexture[FindTexture(vectordrum[random]/*"auto4"*/)]);
            EnableTexture(i,j);
        }
        glPopMatrix();
    }
    //glPopMatrix();

	//glDisable(GL_BLEND);
	//glDisable(GL_ALPHA_TEST);
}

Gremlin_ ()
Ответ на: комментарий от Gremlin_

Перестать извращаться и перенести объявление и определение генератора и распределения в функцию ShowDrum(), где они используются, уменьшив область видимости. Я намеренно промолчу о сигнатуре этой функции, поскольку к вопросу это не относится, но это лютый говнокод, не делай список аргументов длиной в километр

XMs ★★★★★ ()
Ответ на: комментарий от XMs

Перенес , проблема в том ,что рандом отображает одну картинку. Когда в классе то разные, но пачкой то есть в цикле формируется 30 одинаковых картинок при перерисовке они пачкой меняются на следующую пачку, а мне надо чтобы в пачке они были разные

Gremlin_ ()
Ответ на: комментарий от thunar

Спроси любой tidy|check. Начиная от не инициализированной переменной заканчивая не читаемым кодиком. Экономить строчки можно было в 80-ых, как и кислоту прямо на работе жрать в принципе.

onhydro ()
Ответ на: комментарий от Gremlin_

Вот так всё работает:

xms@XMs-desktop ~/projects/tests/random-test $ cat random.cpp
#include <iostream>
#include <random>
#include <vector>

#include <cstdlib>



using namespace std;

int get_random(int max)
  {
        static default_random_engine gen;
        static uniform_int_distribution<int> dist;

        return dist(gen) % max;
  }

int main()
  {
        vector<int> v = {1};
        const size_t count = 100;

        for (size_t i = 0; i < count; i++)
                v.push_back(get_random(v.size()));

        for (int i: v)
                cout << i << ' ';
        cout << endl;

        return EXIT_SUCCESS;
  }
xms@XMs-desktop ~/projects/tests/random-test $ g++ -Wall -Wextra -Werror -pedantic random.cpp 
xms@XMs-desktop ~/projects/tests/random-test $ ./a.out 
1 0 1 1 2 1 0 1 6 0 1 7 3 2 13 2 12 3 16 14 16 2 1 15 6 6 13 8 25 18 20 30 22 9 29 23 10 12 25 1 13 36 35 32 33 8 12 23 31 1 46 43 3 48 14 44 48 56 5 50 8 4 57 45 56 10 5 42 40 25 44 27 1 19 58 65 54 61 15 36 72 9 73 18 50 70 4 79 26 18 62 84 19 26 78 44 19 44 1 63 70 
xms@XMs-desktop ~/projects/tests/random-test $ 

XMs ★★★★★ ()
Ответ на: комментарий от Gremlin_

Ну на вскидку - те же пираты силиконовой долины, хотя, там нормально только джобс угарал вроде, да и не 80ые. Но это лайтово, остальное надо гуглить, что бы вспомнить, а мне лень. Хотя, даже на нашем веку есть всякие whoami.

onhydro ()
Ответ на: комментарий от Gremlin_

Положил. И?

xms@XMs-desktop ~/projects/tests/random-test $ cat random.cpp
#include <iostream>
#include <chrono>
#include <random>
#include <vector>

#include <cstdlib>



using namespace std::chrono;
using namespace std;

int get_random(int max)
  {
        static unsigned seed = system_clock::now().time_since_epoch().count();
        static default_random_engine gen(seed);
        static uniform_int_distribution<int> dist;

        return dist(gen) % max;
  }

int main()
  {
        vector<int> v = {1};
        const size_t count = 10;

        for (size_t i = 0; i < count; i++)
                for (size_t j = 0; j < count; j++)
                        v.push_back(get_random(v.size()));

        for (int i: v)
                cout << i << ' ';
        cout << endl;

        return EXIT_SUCCESS;
  }
xms@XMs-desktop ~/projects/tests/random-test $ g++ -Wall -Wextra -Werror -pedantic random.cpp 
xms@XMs-desktop ~/projects/tests/random-test $ ./a.out 
1 0 1 1 1 3 5 4 2 8 5 0 3 3 0 0 0 15 8 2 4 18 6 11 22 5 20 9 0 24 9 16 27 20 23 34 2 5 29 10 25 5 29 24 20 4 15 22 22 46 46 15 2 49 1 26 49 33 50 7 36 20 24 51 6 30 59 49 66 52 61 23 32 39 48 40 17 5 49 70 41 1 4 73 23 75 42 28 37 51 34 68 72 89 8 44 10 50 34 87 99 
xms@XMs-desktop ~/projects/tests/random-test $ 

XMs ★★★★★ ()
Ответ на: комментарий от XMs
void__ Scene1::ShowDrum(int__ countdrums,float__*rotate_,int__ counttextureondrums,int__**drum,
	int__ credits,int__ win,int__ totalbet,const char__*line,int__ bet,bool__*lines,int__**ms,bool__*buttons)
{
	//glEnable(GL_ALPHA_TEST);
	//glEnable(GL_BLEND);
	//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_SRC_ALPHA,GL_ONE);
	//glAlphaFunc(GL_GREATER, 0.0f); 
	/*
	int__ numb = FindTexture("wild");
	glBindTexture(GL_TEXTURE_2D, image->IndexTexture[numb]);
	EnableTexture(image->TextureCoordinats[numb], image->VertexCoordinats[numb]);
	*/
	//glPushMatrix();
    //glRotatef(180,0,0,1);
	if(buttons[2])
		StartRotate();
	Rotate(/*startrotate*/);
	/*
	std::default_random_engine generator;
	 std::uniform_int_distribution<int>distribution(0, INT_MAX);
	*/
	max_ = vectordrum.size()-1, min_ = 0;
	for(int__ i=0;i<countdrums;i++)
    {
        glPushMatrix();
        glRotatef(rotate[i],1,0,0);
		for(int__ j=0;j<counttextureondrums;j++)
        {
			random = GetRandom(max_);
			glBindTexture(GL_TEXTURE_2D,/*GetTexture(drum[i][j]-4)*/image->IndexTexture[FindTexture(vectordrum[random]/*"auto4"*/)]);
            EnableTexture(i,j);
        }
        glPopMatrix();
    }
    //glPopMatrix();

	//glDisable(GL_BLEND);
	//glDisable(GL_ALPHA_TEST);
}
using namespace std;
int__ Scene1::GetRandom(int max)
{
	//return ((int__)((float__)rand() / RAND_MAX*(max_ - min_) + min_));
	static default_random_engine gen;
    static uniform_int_distribution<int> dist;
    return dist(gen) % max;
}
Gremlin_ ()
Ответ на: комментарий от Gremlin_

Ужасная каша. Для начала проверь, какие числа возвращает GetRandom(). И сразу вопрос на засыпку: почему распределение имеет шаблонный тип int, а функция возвращает какой-то int__? Лично я не могу утверждать, что это одно и то же и что ты не теряешь данные при преобразовании

XMs ★★★★★ ()
Ответ на: комментарий от XMs
typedef GLint int__;

эм тут такое дело, просто я тут использовал код который у меня разные числа генерировал и он вызывается лишь раз , а у меня около 60 фпс рендерит, то есть тут дело не в генераторе и типах, а в чем то другом

Gremlin_ ()
Ответ на: комментарий от Gremlin_

typedef GLint int__;

Отлично, а что такое GLint?


а у меня около 60 фпс рендерит, то есть тут дело не в генераторе и типах, а в чем то другом

Ну так добавь что-то типа std::cout << "Debug: random number is " << random << ", max is " << max_ << std::endl, хоть будешь уверен, что числа правильные приходят

XMs ★★★★★ ()
Ответ на: комментарий от Gremlin_

рисование отделено от логики

Меня терзают смутные сомнения в верности этого утверждения, учитывая, что только в этой функции рисования так и напрашивается декомпозиция и вынос целых блоков куда-то вовне.


аргументов могло быть и больше

Да понятно, что могло. Только плохо это

XMs ★★★★★ ()
Ответ на: комментарий от XMs

Вот исходная программа

void__ Scene::Show(int__ countdrums,float__*rotate_,int__ counttextureondrums,int__**drum,int__ credits,int__ win,int__ totalbet,const char__*line,int__ bet,bool__*lines,int__**ms,bool__*buttons)
{
    glPushMatrix();
    glRotatef(180,0,0,1);
    for(int__ i=0;i<countdrums;i++)
    {
        glPushMatrix();
        glRotatef(rotate_[i],1,0,0);
        for(int__ j=0;j<counttextureondrums;j++)
        {
            glBindTexture(GL_TEXTURE_2D,GetTexture(drum[i][j]-4));
            EnableTexture(i,j);
        }
        glPopMatrix();
    }
    glPopMatrix();
    ShowBoth();
    ShowButtons(buttons);
    ShowReservedWords(credits,win,totalbet,line,bet);
    ShowLine(bet,lines,ms);
}

Gremlin_ ()
Ответ на: комментарий от Gremlin_

Гораздо лучше. Отсюда выносишь рисование драмов в отдельную функцию:

void__ Scene::ShowDrums(int__ countdrums, float__*rotate_, int__ counttextureondrums, int__**drum)
{
    glPushMatrix();
    glRotatef(180,0,0,1);
    for(int__ i=0;i<countdrums;i++)
    {
        glPushMatrix();
        glRotatef(rotate_[i],1,0,0);
        for(int__ j=0;j<counttextureondrums;j++)
        {
            glBindTexture(GL_TEXTURE_2D,GetTexture(drum[i][j]-4));
            EnableTexture(i,j);
        }
        glPopMatrix();
    }
    glPopMatrix();
}

void__ Scene::Show(int__ countdrums,float__*rotate_,int__ counttextureondrums,int__**drum,int__ credits,int__ win,int__ totalbet,const char__*line,int__ bet,bool__*lines,int__**ms,bool__*buttons)
{
    ShowDrums(countdrums, rotate_, counttextureondrums, drum);
    ShowBoth();
    ShowButtons(buttons);
    ShowReservedWords(credits,win,totalbet,line,bet);
    ShowLine(bet,lines,ms);
}


Потом выносишь рисование отдельного драма в функцию:

void__ Scene::ShowSingleDrum(float__ rotate, int__ counttextureondrums, int__ *drum, const int__ row)
{
    glPushMatrix();
    glRotatef(rotate, 1, 0, 0);
    for(int__ i = 0; i < counttextureondrums; i++)
    {
        glBindTexture(GL_TEXTURE_2D, GetTexture(drum[i] - 4));
        EnableTexture(row, i);
    }
    glPopMatrix();
}

void__ Scene::ShowDrums(int__ countdrums, float__*rotate_, int__ counttextureondrums, int__**drum)
{
    glPushMatrix();
    glRotatef(180, 0, 0, 1);
    for(int__ i = 0; i < countdrums; i++)
        ShowSingleDrum(rotate[i], counttextureondrums, drum[i], i);
    glPopMatrix();
}

void__ Scene::Show(
    int__ countdrums,
    float__*rotate_,
    int__ counttextureondrums,
    int__**drum,
    int__ credits,
    int__ win,
    int__ totalbet,
    const char__*line,
    int__ bet,
    bool__*lines,
    int__**ms,
    bool__*buttons)
{
    ShowDrums(countdrums, rotate_, counttextureondrums, drum);
    ShowBoth();
    ShowButtons(buttons);
    ShowReservedWords(credits, win, totalbet, line, bet);
    ShowLine(bet, lines, ms);
}


Затем начинаешь приводить в порядок типы и имена переменных:

void__ Scene::ShowSingleDrum(
    float__ angle,
    int__ drumsTextureCount,
    int__ drums[RSIZE],
    const int__ row)
{
    glPushMatrix();
    glRotatef(angle, 1, 0, 0);
    for (int__ i = 0; i < drumsTextureCount; i++)
    {
        glBindTexture(GL_TEXTURE_2D, GetTexture(drums[i] - 4));
        EnableTexture(row, i);
    }
    glPopMatrix();
}

void__ Scene::ShowDrums(
    int__ drumCount,
    float__ rotation[ROTSIZE],
    int__ drumsTextureCount,
    int__ drums[CSIZE][RSIZE])
{
    glPushMatrix();
    glRotatef(180, 0, 0, 1);
    for (int__ i = 0; i < drumCount; i++)
        ShowSingleDrum(rotation[i], drumsTextureCount, drums[i], i);
    glPopMatrix();
}

void__ Scene::Show(
    int__ drumCount,
    float__ rotation[ROTSIZE],
    int__ drumsTextureCount,
    int__ drums[CSIZE][RSIZE],
    int__ credits,
    int__ win,
    int__ totalbet,
    const char__ *line,
    int__ bet,
    bool__ *lines,
    int__ **ms,
    bool__ *buttons)
{
    ShowDrums(drumCount, rotation, drumsTextureCount, drums);
    ShowBoth();
    ShowButtons(buttons);
    ShowReservedWords(credits, win, totalbet, line, bet);
    ShowLine(bet, lines, ms);
}

Ну а теперь уже можно убирать магические числа, группировать аргументы: вынести описание текстур в отдельный класс, завести структуру/класс с описанием барабана и перенести туда всю кухню, связанную с его состоянием, ну и прочее по мелочи. Этим предлагаю заняться самостоятельно. В идеале у тебя функция ShowDrums() должна принимать один аргумент — список объектов «барабан», либо, если это член класса, вообще ничего

XMs ★★★★★ ()
Последнее исправление: XMs (всего исправлений: 1)
Ответ на: комментарий от Gremlin_

Выполни декомпозицию, как я привёл выше, сразу станет понятно, где ошибка. Заодно проверь, правильно ли работает функция FindTexture(vectordrum[random]), да и вообще сохрани её результат в локальной переменной, хоть строчку сократишь

XMs ★★★★★ ()
Ответ на: комментарий от XMs

там какая-то трабла с BindTexture я даже реализовал strcmp сам на всякий случай но все равно не помогло

int__ Scene1::FindTexture(std::string name)
{
	int__ result = -1;
	for(int__ i=0;i<CountTexture;i++)
	{
		if(strcmp(image->Name[i].c_str(),name.c_str())==0)
		/*
		int__ bb=0;
		for(int__ j=0;j<name.length() && j<image->Name[i].length();j++)
		{
			if(name[j] == image->Name[i][j])
				bb++;	
		}
		if(name.length() == image->Name[i].length() && bb == name.length())
		*/
				result = image->number[i];
	}
	return result;
}

Gremlin_ ()
Ответ на: комментарий от Gremlin_

Да ты издеваешься:

int__ Scene1::FindTexture(std::string name)
{
	for (int__ i = 0; i < CountTexture; i++)
	{
		if (image->Name[i] == name)
			return image->number[i];
	}
	return -1;
}

При такой функции сразу становится понятно, что она делает. И сразу возникают вопросы:

  • У картинки (image — единственное число) может быть несколько имён?
  • Name (почему с заглавной буквы?) и number — массивы одного размера?
  • Если да, то зачем их так разделять?
  • Если нет, то как они связаны, почему у них данные, связанные с одним объектом, лежат на тех же индексах?
  • CountTexture — размер этих массивов?
  • Если да, то зачем его отделять от них?
  • Вообще, почему бы не сделать отдельное хранилище на стандартных контейнерах вместо небезопасных сишных массивов? Казалось бы, что может быть проще:
    struct TextureDescription
    {
    	std::string name;
    	int__ index;
    
    	bool operator==(const std::string &oname)
    		{ return name == oname; }
    }
    
    std::vector<TextureDescription> textureDescs;
    
    int__ Scene1::FindTexture(std::string name)
    {
    	using namespace std;
    	auto it = find(begin(textureDescs), end(textureDescs), name)
    	return it == end(textureDescs)? -1: it->index;
    }
    
XMs ★★★★★ ()
Последнее исправление: XMs (всего исправлений: 3)