Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.ArtificialAnt.Views/3.3/AntTrailView.cs @ 3239

Last change on this file since 3239 was 3239, checked in by gkronber, 14 years ago

Extracted view for artificial ant problem into a separate plugin/project. #952 (Artificial Ant Problem for 3.3)

File size: 9.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.Windows.Forms;
25using HeuristicLab.Core.Views;
26using HeuristicLab.Data;
27using HeuristicLab.MainForm;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using System.Collections.Generic;
30
31namespace HeuristicLab.Problems.ArtificialAnt.Views {
32  [View("AntTrail View")]
33  [Content(typeof(AntTrail), true)]
34  public sealed partial class AntTrailView : ItemView {
35    public new AntTrail Content {
36      get { return (AntTrail)base.Content; }
37      set { base.Content = value; }
38    }
39
40    public AntTrailView() {
41      InitializeComponent();
42    }
43
44    public AntTrailView(AntTrail content)
45      : this() {
46      Content = content;
47    }
48
49    protected override void DeregisterContentEvents() {
50      Content.SymbolicExpressionTreeChanged -= new EventHandler(Content_SymbolicExpressionTreeChanged);
51      base.DeregisterContentEvents();
52    }
53    protected override void RegisterContentEvents() {
54      base.RegisterContentEvents();
55      Content.SymbolicExpressionTreeChanged += new EventHandler(Content_SymbolicExpressionTreeChanged);
56    }
57
58    protected override void OnContentChanged() {
59      base.OnContentChanged();
60      if (Content == null) {
61        pictureBox.Image = null;
62        pictureBox.Enabled = false;
63      } else {
64        pictureBox.Enabled = true;
65        GenerateImage();
66      }
67    }
68
69    private void GenerateImage() {
70      playButton.Enabled = this.Enabled;
71      animationTimer.Stop();
72      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
73        if (Content == null) {
74          pictureBox.Image = null;
75          playButton.Enabled = false;
76        } else {
77          var nodeStack = new Stack<SymbolicExpressionTreeNode>();
78          int rows = Content.World.Rows;
79          int columns = Content.World.Columns;
80          SymbolicExpressionTree expression = Content.SymbolicExpressionTree;
81
82          DrawWorld();
83          using (Graphics graphics = Graphics.FromImage(pictureBox.Image)) {
84            float cellHeight = pictureBox.Height / (float)rows;
85            float cellWidth = pictureBox.Width / (float)columns;
86
87            AntInterpreter interpreter = new AntInterpreter();
88            interpreter.MaxTimeSteps = Content.MaxTimeSteps.Value;
89            interpreter.Expression = Content.SymbolicExpressionTree;
90            interpreter.World = Content.World;
91            int currentAntLocationColumn;
92            int currentAntLocationRow;
93            // draw initial ant
94            interpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
95            DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, interpreter.AntDirection, cellWidth, cellHeight);
96            // interpret ant code and draw trail
97            while (interpreter.ElapsedTime < interpreter.MaxTimeSteps) {
98              interpreter.Step();
99              interpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
100              DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, interpreter.AntDirection, cellWidth, cellHeight);
101            }
102          }
103          pictureBox.Refresh();
104        }
105      }
106    }
107
108    private void DrawWorld() {
109      int rows = Content.World.Rows;
110      int columns = Content.World.Columns;
111      Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
112      using (Graphics graphics = Graphics.FromImage(bitmap)) {
113        float cellHeight = pictureBox.Height / (float)rows;
114        float cellWidth = pictureBox.Width / (float)columns;
115        // draw world
116        for (int i = 0; i < rows; i++) {
117          graphics.DrawLine(Pens.Black, 0, i * cellHeight, pictureBox.Width, i * cellHeight);
118        }
119        for (int j = 0; j < columns; j++) {
120          graphics.DrawLine(Pens.Black, j * cellWidth, 0, j * cellWidth, pictureBox.Height);
121        }
122        for (int i = 0; i < rows; i++) {
123          for (int j = 0; j < columns; j++) {
124            if (Content.World[i, j])
125              graphics.FillEllipse(Brushes.LightBlue, j * cellWidth, i * cellHeight, cellWidth, cellHeight);
126          }
127        }
128        pictureBox.Image = bitmap;
129      }
130    }
131
132    private void DrawAnt(Graphics g, int row, int column, int direction, float cellWidth, float cellHeight) {
133      //g.FillRectangle(Brushes.White, column * cellWidth, row * cellHeight,
134      //      cellWidth, cellHeight);
135      // draw ant body
136      g.FillRectangle(Brushes.Brown,
137            column * cellWidth + cellWidth * 0.25f, row * cellHeight + cellHeight * 0.25f,
138            cellWidth * 0.5f, cellHeight * 0.5f);
139      // show ant direction
140      float centerX = column * cellWidth + cellWidth * 0.5f;
141      float centerY = row * cellHeight + cellHeight * 0.5f;
142      float directionX = centerX;
143      float directionY = centerY;
144      switch (direction) {
145        case 0: { // EAST
146            directionX = centerX + cellWidth * 0.5f;
147            break;
148          }
149        case 1: { // SOUTH
150            directionY = directionY + cellHeight * 0.5f;
151            break;
152          }
153        case 2: { // WEST
154            directionX = centerX - cellWidth * 0.5f;
155            break;
156          }
157        case 3: { // NORTH
158            directionY = directionY - cellHeight * 0.5f;
159            break;
160          }
161        default: throw new InvalidOperationException();
162      }
163      g.DrawLine(Pens.Brown, centerX, centerY, directionX, directionY);
164    }
165
166    void Content_SymbolicExpressionTreeChanged(object sender, EventArgs e) {
167      if (InvokeRequired)
168        Invoke(new EventHandler(Content_SymbolicExpressionTreeChanged), sender, e);
169      else
170        GenerateImage();
171    }
172
173    private void pictureBox_SizeChanged(object sender, EventArgs e) {
174      GenerateImage();
175    }
176
177    #region animation
178    private AntInterpreter animationInterpreter;
179    private void playButton_Click(object sender, EventArgs e) {
180      playButton.Enabled = false;
181      int rows = Content.World.Rows;
182      int columns = Content.World.Columns;
183      SymbolicExpressionTree expression = Content.SymbolicExpressionTree;
184      var nodeStack = new Stack<SymbolicExpressionTreeNode>();
185
186      animationInterpreter = new AntInterpreter();
187      animationInterpreter.MaxTimeSteps = Content.MaxTimeSteps.Value;
188      animationInterpreter.Expression = Content.SymbolicExpressionTree;
189      animationInterpreter.World = Content.World;
190
191      DrawWorld();
192      using (Graphics graphics = Graphics.FromImage(pictureBox.Image)) {
193        float cellHeight = pictureBox.Height / (float)Content.World.Rows;
194        float cellWidth = pictureBox.Width / (float)Content.World.Columns;
195        // draw initial ant
196        int currentAntLocationColumn;
197        int currentAntLocationRow;
198        animationInterpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
199        DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, animationInterpreter.AntDirection, cellWidth, cellHeight);
200        pictureBox.Refresh();
201      }
202
203      animationTimer.Start();
204    }
205
206    private void animationTimer_Tick(object sender, EventArgs e) {
207      using (Graphics graphics = Graphics.FromImage(pictureBox.Image)) {
208        float cellHeight = pictureBox.Height / (float)Content.World.Rows;
209        float cellWidth = pictureBox.Width / (float)Content.World.Columns;
210        int currentAntLocationColumn;
211        int currentAntLocationRow;
212        // interpret ant code and draw trail
213        animationInterpreter.Step();
214        animationInterpreter.AntLocation(out currentAntLocationRow, out currentAntLocationColumn);
215        DrawAnt(graphics, currentAntLocationRow, currentAntLocationColumn, animationInterpreter.AntDirection, cellWidth, cellHeight);
216        pictureBox.Refresh();
217        if (animationInterpreter.ElapsedTime < animationInterpreter.MaxTimeSteps) {
218          animationTimer.Start();
219        } else {
220          animationTimer.Stop();
221          playButton.Enabled = this.Enabled;
222        }
223      }
224    }
225    #endregion
226
227    private void AntTrailView_EnabledChanged(object sender, EventArgs e) {
228      if (this.Enabled) playButton.Enabled = true;
229      else playButton.Enabled = false;
230    }
231  }
232}
Note: See TracBrowser for help on using the repository browser.