Initial commit
This commit is contained in:
37
.gitignore
vendored
Normal file
37
.gitignore
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
*.swp
|
||||||
|
*.*~
|
||||||
|
project.lock.json
|
||||||
|
.DS_Store
|
||||||
|
*.pyc
|
||||||
|
nupkg/
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Rider
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
build/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Oo]ut/
|
||||||
|
msbuild.log
|
||||||
|
msbuild.err
|
||||||
|
msbuild.wrn
|
||||||
|
|
||||||
|
# Visual Studio 2015
|
||||||
|
.vs/
|
16
MazeSandbox.sln
Normal file
16
MazeSandbox.sln
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MazeSandbox", "MazeSandbox\MazeSandbox.csproj", "{C38E834B-D358-49A7-AA67-50F1079F12FC}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C38E834B-D358-49A7-AA67-50F1079F12FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C38E834B-D358-49A7-AA67-50F1079F12FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C38E834B-D358-49A7-AA67-50F1079F12FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C38E834B-D358-49A7-AA67-50F1079F12FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
27
MazeSandbox/CardinalPoint.cs
Normal file
27
MazeSandbox/CardinalPoint.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TalesOfSenylan.Models.Dungeon
|
||||||
|
{
|
||||||
|
public enum CardinalPoint
|
||||||
|
{
|
||||||
|
NORTH,
|
||||||
|
SOUTH,
|
||||||
|
EAST,
|
||||||
|
WEST
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CardinalPointExtension
|
||||||
|
{
|
||||||
|
public static CardinalPoint Opposite(this CardinalPoint cardinalPoint)
|
||||||
|
{
|
||||||
|
switch (cardinalPoint)
|
||||||
|
{
|
||||||
|
case CardinalPoint.NORTH: return CardinalPoint.SOUTH;
|
||||||
|
case CardinalPoint.SOUTH: return CardinalPoint.NORTH;
|
||||||
|
case CardinalPoint.EAST: return CardinalPoint.WEST;
|
||||||
|
case CardinalPoint.WEST: return CardinalPoint.EAST;
|
||||||
|
default: throw new Exception(cardinalPoint + " doesn't have any opposite.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
MazeSandbox/MazeSandbox.csproj
Normal file
8
MazeSandbox/MazeSandbox.csproj
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
212
MazeSandbox/Program.cs
Normal file
212
MazeSandbox/Program.cs
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using Microsoft.VisualBasic.CompilerServices;
|
||||||
|
using TalesOfSenylan.Models.Dungeon;
|
||||||
|
|
||||||
|
namespace MazeSandbox
|
||||||
|
{
|
||||||
|
class Cell
|
||||||
|
{
|
||||||
|
public bool visited;
|
||||||
|
public Dictionary<CardinalPoint, Cell> exits = new Dictionary<CardinalPoint, Cell>();
|
||||||
|
public Vector2 position;
|
||||||
|
|
||||||
|
public Cell(Vector2 position)
|
||||||
|
{
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Maze
|
||||||
|
{
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private Cell startingCell;
|
||||||
|
|
||||||
|
private List<List<Cell>> cells = new List<List<Cell>>();
|
||||||
|
private static Random random = new Random();
|
||||||
|
private Stack<Cell> lastCells = new Stack<Cell>();
|
||||||
|
|
||||||
|
public Maze(int width, int height)
|
||||||
|
{
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
List<Cell> cellsRow = new List<Cell>();
|
||||||
|
for (int j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
Cell c = new Cell(new Vector2(j, i));
|
||||||
|
cellsRow.Add(c);
|
||||||
|
}
|
||||||
|
cells.Add(cellsRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
startingCell = GetRandomCell();
|
||||||
|
VisitCell(startingCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VisitCell(Cell cell)
|
||||||
|
{
|
||||||
|
if (!cell.visited)
|
||||||
|
{
|
||||||
|
lastCells.Push(cell);
|
||||||
|
}
|
||||||
|
cell.visited = true;
|
||||||
|
|
||||||
|
// Puis on regarde quelles sont les cellules voisines possibles et non visitées.
|
||||||
|
List<Cell> adjacentUnvisitedCells = GetAdjacentUnvisitedCells(cell);
|
||||||
|
if (adjacentUnvisitedCells.Count > 0)
|
||||||
|
{
|
||||||
|
// S'il y a au moins une possibilité, on en choisit une au hasard, on ouvre le mur et on recommence avec la nouvelle cellule.
|
||||||
|
Cell selectedExit = GetRandomAdjacentUnvisitedCell(cell);
|
||||||
|
|
||||||
|
CardinalPoint cp = GetExitFromCell(cell, selectedExit);
|
||||||
|
|
||||||
|
cell.exits.Remove(cp);
|
||||||
|
cell.exits.Add(cp, selectedExit);
|
||||||
|
|
||||||
|
selectedExit.exits.Remove(cp.Opposite());
|
||||||
|
selectedExit.exits.Add(cp.Opposite(), cell);
|
||||||
|
|
||||||
|
VisitCell(selectedExit);
|
||||||
|
}
|
||||||
|
// Lorsque l'on est revenu à la case de départ et qu'il n'y a plus de possibilités, le labyrinthe est terminé.
|
||||||
|
else if (lastCells.Count > 0 && startingCell.Equals(lastCells.Peek()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// S'il n'y en pas, on revient à la case précédente et on recommence.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lastCells.Count > 0)
|
||||||
|
{
|
||||||
|
lastCells.Pop();
|
||||||
|
VisitCell(lastCells.Peek());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CardinalPoint GetExitFromCell(Cell startingCell, Cell targetCell)
|
||||||
|
{
|
||||||
|
if (startingCell.position.X.Equals(targetCell.position.X))
|
||||||
|
{
|
||||||
|
if (startingCell.position.Y - targetCell.position.Y == 1)
|
||||||
|
{
|
||||||
|
return CardinalPoint.NORTH;
|
||||||
|
}
|
||||||
|
if (startingCell.position.Y - targetCell.position.Y == -1)
|
||||||
|
{
|
||||||
|
return CardinalPoint.SOUTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (startingCell.position.Y.Equals(targetCell.position.Y))
|
||||||
|
{
|
||||||
|
if (startingCell.position.X - targetCell.position.X == 1)
|
||||||
|
{
|
||||||
|
return CardinalPoint.WEST;
|
||||||
|
}
|
||||||
|
if (startingCell.position.X - targetCell.position.X == -1)
|
||||||
|
{
|
||||||
|
return CardinalPoint.EAST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CardinalPoint.NORTH; // This means there is an error (potential TODO)
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cell GetRandomAdjacentUnvisitedCell(Cell cell)
|
||||||
|
{
|
||||||
|
List<Cell> adjacentUnvisitedCells = GetAdjacentUnvisitedCells(cell);
|
||||||
|
return adjacentUnvisitedCells[random.Next(adjacentUnvisitedCells.Count)];
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Cell> GetAdjacentUnvisitedCells(Cell cell)
|
||||||
|
{
|
||||||
|
List<Cell> adjacentUnvisitedCells = new List<Cell>();
|
||||||
|
|
||||||
|
List<Cell> adjacentCells = GetAdjacentCellsOfCell(cell);
|
||||||
|
foreach (Cell adjacentCell in adjacentCells)
|
||||||
|
{
|
||||||
|
if (!adjacentCell.visited)
|
||||||
|
{
|
||||||
|
adjacentUnvisitedCells.Add(adjacentCell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjacentUnvisitedCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cell GetRandomCell()
|
||||||
|
{
|
||||||
|
int randomX = random.Next(width);
|
||||||
|
int randomY = random.Next(height);
|
||||||
|
|
||||||
|
return cells[randomX][randomY];
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Cell> GetAdjacentCellsOfCell(Cell cell)
|
||||||
|
{
|
||||||
|
List<Cell> adjacentCells = new List<Cell>();
|
||||||
|
|
||||||
|
foreach (List<Cell> cellsRow in cells)
|
||||||
|
{
|
||||||
|
foreach (Cell c in cellsRow)
|
||||||
|
{
|
||||||
|
if (IsAdjacent(c, cell))
|
||||||
|
{
|
||||||
|
adjacentCells.Add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjacentCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAdjacent(Cell c1, Cell c2)
|
||||||
|
{
|
||||||
|
if (AreOnDifferentColumnsAndRows(c1, c2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsAdjacentX(c1, c2) || IsAdjacentY(c1, c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAdjacentX(Cell c1, Cell c2)
|
||||||
|
{
|
||||||
|
if (c1.position.X + 1 == c2.position.X || c1.position.X - 1 == c2.position.X)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAdjacentY(Cell c1, Cell c2)
|
||||||
|
{
|
||||||
|
if (c1.position.Y + 1 == c2.position.Y || c1.position.Y - 1 == c2.position.Y)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool AreOnDifferentColumnsAndRows(Cell c1, Cell c2)
|
||||||
|
{
|
||||||
|
return c1.position.X != c2.position.X && c1.position.Y != c2.position.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Maze m = new Maze(3, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user