#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Parameters; using HeuristicLab.Data; using HeuristicLab.Optimization; using System.Threading; using HeuristicLab.SimulationCore.AgentBased; using HeuristicLab.Analysis; namespace HeuristicLab.SimulationCore.Samples { [Item("GameOfLifeSimulation", "A game of life simulation.")] [Creatable("Simulations")] [StorableClass] public sealed class GameOfLifeSimulation: AgentBasedSimulation { public override Type ProblemType { get { return typeof(GameOfLifeScenario); } } private GameOfLifeScenario Scenario { get { return Problem as GameOfLifeScenario; } } public ValueParameter IterationsParameter { get { return (ValueParameter)Parameters["Iterations"]; } } public GameOfLifeSimulation() : base() { Parameters.Add(new ValueParameter("Iterations", "The number of iterations.", new IntValue(100))); Initialize(); } [StorableConstructor] private GameOfLifeSimulation(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { Initialize(); } private GameOfLifeSimulation(GameOfLifeSimulation original, Cloner cloner) : base(original, cloner) { Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new GameOfLifeSimulation(this, cloner); } private GameOfLifeAgent GetAgent(int x, int y) { int width = Scenario.WidthParameter.Value.Value; int height = Scenario.HeightParameter.Value.Value; if (x >= width || y >= height) throw new Exception("invalid index"); int index = x + y * width; return Agents[index] as GameOfLifeAgent; } private void Initialize() { if (Scenario != null) { Scenario.WidthParameter.ValueChanged += new EventHandler(WidthParameter_ValueChanged); if(Scenario.WidthParameter.Value != null) Scenario.WidthParameter.Value.ValueChanged += new EventHandler(Width_ValueChanged); Scenario.HeightParameter.ValueChanged += new EventHandler(HeightParameter_ValueChanged); if (Scenario.HeightParameter.Value != null) Scenario.HeightParameter.Value.ValueChanged += new EventHandler(Height_ValueChanged); } } void Width_ValueChanged(object sender, EventArgs e) { CreateAgents(); } void Height_ValueChanged(object sender, EventArgs e) { CreateAgents(); } void HeightParameter_ValueChanged(object sender, EventArgs e) { CreateAgents(); } void WidthParameter_ValueChanged(object sender, EventArgs e) { CreateAgents(); } public IEnumerable GetNeighbors(GameOfLifeAgent agent) { int width = Scenario.WidthParameter.Value.Value; int height = Scenario.HeightParameter.Value.Value; int index = Agents.IndexOf(agent); List result = new List(); int y = index / width; int x = index - (y * width); for (int x1 = x - 1; x1 <= x + 1; x1++) { for (int y1 = y - 1; y1 <= y + 1; y1++) { if (x1 >= 0 && y1 >= 0 && x1 < width && y1 < height && (x1 != x || y1 != y)) { GameOfLifeAgent neighbor = GetAgent(x1, y1); result.Add(neighbor); } } } return result; } private void CreateAgents() { Agents.Clear(); int width = Scenario.WidthParameter.Value.Value; int height = Scenario.HeightParameter.Value.Value; for (int i = 0; i < width * height; i++) { Agents.Add(new GameOfLifeAgent(this)); } InitAgents(); } protected override void OnProblemChanged() { base.OnProblemChanged(); Initialize(); CreateAgents(); } private void InitAgents() { double rate = Scenario.AliveRateParameter.Value.Value; int width = Scenario.WidthParameter.Value.Value; int height = Scenario.HeightParameter.Value.Value; Random rand = new Random(); for (int i = 0; i < width * height; i++) { GameOfLifeAgent agent = Agents[i] as GameOfLifeAgent; agent.Alive = rand.NextDouble() < rate; } } protected override void OnPrepared() { base.OnPrepared(); InitAgents(); } private void UpdateResults() { int width = Scenario.WidthParameter.Value.Value; int height = Scenario.HeightParameter.Value.Value; HeatMap cells = new HeatMap(width, height); for (int i = 0; i < width * height; i++) { int y = i / width; int x = i - (y * width); if (GetAgent(x, y).Alive) cells[x, y] = 1; else cells[x, y] = 0; } Results["Cells"].Value = cells; IntValue currentIterations = (Results["CurrentIterations"].Value as IntValue); currentIterations.Value++; } protected override void Run(CancellationToken cancellationToken) { int iterations = IterationsParameter.Value.Value; int width = Scenario.WidthParameter.Value.Value; int height = Scenario.HeightParameter.Value.Value; int start = 0; if (Results.ContainsKey("CurrentIterations")) { start = (Results["CurrentIterations"].Value as IntValue).Value; } else { Results.Add(new Result("CurrentIterations", new IntValue(0))); Results.Add(new Result("Cells", new HeatMap(width, height))); } for (int i = start; i < iterations; i++) { cancellationToken.ThrowIfCancellationRequested(); base.Step(); UpdateResults(); Thread.Sleep(250); } } } }