确保相邻节点不共享相同的值

Posted

技术标签:

【中文标题】确保相邻节点不共享相同的值【英文标题】:Ensure neighbor nodes do not share same value 【发布时间】:2015-03-09 16:11:24 【问题描述】:

我正在创建一个游戏 - 一个颜色网格,玩家可以向上、向下、向左或向右导航。如果方向说“去红场”,玩家必须这样做。玩家必须遵循的路径由遵循以下规则的随机路径生成算法确定:

游戏规则:

这是一款帮助人们练习外语的迷宫游戏 给玩家一个颜色网格,他们沿着随机生成的从左到右的路径跟随下一个给定的颜色(如果随机生成的路径上的下一个颜色是红色,他们将被提示去红色方块) - 显然稍后提示将是外语 例如,“Rojo”出现,他们必须去一个红色方块 这将取决于时间...如果您在同一个图块上停留的时间过长,您会受到伤害 如果你踩错颜色,你会受到伤害 由于迷宫是从左到右生成的(参见下面的算法信息),它们可以选择移动到北、东或南节点

逻辑规则:

从左到右,表示在第 0 列选择随机行 路径必须从第 0 列连接到最后一列 路径有风,但无法返回,这意味着它可以向上、向下和向右循环 彼此相邻的节点不能共享相同的颜色 当前节点北、东、南的节点(例如灰色节点)不能共享相同的颜色 在生成随机路径时会预先生成颜色提示(要前往的下一个单元格)...在创建网格时将每种颜色分配给一个单元格...并且随机生成的路径存储顺序/路径这些颜色都亮了……所以我可以将下一个颜色传递给玩家让他们踩上去。

路径生成算法信息:Random path generation algorithm

我正在生成一个随机颜色的网格。当然,这意味着它不能完全随机,因为我需要确保玩家不能有超过一种与邻居相同的颜色可供选择。

这张图片描述了它:灰色的单元格是玩家的起始位置...北、东和南的邻居都共享相同的颜色...这很糟糕。

游戏中

网格是彩色平铺图像的网格。因此,在生成网格后不应更改图块“颜色”。在网格创建过程中,每个新单元格,我都会创建一个随机索引,并将单元格颜色设置为等于 colorsObject[randomIndex] 以确保分配随机颜色

为了尝试解决这个问题,我尝试存储上次使用的颜色...在下一次创建单元格时,我从颜色对象中删除存储的上次使用的颜色(出于我自己的原因需要一个对象,否则将使用数组),设置随机以从缩短的颜色列表中进行选择,并使用该颜色。然后将 lastUsedColor 添加回对象:

    var lastUsedColor = "";
    for (var row = 0; row <= bridgeSegment.settings.rows-1; row++) 
        this.grid[row] = []; 
        for (var col = 0; col <= bridgeSegment.settings.cols-1; col++)                 
            if (lastUsedColor != "") delete this.colors[lastUsedColor];

            var colorIndex = Math.floor(Math.random() * (Object.keys(this.colors).length - 0) + 0);

            var keyName = Object.keys(this.colors)[colorIndex]; 

            image = (this.maze == 1) ? image : keyName;

            if (lastUsedColor != "") this.colors[lastUsedColor] = lastUsedColor;
            lastUsedColor = keyName;

            var myCell = me.pool.pull("mazetile", x, y, 
                name : "mazetile",
                type : "mazetile",
                image : image,
                row : row,
                col : col,
                width: 64,
                height : 64,
                spritewidth : 64
            );
            me.game.world.addChild(myCell);
            this.grids[row][col] = myCell;  
        

这在逐行的基础上工作(意味着 2 个相邻的列不会共享相同的颜色),但在下一行,可以有相同颜色的相邻节点。

我的下一个想法是首先生成所有带有颜色的平铺图像......然后再次迭代以检查相邻颜色......如果有,换出新图像。但我想在生成一组图块时完成此操作,而无需执行另一个嵌套 for 循环。


