cscの作法 その105

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題

迷路を描画せよ。

# 参考にしたページ


https://lets-csharp.com/mase-generator/

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a8bff639-24fd-9ee8-eb89-ada87aff27fc.png)


# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%

>csc maze.cs

```

# サンプルコード

```
using System;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Linq;
using System.Collections.Generic;

public enum MoveDirect {
	Left,
	Up,
	Right,
	Down,
}

public class BranchPoint {
	public BranchPoint(int colum, int row, int spacing, int leftMargin, int topMargin) {
		Colum = colum;
		Row = row;
		Spacing = spacing;
		Used = false;
		_point = new Point(leftMargin + colum * spacing, topMargin + row * spacing);
	}
	public int Colum {
		set;
		get;
	}
	public int Row {
		set;
		get;
	}
	public int Spacing {
		set;
		get;
	}
	public bool Used {
		set;
		get;
	}
	Point _point;
	public Point Point {
		get {
			return _point;
		}
	}
	List<MoveDirect> _moveDirects = new List<MoveDirect>();
	public List<MoveDirect> MoveDirects {
		get {
			return _moveDirects;
		}
	}
}

public class Line {
	public Line(Point start, Point end) {
		Start = start;
		End = end;
	}
	public Point Start {
		set;
		get;
	}
	public Point End {
		set;
		get;
	}
}



public class MaseGenerator
{
	Random Random = new Random();
	List<BranchPoint> _branchPoints = new List<BranchPoint>();
	BranchPoint CurPoint = null;
	List<BranchPoint> ConnectedPoints = new List<BranchPoint>();
	public List<Line> _lines = new List<Line>();
	int _numberOfRecursion = 0;
	public MaseGenerator(int columMax, int rowMax, int spacing, int leftMargin, int topMargin) {
		RowMax = rowMax;
		ColumMax = columMax;
		for (int y = 0; y < RowMax; y++)
		{
			for (int x = 0; x < ColumMax; x++)
				_branchPoints.Add(new BranchPoint(x, y, spacing, leftMargin, topMargin));
		}
		CurPoint = _branchPoints.FirstOrDefault(x => x.Colum == ColumMax / 2 && x.Row == RowMax / 2);
		CurPoint.Used = true;
		ConnectedPoints.Add(CurPoint);
		CreateMaze();
	}
	public int ColumMax {
		set;
		get;
	}
	public int RowMax {
		set;
		get;
	}
	public List<BranchPoint> BranchPoints {
		get { 
			return _branchPoints.ToList(); 
		}
	}
	public List<Line> Lines {
		get { 
			return _lines.ToList(); 
		}
	}
	public int NumberOfRecursion {
		get { 
			return _numberOfRecursion; 
		}
	}
	void CreateMaze() {
		_numberOfRecursion++;
		while (true)
		{
			BranchPoint point = ConnectedPoints.Last();
			if (GetMoveDirect(point).Count > 0)
			{
				CurPoint = point;
				break;
			}
			ConnectedPoints.Remove(point);
			if (ConnectedPoints.Count == 0)
				return;
		}
		while (true)
		{
			bool ret = MovePoint();
			if (!_branchPoints.Any(x => !x.Used))
				return;
			if (!ret)
				CreateMaze();
		}
	}
	bool MovePoint() {
		List<MoveDirect> moveDirects = GetMoveDirect(CurPoint);
		if (moveDirects.Count == 0)
			return false;
		int r = Random.Next(moveDirects.Count);
		MoveDirect direct = moveDirects[r];
		if (direct == MoveDirect.Left)
			MoveLeft();
		if (direct == MoveDirect.Up)
			MoveUp();
		if (direct == MoveDirect.Right)
			MoveRight();
		if (direct == MoveDirect.Down)
			MoveDown();
		return true;
	}
	List<MoveDirect> GetMoveDirect(BranchPoint curPoint) {
		List<MoveDirect> ret = new List<MoveDirect>();
		if (CanMoveLeft(curPoint))
			ret.Add(MoveDirect.Left);
		if (CanMoveUp(curPoint))
			ret.Add(MoveDirect.Up);
		if (CanMoveRight(curPoint))
			ret.Add(MoveDirect.Right);
		if (CanMoveDown(curPoint))
			ret.Add(MoveDirect.Down);
		return ret;
	}
	bool CanMoveLeft(BranchPoint curPoint) {
		if (curPoint.Colum == 0)
			return false;
		BranchPoint point = _branchPoints.FirstOrDefault(x => x.Colum == curPoint.Colum - 1 && x.Row == curPoint.Row);
		if (!point.Used)
			return true;
		else
			return false;
	}
	void MoveLeft() {
		Point oldPoint = CurPoint.Point;
		CurPoint.MoveDirects.Add(MoveDirect.Left);
		CurPoint = _branchPoints.FirstOrDefault(x => x.Colum == CurPoint.Colum - 1 && x.Row == CurPoint.Row);
		CurPoint.MoveDirects.Add(MoveDirect.Right);
		Point newPoint = CurPoint.Point;
		CurPoint.Used = true;
		ConnectedPoints.Add(CurPoint);
		_lines.Add(new Line(oldPoint, newPoint));
	}
	bool CanMoveUp(BranchPoint curPoint) {
		if (curPoint.Row == 0)
			return false;
		BranchPoint point = _branchPoints.FirstOrDefault(x => x.Colum == curPoint.Colum && x.Row == curPoint.Row - 1);
		if (!point.Used)
			return true;
		else
			return false;
	}
	void MoveUp() {
		Point oldPoint = CurPoint.Point;
		CurPoint.MoveDirects.Add(MoveDirect.Up);
		CurPoint = _branchPoints.FirstOrDefault(x => x.Colum == CurPoint.Colum && x.Row == CurPoint.Row - 1);
		CurPoint.MoveDirects.Add(MoveDirect.Down);
		Point newPoint = CurPoint.Point;
		CurPoint.Used = true;
		ConnectedPoints.Add(CurPoint);
		_lines.Add(new Line(oldPoint, newPoint));
	}
	bool CanMoveRight(BranchPoint curPoint) {
		if (curPoint.Colum + 1 >= ColumMax)
			return false;
		BranchPoint point = _branchPoints.FirstOrDefault(x => x.Colum == curPoint.Colum + 1 && x.Row == curPoint.Row);
		if (!point.Used)
			return true;
		else
			return false;
	}
	void MoveRight() {
		Point oldPoint = CurPoint.Point;
		CurPoint.MoveDirects.Add(MoveDirect.Right);
		CurPoint = _branchPoints.FirstOrDefault(x => x.Colum == CurPoint.Colum + 1 && x.Row == CurPoint.Row);
		CurPoint.MoveDirects.Add(MoveDirect.Left);
		Point newPoint = CurPoint.Point;
		CurPoint.Used = true;
		ConnectedPoints.Add(CurPoint);
		_lines.Add(new Line(oldPoint, newPoint));
	}
	bool CanMoveDown(BranchPoint curPoint) {
		if (curPoint.Row + 1 >= RowMax)
			return false;
		BranchPoint point = _branchPoints.FirstOrDefault(x => x.Colum == curPoint.Colum && x.Row == curPoint.Row + 1);
		if (!point.Used)
			return true;
		else
			return false;
	}
	void MoveDown() {
		Point oldPoint = CurPoint.Point;
		CurPoint.MoveDirects.Add(MoveDirect.Down);
		CurPoint = _branchPoints.FirstOrDefault(x => x.Colum == CurPoint.Colum && x.Row == CurPoint.Row + 1);
		CurPoint.MoveDirects.Add(MoveDirect.Up);
		Point newPoint = CurPoint.Point;
		CurPoint.Used = true;
		ConnectedPoints.Add(CurPoint);
		_lines.Add(new Line(oldPoint, newPoint));
	}
}

