压缩if-elseif-else语句以节省比较

时间:2016-04-09 23:17:06

标签: c# performance if-statement unity3d

我希望能得到一些帮助。我遇到的唯一真正问题是这段代码效率不高。基本上我有一组瓷砖,需要根据它们周围的瓷砖组合来决定要实例化哪种瓷砖。在下面的代码中,我正在检查的瓷砖的位置是我的地图中的关键(ex map [right]是右边的瓷砖,topLeft是与左上角对角相邻的瓷砖,top2等是瓷砖那个方向有两个空间)。

有问题的代码:

if (map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.NOTHING && map[bottom].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeTopLeftInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.NOTHING && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeTopRightInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.WALL && map[top].Type == TileType.NOTHING && map[right].Type == TileType.NOTHING && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeBottomLeftInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.NOTHING && map[top].Type == TileType.NOTHING && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeBottomRightInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.WALL && map[top].Type == TileType.FLOOR && map[right].Type == TileType.FLOOR && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeCornerTopRightTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.FLOOR && map[top].Type == TileType.FLOOR && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeCornerTopLeftTile, t.Position, Quaternion.identity);
                    }

                    else if (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[topRight].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeCornerBottomLeftTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.FLOOR && map[bottom].Type == TileType.WALL && map[topLeft].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeCornerBottomRightTile, t.Position, Quaternion.identity);
                    }

                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.NOTHING && map[left2].Type == TileType.NOTHING) || (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.WALL && map[left2].Type == TileType.FLOOR && map[bottom2].Type == TileType.WALL))
                    {
                        Instantiate(wallTopLeftTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.NOTHING && map[right2].Type == TileType.NOTHING) || (map[right].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[left].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.WALL && map[right2].Type == TileType.FLOOR && map[bottom2].Type == TileType.WALL))
                    {
                        Instantiate(wallTopRightTile, t.Position, Quaternion.identity);
                    }

                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[left2].Type == TileType.NOTHING) || (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[left2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallBottomLeftTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[right2].Type == TileType.NOTHING) || (map[right].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[left].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[right2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallBottomRightTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[left2].Type == TileType.NOTHING && map[bottom2].Type == TileType.FLOOR) || (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[left2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallMidLeftTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[right2].Type == TileType.NOTHING && map[bottom2].Type == TileType.FLOOR) || (map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.FLOOR && map[bottom].Type == TileType.WALL && map[right2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallMidRightTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.NOTHING && map[bottom2].Type == TileType.WALL))
                    {
                        Instantiate(wallTopTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallBottomTile, t.Position, Quaternion.identity);
                    }
                    else if (map[top].Type == TileType.NOTHING && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeBottomTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.NOTHING && map[right].Type == TileType.FLOOR) || (map[left].Type == TileType.NOTHING && map[right].Type == TileType.WALL && map[top].Type != TileType.NOTHING))
                    {
                        Instantiate(wallEdgeRightTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.FLOOR && map[right].Type == TileType.NOTHING) || (map[left].Type == TileType.WALL && map[right].Type == TileType.NOTHING && map[top].Type != TileType.NOTHING))
                    {
                        Instantiate(wallEdgeLeftTile, t.Position, Quaternion.identity);
                    }
                    else if (map[bottom].Type == TileType.NOTHING && map[top].Type == TileType.FLOOR)
                    {
                        Instantiate(wallEdgeTopTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.WALL && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallMiddleTile, t.Position, Quaternion.identity);
                    }
                    else
                    {
                        // Should never get here, so if a white Tile is seen, something went wrong!
                        Instantiate(whiteTile, t.Position, Quaternion.identity);
                    }

我已经制作了一张桌子,因为我认为我会检查每个位置,为它指定一个0-2的数字,将该数字从基数3转换为十进制,然后在结果上使用switch语句来确定哪个tile到实例。数字代码位于最右侧。 但是有很多组合,我觉得必须有更好或更简单的方法。任何想法都值得赞赏!

表: Table of conditions

1 个答案:

答案 0 :(得分:0)

为了简单地减少caparison操作的数量,我建议以树型方式安排AND条件。这是一个简化的例子。

注意:我正在使用单曲和为了便于阅读 - 我的意思是逻辑AND。

从:

开始
if(a&b&c) {functionW(a);return;}  //1 comparison, 2 ANDops
else if(a&b&!c) {functionX(a);return;}//2 comparison, 4 ANDops
else if(a&!b&!c) {functionX(b);return;}//3 comparison, 6 ANDops
else if(a&!b&c) {functionX(c);return;}//4 comparison, 8 ANDops
else if(!&a&b&c) {functionY(b);return}//5 comparison, 10 ANDops
else if(!a&!b&c){functionZ(c);return}//6 comparison, 12 ANDops
else if(!b&!e){functionZ(c);return;}//7 comparison, 13 ANDops

树格式:为我们正在检查的每个元素取一个分支,因此首先检查:

//out here,first, go all the statements, where it doesn't mater what value a has.  We haveonly one condition in our example, but if we had many, we could create a separate "tree" out here.
if(!b&!e){functionZ(c);return;}//1 comparison, 1 ANDops
//now we start a branch based on a
if(a)
{//in here go all the if statements where a is true
    //now we create onther tree branch based on b
    if(b)
    {   
        if(!c){ functionW(a); return;}// total 4 comparisons to get here. 1 ANDops
    }
    else 
    {//all option where b is false
        if(c) {functionX(c); return;}// total 4 comparisons to get here, 1 ANDops
        else {functionX(b); return;}// total 4 comparisons to get here, 1 ANDops
    }
}
else
{//in here go all the if statements where a is false (there are only two, so no need for a branch)
    if(b&c) {functionY(b);return}// total 3 comparisons to get here. 2 ANDops
    else if(!b&c){functionZ(c);return}// total 3 comparisons to get here, 3 ANDops
}

显然,只有7种不同的条件,你才能获得巨大的优势,但随着你开始的条件数量的增加,这种改进会增加。