生命游戏中的滞后代码3D

时间:2013-06-03 17:37:35

标签: c# performance 3d conways-game-of-life

我的生命游戏编码为3D环境,使用SharpGL用C#编写。代码工作正常,就逻辑而言,它运行得非常慢。

游戏中的单元格采用颜色编码,这意味着根据下一次“转弯”的状态,它们会改变颜色。我的老师要在一些非常旧的计算机上测试项目,所以我需要弄清楚如何使代码更快更高效。

计算代码发布在下面。请指出可能会减慢游戏速度的任何问题。

//cell.willdie means that the cell will die in the next turn
//cell.dies means that the cell dies immediately
//cell.abouttobeborn means that the cell will be born in the next turn
//cell.coord is where the cell is

public void checkcells() //determines whether or not for every cell if they die or not. Also changes color-coding of cells.
        {
            List<int[]> openspaceatwhere = new List<int[]>();
            List<cell_class> acell = new List<cell_class>();
            for (int i = 0; i < cell.Count(); i++)
            {
                bool dies = false;
                int neighbors = 0;
                cell[i].willdie = false;
                for (int x = -1; x < 2; x++)
                {
                    for (int y = -1; y < 2; y++)
                    {
                        for (int z = -1; z < 2; z++)
                        {
                            bool isopen = true;
                            for (int i2 = 0; i2 < cell.Count(); i2++)
                            {
                                if (!(x == 0 && y == 0 && z == 0) && cell[i].coord[0] + x == cell[i2].coord[0] && cell[i].coord[1] + y == cell[i2].coord[1] && cell[i].coord[2] + z == cell[i2].coord[2])
                                {
                                    isopen = false;
                                    neighbors += 1;
                                }
                            }
                            if (isopen)
                            {
                                openspaceatwhere.Add(new int[4] { cell[i].coord[0]+x, cell[i].coord[1]+y, cell[i].coord[2]+z, 0 });
                            }
                        }
                    }
                }
                if (neighbors > 6 || neighbors < 3)
                    dies = true;
                if (dies)
                    cell[i].dies = true;
                else
                    cell[i].dies = false;
                for (int a = 0; a < openspaceatwhere.Count(); a++)
                {
                    for (int b = 0; b < openspaceatwhere.Count(); b++)
                    {
                        if (openspaceatwhere[a][0] == openspaceatwhere[b][0] && openspaceatwhere[a][1] == openspaceatwhere[b][1] && openspaceatwhere[a][2] == openspaceatwhere[b][2])
                        {
                            if (a != b)
                            { openspaceatwhere.RemoveAt(b); openspaceatwhere[a][3] += 1; }
                        }
                    }
                }
            }
            List<int[]> quequecell = new List<int[]>();
            for (int i = 0; i < openspaceatwhere.Count(); i++ )
            {
                if(openspaceatwhere[i][3] == 6)
                    quequecell.Add(new int[3] { openspaceatwhere[i][0], openspaceatwhere[i][1], openspaceatwhere[i][2]});
            }
            for (int i = 0; i < cell.Count(); i++)
            {
                if (cell[i].dies)
                {
                    if (animated && delay == 50)
                    {
                        cell.RemoveAt(i);
                        cellsdied += 1;
                        i--;
                    }
                    else
                    {
                        cell[i].willdie = true;
                    }
                }
            }
            for (int i = 0; i < quequecell.Count(); i++)
            {
                if (animated && delay == 50)
                {
                    cell.Add(new cell_class());
                    cell[cell.Count()-1].coord[0] = quequecell[i][0];
                    cell[cell.Count()-1].coord[1] = quequecell[i][1];
                    cell[cell.Count()-1].coord[2] = quequecell[i][2];
                    createdcells += 1;
                }
                else
                {
                    acell.Add(new cell_class());
                    acell[acell.Count()-1].coord[0] = quequecell[i][0];
                    acell[acell.Count()-1].coord[1] = quequecell[i][1];
                    acell[acell.Count()-1].coord[2] = quequecell[i][2];
                    acell[acell.Count()-1].abouttobeborn = true;
                    rendercell(acell[acell.Count()-1]);
                }
            }
        }

1 个答案:

答案 0 :(得分:2)

  1. 确保这段代码实际上是性能瓶颈。即使您使用的是xxxGL,绘图也可能非常耗时。
  2. 查看您正在使用的列表类型,并确保它们对您正在执行的操作有效。例如,根据单元格列表的类型,

        for (int i = 0; i < cell.Count(); i++)
        {
            if (cell[i].dies)
            {
                if (animated && delay == 50)
                {
                    cell.RemoveAt(i);
                    cellsdied += 1;
                    i--;
                }
                else
                {
                    cell[i].willdie = true;
                }
            }
        }
    
  3. 由于您正在使用迭代的RemoveAt(i),i--样式,这段代码可能会非常慢。

    3.考虑保留一些数据结构并更新它们,而不是构建新的列表和对象。可以认为细胞在游戏的生命周期中存在。有时它已经死了,有时它正在死亡或活着,但是不需要删除或重新创建单元对象。我在C#的知识基础之外,但是对“新”的调用涉及内存分配,并且比保持对象和修改其状态更昂贵。