我已经尝试了 roko 建议的方法,“迷宫”现在可以正常工作了,但是当玩家移动到桥的下一部分时(我已经在网格中生成了第二组图块,请参阅此我的意思是:http://i.imgur.com/Hlerxm3.png),他附近似乎没有颜色:

你可以看到它说“黄色”,但他周围没有黄色选项。

代码:(省略代码以实际循环并生成网格,因为这不是问题)

run : function (maze) 
    this.maze= maze;
    this.list = [];
    this.containerOfGrids = [];
    this.myDirectionsText = new game.HUD.ScreenText(630, 10, 10, 10, font: "32x32_font", text: "1")

    game.data.gameHUD.addChild(this.myDirectionsText);          
    for (var i = 0; i <= game.data.bridgeSegments.length-1; i++) 
        this.containerOfGrids[i] = [];
        this.createGrid(game.data.bridgeSegments[i], i);                
    

    //call to set initial color cell
    this.firstCell();

,  

最初调用以选择第一个单元格。如果它是顶部的桥段(桥形状 1),我需要从第一列中的随机行开始...如果它是路径蜿蜒的其他网格,我需要随机选择一列...

firstCell : function () 
    //choose intitial random starting cell 
    if (game.data.bridgeSegments[this.bridgeIndex].settings.realname == "bridge_shape_1") 
        var row = Math.floor(Math.random() * (this.containerOfGrids[this.bridgeIndex].length - 0) + 0);
        var col = 0;    
        this.gridLen = this.containerOfGrids[this.bridgeIndex][row].length;
    
    else 
        var row = 0;
        var col = Math.floor(Math.random() * (this.containerOfGrids[this.bridgeIndex][row].length - 0) + 0);
        this.gridLen = this.containerOfGrids[this.bridgeIndex].length;
    
    this.containerOfGrids[this.bridgeIndex][row][col].firstCell = true;

    this.currColor = this.containerOfGrids[this.bridgeIndex][row][col].color;
    this.containerOfGrids[this.bridgeIndex][row][col].renderable.alpha = 1;
    this.myDirectionsText.settings.text = this.containerOfGrids[this.bridgeIndex][row][col].color;

,

//passing in collided cell, cell row and col from the Tile Class
nextCell : function (cell, row, col) 
    if (cell.col < this.gridLen)   
        this.checkValidCells(row, col);
        this.checkValidMove(cell, this.currColor);

        var randomNumber = Math.floor(Math.random() * (this.list.length));          
        this.currColor = (this.list.length > 0) ? this.list[randomNumber].color : "RED";
        this.myDirectionsText.settings.text = this.currColor; 
    

,

checkValidMove : function (cell, color) 
    if (cell.color == color) 
        cell.renderable.image = (game.data.bridgeSegments[this.bridgeIndex].settings.view == "topdown") ? me.loader.getImage("MyFlatTile3") :  me.loader.getImage("Tile128Green");          
    
    else 
        game.data.health -=10;
        cell.renderable.image = (game.data.bridgeSegments[this.bridgeIndex].settings.view == "topdown") ? me.loader.getImage("MyFlatTile3") :  me.loader.getImage("Tile128Red");
    
    cell.renderable.alpha = 1;  
,

checkValidCells : function (row, col) 
    this.list = [];


    if (row - 1 >= 0) 
        if (!this.containerOfGrids[this.bridgeIndex][row-1][col].explored) 
            this.list.push(this.containerOfGrids[this.bridgeIndex][row-1][col]);
        
    

    if (col - 1 >= 0) 
        if (!this.containerOfGrids[this.bridgeIndex][row][col-1].explored) 
            this.list.push(this.containerOfGrids[this.bridgeIndex][row][col-1]);
        
           

    if (col + 1 < this.containerOfGrids[this.bridgeIndex][row].length && this.containerOfGrids[this.bridgeIndex][row][col + 1] != "undefined")  
        if (!this.containerOfGrids[this.bridgeIndex][row][col+1].explored) 
            this.list.push(this.containerOfGrids[this.bridgeIndex][row][col+1]);
        

    
    if (row + 1 < this.containerOfGrids[this.bridgeIndex].length && this.containerOfGrids[this.bridgeIndex][row+1][col] != "undefined") 
        if (!this.containerOfGrids[this.bridgeIndex][row+1][col].explored) 
            this.list.push(this.containerOfGrids[this.bridgeIndex][row+1][col]);
        
    


在我的 tile 类中,我在与当前单元格发生冲突时启动下一个单元格:

        if (!this.explored) 
            nextCell(this, this.row, this.col);
            this.explored=true;
        

【问题讨论】:

您想避免相邻的瓷砖颜色相同或相邻的瓷砖颜色相同吗? @KSFT 随机路径上的邻居节点不能共享相同的颜色。但为了简单起见,我们可以说彼此相邻的节点不能共享相同的颜色。 我不确定它们是否相同。在您提供的示例图像中,没有两个相同颜色的相邻节点,但您说“这很糟糕”。 @KSFT 对不起,我很困惑。添加最后一条规则 @RokoC.Buljan 查看游戏规则 :) 抱歉 【参考方案1】:

