如何生产不产生超过X个连续元素的更多的随机数序列 [英] How to produce a random number sequence that doesn't produce more than X consecutive elements
问题描述
好吧,我真的不知道如何正确地框定问题,因为我几乎没有有任何想法如何来形容我想用一句话,我表示歉意。
Ok, I really don't know how to frame the question properly because I barely have any idea how to describe what I want in one sentence and I apologize.
让我直接切入正题,你可以跳过剩下的事业,我只是想表明,我已经尝试过的东西,而不是到这里来问一个问题就改。
Let me get straight to the point and you can just skip the rest cause I just want to show that I've tried something and not coming here to ask a question on a whim.
我需要产生6随机数的算法地方不得以任何顺序连续生产超过2个号码。
I need an algorithm that produces 6 random numbers where it may not produce more than 2 consecutive numbers in that sequence.
例如:3 3 4 4 2 1
example: 3 3 4 4 2 1
^罚款。
例如:3 3 3 4 4 2
example: 3 3 3 4 4 2
^ NO! NO!的错误!
^NO! NO! WRONG!
显然,我不知道如何做到这一点没有绊倒自己不断。
Obviously, I have no idea how to do this without tripping over myself constantly.
有一个STL或升压功能,可以做到这一点?或者,也许这里有人知道如何捏造的算法吧。这将是真棒。
Is there a STL or Boost feature that can do this? Or maybe someone here knows how to concoct an algorithm for it. That would be awesome.
我想要做什么,我已经试过。(你可以跳过部分)
这是在C ++中。我试图做一个小组去PON /俄罗斯方块攻击/益智联盟任何克隆的做法。游戏中有6块行和3个或更多的匹配块将摧毁块。 下面是情况下,视频你不熟悉。
This is in C++. I'm trying to make a Panel de Pon/Tetris Attack/Puzzle League whatever clone for practice. The game has a 6 block row and 3 or more matching blocks will destroy the blocks. Here's a video in case you're not familiar.
在一个新行来自底部它不能与3水平比较块出来,否则它会自动消失。这是我不希望的水平。纵是罚款,但。
When a new row comes from the bottom it must not come out with 3 horizontal matching blocks or else it will automatically disappear. Something I do not want for horizontal. Vertical is fine though.
我试图做到这一点,看来我无法得到它的权利。当我开始块的大块游戏缺少,因为它检测到匹配时,它不应该。我的方法是更可能重手,太令人费解,你会看到的。
I've tried to accomplish just that and it appears I can't get it right. When I start the game chunks of blocks are missing because it detects a match when it shouldn't. My method is more than likely heavy handed and too convoluted as you'll see.
enum BlockType {EMPTY, STAR, UP_TRIANGLE, DOWN_TRIANGLE, CIRCLE, HEART, DIAMOND};
vector<Block> BlockField::ConstructRow()
{
vector<Block> row;
int type = (rand() % 6)+1;
for (int i=0;i<6;i++)
{
row.push_back(Block(type));
type = (rand() % 6) +1;
}
// must be in order from last to first of the enumeration
RowCheck(row, diamond_match);
RowCheck(row, heart_match);
RowCheck(row, circle_match);
RowCheck(row, downtriangle_match);
RowCheck(row, uptriangle_match);
RowCheck(row, star_match);
return row;
}
void BlockField::RowCheck(vector<Block> &row, Block blockCheckArray[3])
{
vector<Block>::iterator block1 = row.begin();
vector<Block>::iterator block2 = row.begin()+1;
vector<Block>::iterator block3 = row.begin()+2;
vector<Block>::iterator block4 = row.begin()+3;
vector<Block>::iterator block5 = row.begin()+4;
vector<Block>::iterator block6 = row.begin()+5;
int bt1 = (*block1).BlockType();
int bt2 = (*block2).BlockType();
int bt3 = (*block3).BlockType();
int bt4 = (*block4).BlockType();
int type = 0;
if (equal(block1, block4, blockCheckArray))
{
type = bt1 - 1;
if (type <= 0) type = 6;
(*block1).AssignBlockType(type);
}
else if (equal(block2, block5, blockCheckArray))
{
type = bt2 - 1;
if (type <= 0) type = 6;
(*block2).AssignBlockType(type);
}
else if (equal(block3, block6, blockCheckArray))
{
type = bt3 - 1;
if (type == bt3) type--;
if (type <= 0) type = 6;
(*block3).AssignBlockType(type);
}
else if (equal(block4, row.end(), blockCheckArray))
{
type = bt4 - 1;
if (type == bt3) type--;
if (type <= 0) type = 6;
(*block4).AssignBlockType(type);
}
}
的叹息的,我不知道这是否有助于显示这个......至少它表明我试过的东西。
Sigh, I'm not sure if it helps to show this...At least it shows that I've tried something.
基本上,我通过分配随机块类型,由BlockType枚举所述,一座座对象的构造函数构造的行(一座座对象有blockType和位置)。
Basically, I construct the row by assigning random block types, described by the BlockType enum, to a Block object's constructor(a Block object has blockType and a position).
然后我用一个RowCheck功能,看看是否有一行是连续3 blockTypes,我对所有块类型做到这一点。在* _match变量是用相同的块类型3座对象的数组。如果我发现有3个连续的块类型的话,我只是单纯的一个减去第一个值。但是,如果我这样做,我可能最终会在不经意间产生另外3个比赛,所以我只是确保块类型,以便将会从最大到最小。
Then I use a RowCheck function to see if there's 3 consecutive blockTypes in one row and I have do this for all block types. The *_match variables are arrays of 3 Block objects with the same block type. If I do find that there are 3 consecutive block types then, I just simply subtract the first value by one. However if I do that I might end up inadvertently producing another 3 match so I just make sure the block types are going in order from greatest to least.
好吧,这是糟糕的,这是令人费解的,它不工作!这就是为什么我需要你的帮助。
Ok, it's crappy, it's convoluted and it doesn't work! That's why I need your help.
推荐答案
这应该足以保持previous两个值的记录,循环当新生成的一个同时匹配previous值。
It should suffice to keep record of the previous two values, and loop when the newly generated one matches both of the previous values.
有关任意游程,这将是有意义的大小对飞历史缓冲区,并做比较,在一个循环中也是如此。但这应该是接近匹配您的要求。
For an arbitrary run length, it would make sense to size a history buffer on the fly and do the comparisons in a loop as well. But this should be close to matching your requirements.
int type, type_old, type_older;
type_older = (rand() % 6)+1;
row.push_back(Block(type_older));
type_old = (rand() % 6)+1;
row.push_back(Block(type_old));
for (int i=2; i<6; i++)
{
type = (rand() % 6) +1;
while ((type == type_old) && (type == type_older)) {
type = (rand() % 6) +1;
}
row.push_back(Block(type));
type_older = type_old;
type_old = type;
}
这篇关于如何生产不产生超过X个连续元素的更多的随机数序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!