Created
March 30, 2017 07:47
-
-
Save nic-hartley/b9060b38dab44884afec4901b41647f6 to your computer and use it in GitHub Desktop.
A full program for a WinForms-based app that draws a few colorful Drunkards' Walks.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Drawing; | |
using System.Windows.Forms; | |
namespace ColorWalker | |
{ | |
class Walker | |
{ | |
private int _lastX = 0, _lastY = 0; | |
private readonly int _maxVariance = 2, _speed = 3; | |
private Color _current = Color.FromArgb(128, 128, 128); | |
private Pen _artMaker = new Pen(Color.White, 3); | |
private Random _rng; | |
public Walker(Random rng, int startingX, int startingY) | |
{ | |
this._rng = rng; | |
this._lastX = startingX; | |
this._lastY = startingY; | |
} | |
private bool Wrap(ref int what, int min, int max) | |
{ | |
if (what < min) | |
what = max; | |
else if (what > max) | |
what = min; | |
else | |
return false; | |
return true; | |
} | |
public Tuple<int, int, Color> UpdateAndDraw(Graphics g, Size clientSize) | |
{ | |
int nextX = _lastX, nextY = _lastY; | |
nextX += _rng.Next(-_speed, _speed + 1); | |
nextY += _rng.Next(-_speed, _speed + 1); | |
bool centered = | |
Wrap(ref nextX, 0, clientSize.Width) | // no, I didn't mean || | |
Wrap(ref nextY, 0, clientSize.Height); | |
int nextR = _current.R + _rng.Next(-_maxVariance, _maxVariance + 1); | |
Wrap(ref nextR, 0, 255); | |
int nextG = _current.G + _rng.Next(-_maxVariance, _maxVariance + 1); | |
Wrap(ref nextG, 0, 255); | |
int nextB = _current.B + _rng.Next(-_maxVariance, _maxVariance + 1); | |
Wrap(ref nextB, 0, 255); | |
_current = Color.FromArgb(nextR, nextG, nextB); | |
_artMaker.Color = _current; | |
if (centered) | |
{ | |
g.DrawEllipse(_artMaker, nextX, nextY, 1, 1); | |
} | |
else | |
{ | |
g.DrawLine(_artMaker, _lastX, _lastY, nextX, nextY); | |
} | |
_lastX = nextX; | |
_lastY = nextY; | |
return Tuple.Create(nextX, nextY, _current); | |
} | |
} | |
public partial class ArtMakingForm : Form | |
{ | |
#region Windows Form Designer generated code | |
/// <summary> | |
/// Required designer variable. | |
/// </summary> | |
private System.ComponentModel.IContainer components = null; | |
/// <summary> | |
/// Clean up any resources being used. | |
/// </summary> | |
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |
protected override void Dispose(bool disposing) | |
{ | |
if (disposing && (components != null)) | |
{ | |
components.Dispose(); | |
} | |
base.Dispose(disposing); | |
} | |
/// <summary> | |
/// Required method for Designer support - do not modify | |
/// the contents of this method with the code editor. | |
/// </summary> | |
private void InitializeComponent() | |
{ | |
this.components = new System.ComponentModel.Container(); | |
this.timer = new System.Windows.Forms.Timer(this.components); | |
this.SuspendLayout(); | |
// | |
// timer | |
// | |
this.timer.Enabled = true; | |
this.timer.Interval = 1; | |
this.timer.Tick += new System.EventHandler(this.Stumble); | |
// | |
// ArtMakingForm | |
// | |
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); | |
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |
this.ClientSize = new System.Drawing.Size(496, 473); | |
this.Name = "ArtMakingForm"; | |
this.Text = "Watch The Colorful Drunk"; | |
this.Load += new System.EventHandler(this.ArtMakingForm_Load); | |
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Stumble); | |
this.ResumeLayout(false); | |
} | |
private System.Windows.Forms.Timer timer; | |
#endregion | |
private Random _rng = new Random(); | |
private List<Walker> _walkers = new List<Walker>(10); | |
private Dictionary<Tuple<int, int>, Color> _drawnBefore = | |
new Dictionary<Tuple<int, int>, Color>(); | |
public ArtMakingForm() | |
{ | |
InitializeComponent(); | |
this.ClientSize = new Size(512, 512); | |
this.MaximumSize = this.Size; | |
this.MinimumSize = this.Size; | |
for (int i = 0; i < _walkers.Capacity; ++i) | |
{ | |
_walkers.Add(new Walker(_rng, this.ClientSize.Width / 2, | |
this.ClientSize.Height / 2)); | |
} | |
} | |
private void ArtMakingForm_Load(object sender, EventArgs e) | |
{ | |
timer.Start(); | |
} | |
private void Stumble(object sender, EventArgs e) | |
{ | |
Graphics g = this.CreateGraphics(); | |
foreach (var walker in _walkers) | |
{ | |
var res = walker.UpdateAndDraw(g, this.ClientSize); | |
} | |
} | |
[STAThread] | |
static void Main() | |
{ | |
Application.EnableVisualStyles(); | |
Application.SetCompatibleTextRenderingDefault(false); | |
Application.Run(new ArtMakingForm()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment