如何在像糖果粉碎这样的游戏中为瓷砖分配颜色

时间:2016-03-25 11:16:05

标签: c++ c opengl stl

我参与了C / C ++中的部分游戏,其中瓷砖交换Here。 我想现在实施糖果粉碎,我知道画糖果需要花费很多精力。只需让瓷砖完成工作。 在为瓷砖分配颜色的部分中,我不希望三种颜色出现在行或列中。我如何以有效的方式做到这一点。 我目前正在随机分配颜色:

board[i][j].color=rand()%3;

看起来像这样: Snapshot of program

是的我不希望一行或一列中的三个单元格或图块具有相同的颜色,即不超过两个相同颜色的相邻图块。  我的意思是我不想要一个颜色被分配一次的解决方案,并检查一行中的三个瓷砖是否具有相同的颜色。如果不再为所有图块生成颜色。这太天真和昂贵。 另一种解决方案可以是在以光栅顺序检查向色块分配颜色之前检查以查看下方或左侧的两个区块是否具有相同的颜色(如果是这样的话,分配一些其他颜色)。这也很明显。还有更好的方法吗?

在Weather Wane的回答之后,我发布了使用STL迭代器和set_difference方法进行设置差异操作的代码。我正在尝试的是在通过使用设置操作仅消除已经重复两次(下方或左侧)的那些颜色来随机选择我正在形成该组的一组颜色之前。代码中有问题。我对STL知之甚少。任何人都可以指导我如何正确使用它。

for(j=0;j<maxy;j++)
{for(i=0;i<maxx;i++)
{
    int first[] = {0,1,2,3},fsize,i34;
    std::vector<int> v(5);                     
    std::vector<int>::iterator it;

    board[i][j].x0=x0+i*dx+1;
    board[i][j].x1=x0+(i+1)*dx-1;
    board[i][j].y0=y0+j*dy+1;
    board[i][j].y1=y0+(j+1)*dy-1;


    if((i-1)>=0&&board[i-1][j].color==0&&(i-2)>=0&&board[i-2][j].color==0)
    {int second[] = {0};
    std::sort (first,first+4);     
    it=std::set_difference (first, first+4, second, second+1, v.begin());
    v.resize(it-v.begin());                      
    std::copy(v.begin(), v.end(), first);
    }
    fsize=v.size();
    if((i-1)>=0&&board[i-1][j].color==1&&(i-2)>=0&&board[i-2][j].color==1)
    {int second[] = {1};
    std::sort (first,first+fsize);     //  5 10 15 20 25
    it=std::set_difference (first, first+fsize, second, second+1, v.begin());
                                            //  5 15 25  0  0  0  0  0  0  0
    v.resize(it-v.begin());                      //  5 15 25
    std::copy(v.begin(), v.end(), first);
    }
    fsize=v.size();
    if((i-1)>=0&&board[i-1][j].color==2&&(i-2)>=0&&board[i-2][j].color==2)
    {int second[] = {2};
    std::sort (first,first+fsize);     //  5 10 15 20 25
    it=std::set_difference (first, first+fsize, second, second+1, v.begin());
                                       //  5 15 25  0  0  0  0  0  0  0
    v.resize(it-v.begin());                      //  5 15 25
    std::copy(v.begin(), v.end(), first);
    }
    fsize=v.size();
    if((j-1)>=0&&board[i][j-1].color==0&&(j-2)>=0&&board[i][j-2].color==0)
    {int second[] = {0};
    std::sort (first,first+fsize);     //  5 10 15 20 25
    it=std::set_difference (first, first+fsize, second, second+1, v.begin());
                                       //  5 15 25  0  0  0  0  0  0  0
    v.resize(it-v.begin());                      //  5 15 25
    std::copy(v.begin(), v.end(), first);
    }
    fsize=v.size();
    if((j-1)>=0&&board[i][j-1].color==1&&(j-2)>=0&&board[i][j-2].color==1)
    {int second[] = {1};
    std::sort (first,first+fsize);     //  5 10 15 20 25
    it=std::set_difference (first, first+fsize, second, second+1, v.begin());
                              //  5 15 25  0  0  0  0  0  0  0
    v.resize(it-v.begin());                      //  5 15 25
    std::copy(v.begin(), v.end(), first);
    }
    fsize=v.size();
    if((j-1)>=0&&board[i][j-1].color==2&&(j-2)>=0&&board[i][j-2].color==2)
    {int second[] = {2};
    std::sort (first,first+fsize);     //  5 10 15 20 25
                                    // 10 20 30 40 50
    it=std::set_difference (first, first+fsize, second, second+1, v.begin());
                                  //  5 15 25  0  0  0  0  0  0  0
    v.resize(it-v.begin());                      //  5 15 25
    std::copy(v.begin(), v.end(), first);
    }
    //  first=&v[0];
    fsize=v.size();
    cout<<v.size()<<" ";
    for(i34=0,it=v.begin();it!=v.end();it++)
    {cout<<*it<<" "; first[i34++]=*it;}
    cout<<" ";
    if(v.size()>0&&v.size()!=5)
    board[i][j].color=first[rand()%i34];
    else if (v.size()==5) board[i][j].color=first[rand()%4];
    }
    cout<<"\n";
}

