【问题标题】:Conways Game Of Life Rendering康威生命游戏渲染
【发布时间】:2014-03-20 14:17:20
【问题描述】:

我已经完成了一个生命游戏的实现,但是在应用游戏规则后渲染网格时遇到了问题。我有一个看起来像这样的游戏循环:

while (gameIsRunning)
{
    //Needed for accessing UIControls from the background
    //thread.

    if (InvokeRequired)
    {
        //Process the array.
        MainBoard.Cells = engine.ApplyGameRules(MainBoard.Cells, MainBoard.Size.Height, MainBoard.Size.Width, BOARD_DIMENSIONS);
        //Check if there is a state such as
        //all states being dead, or all states being
        //alive.
        //Update the grid with the updated cells.
        this.Invoke(new MethodInvoker(delegate
                                     {
                                         timeCounter++;
                                         lblTimeState.Text = timeCounter.ToString();
                                         pictureBox1.Invalidate();
                                         pictureBox1.Update();
                                         Thread.Sleep(100);
                                     }));

        }
    }

还有一个如下所示的绘图函数:

for (int x = 0; x < MainBoard.Size.Height; x++)
{
    for (int y = 0; y < MainBoard.Size.Width; y++)
    {
        Cell individualCell = MainBoard.Cells[y, x];
        if (individualCell.IsAlive() == false)
        {
            e.Graphics.FillRectangle(Brushes.Red, MainBoard.Cells[y, x].Bounds);
        }
        //White indicates that cells are alive
        else if (individualCell.IsAlive() == true)
        {
            e.Graphics.FillRectangle(Brushes.White, MainBoard.Cells[y, x].Bounds);
        }
        else if (individualCell.IsInfected() == true)
        {
            e.Graphics.FillRectangle(Brushes.Green, MainBoard.Cells[y, x].Bounds);
        }
        //Draws the grid background itself.
        e.Graphics.DrawRectangle(Pens.Black, MainBoard.Cells[y, x].Bounds);
    }
}

我遇到的问题是我将所有游戏规则应用于网格中的每个单元格,然后绘制该网格,然后再次应用所有规则,所以我永远不会得到我想要的生命形式 blob应该看到。游戏规则是否应该逐个单元格地应用,以使其类似于以下内容:将游戏规则应用于单元格,绘制网格,将游戏规则应用于另一个单元格,绘制网格......?

【问题讨论】:

  • 据我了解,您将规则应用于整个网格,然后重绘。所以你需要将网格的状态保持原样,然后根据original网格中的情况更新一个copy
  • 好的,我会尝试类似的方法,我记得在某处读到,在显示网格时必须使用副本,并且我使用原件来进行规则应用和渲染。

标签: c# conways-game-of-life


【解决方案1】:

看起来程序的当前意图是正确的。

你应该做的是(伪代码):

  Board oldBoard = new Board(start cell definitions);
  while(not finished) {
      Board newBoard = calculate(oldBoard);
      display(newBoard);
      oldBoard = newBoard();
  }

如果您没有看到您期望的表单,那么要么是您的显示代码错误,要么是您的规则代码错误。

在伪代码中,一旦不再需要上一代的板,我将丢弃它,并为每一代制作一个新板。 calculate() 包含一个 new Board() 语句。

当然,如果制作新板的成本很高,您可以重新使用一个,然后在“当前”和“其他”板之间来回切换。请记住,每次你写板时,它的新状态必须 100% 是上一代状态的函数,并且不受其自身起始状态的影响。即您必须写入每个单元格。

另一种方法是让每个单元格保存两个值。因此,不是两个板,每个单元格一个值,而是一个板,每个单元格包含一个“当前”和“上一个”值。

  Board board = new Board(initial state);
  while(not finished) {
      board.calculate(); // fills "current" cells based on "previous" cells.
      display(board);
      board.tick(); // "current" becomes "previous".
                    // "previous" becomes current, but is "dirty" until calculated.
  }

有很多方法可以做到。一种方法是:

  public class Cell {
      private boolean[] state = new boolean[2];
      private int generation = 0;

      public void setCurrentState(boolean state) {
          state[generation] = state;
      }

      public void getCurrentState() {
          return state[generation];
      }

      public void getLastState() {
          return state[ (generation + 1) % 2 ];
      }

      public void tick() {
          generation = (generation + 1) % 2;
      }

  }

【讨论】:

  • 在伪代码的最后一行,是否所有旧单元格都在重新初始化?
  • 感谢您的反馈。我仍然不确定我是否直接理解。例如,在我的代码中,我的 MainBoard.Cells 是二维数组或表格。我将规则应用于此表,然后在一代中重新绘制该表。我的初始状态是所有细胞都活着。第 2 代我使用相同的 MainBoard.Cells,它现在具有每个单元格的更新状态。我再次应用规则并重新绘制。此外,我表中的每个单元格都有一个 isAlive 属性来确定是死是活。
  • 这样做的问题是,当你计算cell(n)时,它需要知道上一代cell(n-1)的状态。您可能只是更改了 cell(n-1) 的值。
  • 例如,使用 4x4 网格,其中所有单元格作为起始状态开始活动。如果我仅根据起始板计算新板,那么每个单元都会死?因为在逐个单元使用原始板单元时,新板上的每个单元都会因过度拥挤而死。那么这个新的板子变成了以前的板子,需要为第三代生成另一个新的板子,对吗?
  • 正确。要获得有趣的结果,您必须使用可以生存的模式来初始化您的第一个网格。
猜你喜欢
  • 2013-02-21
  • 2010-09-07
  • 2017-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多