public partial class Form1 : Form {
	int RowMax = 28;
	int ColumMax = 32;
	int LeftMargin = 30;
	int TopMargin = 35;
	int Spacing = 15;
	MaseGenerator MaseGenerator = null;
	public Form1() {
		Text = "Maze";
		ClientSize = new Size(520, 470);
		this.DoubleBuffered = true;
		this.BackColor = Color.Black;
		CreateMenu();
		MaseGenerate();
	}
	void MaseGenerate() {
		MaseGenerator = new MaseGenerator(ColumMax, RowMax, Spacing, LeftMargin, TopMargin);
	}
	void CreateMenu() {
		ToolStripMenuItem menuItemGenerate = new ToolStripMenuItem("生成");
		menuItemGenerate.Click += MenuItemGenerate_Click;
		MenuStrip menuStrip = new MenuStrip();
		this.Controls.Add(menuStrip);
		menuStrip.Items.Add(menuItemGenerate);
	}
	private void MenuItemGenerate_Click(object sender, EventArgs e) {
		MaseGenerate();
		Invalidate();
	}
	protected override void OnPaint(PaintEventArgs e) {
		DrawMaze(e.Graphics);
		base.OnPaint(e);
	}
	void DrawMaze(Graphics graphics) {
		int lineWidth = 3;
		Pen pen = new Pen(Color.White, lineWidth);
		SolidBrush brush = new SolidBrush(Color.White);
		foreach (Line line in MaseGenerator.Lines)
		{
			Point start = new Point(line.Start.X - lineWidth / 2, line.Start.Y - lineWidth / 2);
			Point end = new Point(line.End.X - lineWidth / 2, line.End.Y - lineWidth / 2);
			Size size = new Size(lineWidth, lineWidth);
			graphics.FillRectangle(brush, new Rectangle(start, size));
			graphics.FillRectangle(brush, new Rectangle(end, size));
			graphics.DrawLine(pen, line.Start, line.End);
		}
		pen.Dispose();
		brush.Dispose();
	}
	[STAThread]
	public static void Main() {
		Application.Run(new Form1());
	}
}





```


以上。