3 个答案:

答案 0 :(得分:0)

不是重复选择颜色然后按照规则检查颜色,而是先应用规则并制作一系列可用颜色。然后随机选择数组索引。如果没有可用的颜色:倒带,从上一个列表中删除以前选择的颜色。

假设您有3种颜色。而不是重复使用

board[i][j].color = rand() % 3;

直到颜色符合规则,您可以构建符合规则的颜色数组,例如

int avail_color[3];
int num_avail;

然后你选择这样的颜色

board[i][j].color = avail_color[ rand() % num_avail ];

Fisher-Yates shuffle类似。

答案 1 :(得分:0)

无论如何,你必须实现一个函数来计算一个图块是否在一个&#34; 3相同颜色的图块组中#34;。

实现它并在颜色分配功能中使用它。

Whish:

  

每个瓷砖   选择一种随机颜色,直到它没有制作一个&#34; 3相同颜色的瓷砖组&#34;。

答案 2 :(得分:0)

我想要的是实现减号设置操作,其中我排除这些颜色争用随机选择,这些颜色在左侧或下方重复两次。

for(i=0;i<maxx;i++)
        for(j=0;j<maxy;j++)
        {exzero=exone=extwo=exthree=0;
            board[i][j].x0=x0+i*dx+1;
            board[i][j].x1=x0+(i+1)*dx-1;
            board[i][j].y0=y0+j*dy+1;
            board[i][j].y1=y0+(j+1)*dy-1;
            if((i-1)>=0&&board[i-1][j].color==0&&(i-2)>=0&&board[i-2][j].color==0)
                exzero=1;
            if((i-1)>=0&&board[i-1][j].color==1&&(i-2)>=0&&board[i-2][j].color==1)
                exone=1;
            if((i-1)>=0&&board[i-1][j].color==2&&(i-2)>=0&&board[i-2][j].color==2)
                extwo=1;
            if((i-1)>=0&&board[i-1][j].color==3&&(i-2)>=0&&board[i-2][j].color==3)
                            exthree=1;
            if((j-1)>=0&&board[i][j-1].color==0&&(j-2)>=0&&board[i][j-2].color==0)
                exzero=1;
            if((j-1)>=0&&board[i][j-1].color==1&&(j-2)>=0&&board[i][j-2].color==1)
                exone=1;
            if((j-1)>=0&&board[i][j-1].color==2&&(j-2)>=0&&board[i][j-2].color==2)
                extwo=1;
            if((j-1)>=0&&board[i][j-1].color==3&&(j-2)>=0&&board[i][j-2].color==3)
                            exthree=1;
            compositebin=exzero|exone<<1|extwo<<2|exthree<<3;
        //  cout<<compositebin<<" ";
            switch(compositebin)
            {
            case 0:board[i][j].color=rand()%4;break;
            case 1:board[i][j].color=rand()%2?1:2;break;
            case 2:board[i][j].color=rand()%2?0:2;break;
            case 3:board[i][j].color=2;break;
            case 4:board[i][j].color=rand()%2?1:0;break;
            case 5:board[i][j].color=1;break;
            case 6:board[i][j].color=0;break;
            case 7:break;
            case 8:board[i][j].color=rand()%2?rand()%2?0:1:2;break;
            case 9:board[i][j].color=rand()%2?1:2;break;
            case 10:board[i][j].color=rand()%2?0:2;break;
            case 11:board[i][j].color=2;break;
            case 12:board[i][j].color=rand()%2?1:0;break;
            case 13:board[i][j].color=1;break;
            case 14:board[i][j].color=0;break;
            case 15:break;
            }

        }

这段代码使用标志排除零,排除一个,排除两个并排除三个排除四种颜色做一个整洁的工作。我形成一个复合二进制数,并根据其值切换,从{0,1,2,3}的子集中随机选择。