如果我没听错的话,你不仅关心的是不在自己旁边放置相同的颜色,而且还关心所有方向的所有 2 个步骤。

您可以在为图块 (a,b) 着色时制定规则,而不是从对象中删除颜色。如果 a-2 a+2 AND y-2

然后你必须检查你想要放置的每种颜色的规则(每种颜色可以同时有多个活动规则,如果 0,0 和 3,0 都是红色,你需要当您移动到下一行时,第一条规则仍然存在)。

在不知道您是如何实现颜色和网格的情况下,很难进行更详细的说明。

编辑再读一遍,发现我写的是 y-2

【讨论】:

【参考方案2】:

这行得通吗?我不确定我是否完全理解这个问题,但我认为这是正确的。我正在创建一个名为 grid 的数组并用随机颜色填充它,每次检查它是否与附近的颜色不同。

编辑:不,这还不行。我会努力解决的。 好的,我想我已经解决了。

    grid = [];
for(var i=0;i<=totalRows;row++)

    grid[i]=[]
    for(var j=0;j<=totalCols;j++)
    
        do
        
            var colorIndex = Math.floor(Math.random() * (Object.keys(this.colors).length - 0) + 0);
            var keyName = Object.keys(this.colors)[colorIndex]; 
            grid[i][j]=keyName;
            var nearSameColor=false;
            for(var k=i-2;k<=i+2;k++)
            
                if(k<0||k>totalRows)
                    continue;
                for(var l=j-2;l<=l+2;l++)
                
                    if(l<0||l>totalCols||(k==i&&l==j))
                        continue;
                    nearSameColor=nearSameColor||grid[i+k][j+l]==grid[i][i];
                
            
        while(nearSameColor)
    

for (var row = 0; row <= totalRows; row++) 
    this.containerOfGrids[i][row] = [];
    for (var col = 0; col <= totalCols; col++) 
        image = grid[row][col];

        //other code

【讨论】:

您应该解释您所做的更改以及您认为它们可能有用的原因。 @KSFT 请按照 Roko 提到的方式添加您的推理 @Growler 我试图解释它。有什么具体的部分你想让我解释一下吗?

以上是关于确保相邻节点不共享相同的值的主要内容,如果未能解决你的问题,请参考以下文章

Dijkstra 算法随机选择具有相同最小权重的相邻节点

Google ORTools - 不能共享相同路由的节点(再次)

Day1 Heap与Priority_queue

为树中的节点添加颜色

Leetcode swap-nodes-in-pairs(链表 交换相邻节点)

宽度为 25% 的四个节点不适合彼此相邻?