diff --git a/.idea/.idea.RobotIntelFinal/.idea/contentModel.xml b/.idea/.idea.RobotIntelFinal/.idea/contentModel.xml
index 83db942..8bae461 100644
--- a/.idea/.idea.RobotIntelFinal/.idea/contentModel.xml
+++ b/.idea/.idea.RobotIntelFinal/.idea/contentModel.xml
@@ -7,9 +7,11 @@
+
+
@@ -34,6 +36,12 @@
+
+
+
+
+
+
@@ -49,6 +57,7 @@
+
diff --git a/.idea/.idea.RobotIntelFinal/.idea/workspace.xml b/.idea/.idea.RobotIntelFinal/.idea/workspace.xml
index 0d747c3..9ff8581 100644
--- a/.idea/.idea.RobotIntelFinal/.idea/workspace.xml
+++ b/.idea/.idea.RobotIntelFinal/.idea/workspace.xml
@@ -18,29 +18,21 @@
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
@@ -58,31 +50,56 @@
-
+
-
-
+
-
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -95,34 +112,39 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -140,7 +162,7 @@
-
+
@@ -200,7 +222,7 @@
-
+
@@ -240,33 +262,18 @@
-
- file://$PROJECT_DIR$/ConsoleApp/PathPlanners/PathPlanner.cs
- 87
-
-
-
-
-
-
-
-
-
-
-
- file://$PROJECT_DIR$/ConsoleApp/PathPlanners/PathPlanner.cs
- 85
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ConsoleApp/ConsoleApp.csproj b/ConsoleApp/ConsoleApp.csproj
index 6d8ae3b..f73aec2 100644
--- a/ConsoleApp/ConsoleApp.csproj
+++ b/ConsoleApp/ConsoleApp.csproj
@@ -22,6 +22,13 @@
PreserveNewest
+
+ PreserveNewest
+
+
+
+
+
diff --git a/ConsoleApp/CoreModule.cs b/ConsoleApp/CoreModule.cs
index e0e2585..0db5b04 100644
--- a/ConsoleApp/CoreModule.cs
+++ b/ConsoleApp/CoreModule.cs
@@ -15,6 +15,7 @@ namespace ConsoleApp
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
+ container.Register(Reuse.Singleton);
}
diff --git a/ConsoleApp/HexPlot.py b/ConsoleApp/HexPlot.py
new file mode 100644
index 0000000..a10fbe8
--- /dev/null
+++ b/ConsoleApp/HexPlot.py
@@ -0,0 +1,39 @@
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib
+
+
+if __name__ == "__main__":
+ xc = []
+ yc = []
+ xm = []
+ ym = []
+ xf = []
+ yf = []
+ with open("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/HexPath.txt") as c:
+ for line in c:
+ x, y = line.split()
+ xc.append(int(x))
+ yc.append(int(y))
+
+ with open("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/Mines.txt") as m:
+ for line in m:
+ x, y = line.split()
+ xm.append(int(x))
+ ym.append(int(y))
+
+ with open("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/HexDetectedMines.txt") as f:
+ for line in f:
+ x, y = line.split()
+ xf.append(int(x))
+ yf.append(int(y))
+ fig = plt.figure()
+ plt.plot(xc, yc)
+ plt.plot(xc, yc, 'o', label='vehicle', color='blue')
+ plt.plot(xm, ym, 'o', label='all mines', color='red')
+ plt.plot(xf, yf, 'o', label='detected mines', color='orange')
+ plt.title('Hex Simulation')
+ plt.legend(loc='lower left', fontsize='xx-small')
+
+ matplotlib.pyplot.savefig('/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/HexTest.png')
+ plt.close(fig)
\ No newline at end of file
diff --git a/ConsoleApp/ISimulationResults.cs b/ConsoleApp/ISimulationResults.cs
new file mode 100644
index 0000000..e8f930a
--- /dev/null
+++ b/ConsoleApp/ISimulationResults.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using ConsoleApp.Maps;
+using HexCore;
+
+namespace ConsoleApp
+{
+ public interface ISimulationResults
+ {
+ void WriteResults();
+ int HexTotalMoves { get; set; }
+ int HexBombsFound { get; set; }
+ int TotalBombs { get; set; }
+ List HexPath { get; set; }
+ List HexMappedBombs { get; set; }
+ List Mines { get; set; }
+ int HexClearedCells { get; set; }
+ int HexUnClearedCells { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ConsoleApp/Maps/HexMap.cs b/ConsoleApp/Maps/HexMap.cs
index bbb7b51..ffe61a4 100644
--- a/ConsoleApp/Maps/HexMap.cs
+++ b/ConsoleApp/Maps/HexMap.cs
@@ -17,6 +17,9 @@ namespace ConsoleApp.Maps
public OffsetTypes OffsetType { get; }
public MovementType DefaultMovement { get; }
+ public TerrainType ClearedTerrain { get; }
+
+ public TerrainType UnclearedTerrain { get; }
///
@@ -28,35 +31,28 @@ namespace ConsoleApp.Maps
{
//Set Offset Type for 2d -> 3d conversion
OffsetType = OffsetTypes.OddRowsRight;
- //convert to cm
- x *= 100;
- y *= 100;
-
- //calculate number of cells on x and y axis
- var xCellCount = (int)Math.Ceiling((decimal) (x) / 25);
- var yCellCount = (int)Math.Ceiling((decimal) (y) / 25);
- Height = yCellCount;
- Width = xCellCount;
+ Height = y;
+ Width = x;
- var unclearedTerrain = new TerrainType(1, "uncleared");
- var clearedTerrain = new TerrainType(2, "cleared");
+ UnclearedTerrain = new TerrainType(1, "uncleared");
+ ClearedTerrain = new TerrainType(2, "cleared");
DefaultMovement = new MovementType(1, "default");
var movementTypes = new MovementTypes(
- new ITerrainType[] { unclearedTerrain, clearedTerrain },
+ new ITerrainType[] { UnclearedTerrain, ClearedTerrain },
new Dictionary>
{
[DefaultMovement] = new Dictionary
{
- [unclearedTerrain] = 1,
- [clearedTerrain] = 2
+ [UnclearedTerrain] = 1,
+ [ClearedTerrain] = 2
}
}
);
- Graph = GraphFactory.CreateRectangularGraph(Width, Height, movementTypes, unclearedTerrain);
+ Graph = GraphFactory.CreateRectangularGraph(Width, Height, movementTypes, UnclearedTerrain);
}
-
+
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Maps/IHexMap.cs b/ConsoleApp/Maps/IHexMap.cs
index a979480..555868b 100644
--- a/ConsoleApp/Maps/IHexMap.cs
+++ b/ConsoleApp/Maps/IHexMap.cs
@@ -9,5 +9,7 @@ namespace ConsoleApp.Maps
int Width { get; }
int Height { get; }
MovementType DefaultMovement { get; }
+ public TerrainType ClearedTerrain { get; }
+ public TerrainType UnclearedTerrain { get; }
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Maps/IMapFactory.cs b/ConsoleApp/Maps/IMapFactory.cs
index 59cd0d3..b369ba3 100644
--- a/ConsoleApp/Maps/IMapFactory.cs
+++ b/ConsoleApp/Maps/IMapFactory.cs
@@ -7,7 +7,6 @@ namespace ConsoleApp.Maps
{
int Height { get; }
int Width { get; }
- int CellWidth { get; }
void GenerateMaps(int x, int y, double minePercentage);
IHexMap GetHexMap();
ISquareMap GetSquareMap();
diff --git a/ConsoleApp/Maps/IMineMap.cs b/ConsoleApp/Maps/IMineMap.cs
index b21ed22..5a13a56 100644
--- a/ConsoleApp/Maps/IMineMap.cs
+++ b/ConsoleApp/Maps/IMineMap.cs
@@ -1,7 +1,13 @@
+using System.Collections.Generic;
+
namespace ConsoleApp.Maps
{
public interface IMineMap
{
bool[,] Map { get; }
+
+ int TotalBombs { get; }
+ bool GetCell(int x, int y);
+ List PlacedMines { get; }
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Maps/MapExtensions.cs b/ConsoleApp/Maps/MapExtensions.cs
index 8a046b4..4e3e0ab 100644
--- a/ConsoleApp/Maps/MapExtensions.cs
+++ b/ConsoleApp/Maps/MapExtensions.cs
@@ -15,6 +15,5 @@ namespace ConsoleApp.Maps
}
}
}
-
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Maps/MapFactory.cs b/ConsoleApp/Maps/MapFactory.cs
index a7418dc..8d1d423 100644
--- a/ConsoleApp/Maps/MapFactory.cs
+++ b/ConsoleApp/Maps/MapFactory.cs
@@ -10,7 +10,6 @@ namespace ConsoleApp.Maps
private int _defaultWidth;
public int Height { get; protected set; }
public int Width { get; protected set; }
- public int CellWidth { get; }
@@ -22,11 +21,17 @@ namespace ConsoleApp.Maps
public void GenerateMaps(int x, int y, double minePercentage)
{
- Width = x;
- Height = y;
- _squareMap = new SquareMap(x, y);
- _hexMap = new HexMap(x, y);
- _mineMap = new MineMap(x, y, minePercentage);
+ //convert to cm
+ x *= 100;
+ y *= 100;
+ //calculate number of cells on x and y axis
+ var xCellCount = (int)Math.Ceiling((decimal) (x) / 25);
+ var yCellCount = (int)Math.Ceiling((decimal) (y) / 25);
+ Width = xCellCount;
+ Height = yCellCount;
+ _squareMap = new SquareMap(xCellCount, yCellCount);
+ _hexMap = new HexMap(xCellCount, yCellCount);
+ _mineMap = new MineMap(xCellCount, yCellCount, minePercentage);
}
public IHexMap GetHexMap() => _hexMap ?? throw new NullReferenceException("hex map not initialized");
public ISquareMap GetSquareMap() => _squareMap ?? throw new NullReferenceException("square map not initialized");
@@ -34,7 +39,6 @@ namespace ConsoleApp.Maps
public MapFactory(IVehicle vehicle)
{
- CellWidth = vehicle.Width/2;
_defaultHeight = 0;
_defaultWidth = 0;
Height = _defaultHeight;
diff --git a/ConsoleApp/Maps/MineMap.cs b/ConsoleApp/Maps/MineMap.cs
index bd2b8b1..7b0fa6d 100644
--- a/ConsoleApp/Maps/MineMap.cs
+++ b/ConsoleApp/Maps/MineMap.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using HexCore;
namespace ConsoleApp.Maps
{
@@ -9,24 +11,40 @@ namespace ConsoleApp.Maps
private int _x;
private int _y;
public bool[,] Map { get; }
+ public int TotalBombs { get; }
+ public List PlacedMines { get; }
+
public MineMap(int x, int y, double minePercentage)
{
_x = x;
_y = y;
- _mineCount = x*y*((int)minePercentage/100);
+ PlacedMines = new List();
+ _mineCount = (int)(x*y*(minePercentage/100));
+ TotalBombs = _mineCount;
Map = new bool[x, y];
Map.Fill2DArray(false);
PlaceMines();
+
}
+ public bool GetCell(int x, int y) => Map[x,y];
+
private void PlaceMines()
{
var rand = new Random();
- for (int i = 0; i < _mineCount; i++)
+ for (var i = 0; i < _mineCount; i++)
{
- var x = rand.Next(_x);
- var y = rand.Next(_y);
- Map[x, y] = true;
+ var x = rand.Next(5,_x-5);
+ var y = rand.Next(5,_y-5);
+ if (Map[x, y] == true)
+ {
+ i--;
+ }
+ else
+ {
+ Map[x, y] = true;
+ PlacedMines.Add(new Cell(x,y));
+ }
}
}
}
diff --git a/ConsoleApp/Maps/SquareMap.cs b/ConsoleApp/Maps/SquareMap.cs
index 3ad78b6..2c92e55 100644
--- a/ConsoleApp/Maps/SquareMap.cs
+++ b/ConsoleApp/Maps/SquareMap.cs
@@ -19,26 +19,21 @@ namespace ConsoleApp.Maps
///
public SquareMap(int x, int y)
{
- //convert to cm
- x *= 100;
- y *= 100;
- //calculate number of cells on x and y axis
- var xCellCount = (int)Math.Ceiling((decimal) (x) / 25);
- var yCellCount = (int)Math.Ceiling((decimal) (y) / 25);
+
//set Width and height Properties
- Width = xCellCount-1;
- Height = yCellCount-1;
+ Width = x-1;
+ Height = y-1;
//Initialize Map
- Map = new Cell[xCellCount, yCellCount];
+ Map = new Cell[x, y];
//set last cell;
StartingCell = Map[0, 0];
- for (int i = 0; i < xCellCount; i++)
+ for (int i = 0; i < x; i++)
{
- for (int j = 0; j < yCellCount; j++)
+ for (int j = 0; j < y; j++)
{
Map[i,j] = new Cell(i, j);
}
diff --git a/ConsoleApp/Output/Data.txt b/ConsoleApp/Output/Data.txt
new file mode 100644
index 0000000..a3ad04a
--- /dev/null
+++ b/ConsoleApp/Output/Data.txt
@@ -0,0 +1,7 @@
+General:
+ Total Mines: 23
+Hex:
+ Total Moves: 927
+ Bombs Found: 23
+ Cleared Cell Count: 2295
+ Uncleared Cell Count: 9
diff --git a/ConsoleApp/Output/HexDetectedMines.txt b/ConsoleApp/Output/HexDetectedMines.txt
new file mode 100644
index 0000000..e69de29
diff --git a/ConsoleApp/Output/HexPath.txt b/ConsoleApp/Output/HexPath.txt
new file mode 100644
index 0000000..032288e
--- /dev/null
+++ b/ConsoleApp/Output/HexPath.txt
@@ -0,0 +1,927 @@
+0 0
+1 0
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 0
+9 0
+10 0
+11 0
+12 0
+13 0
+14 0
+15 0
+16 0
+17 0
+18 0
+19 0
+20 0
+21 0
+22 0
+23 0
+24 0
+25 0
+26 0
+27 0
+28 0
+29 0
+30 0
+31 0
+32 0
+33 0
+34 0
+35 0
+36 0
+37 0
+38 0
+39 0
+40 0
+41 0
+42 0
+43 0
+44 0
+45 0
+46 0
+47 0
+47 1
+47 2
+47 3
+46 3
+45 3
+44 3
+43 3
+42 3
+41 3
+40 3
+39 3
+38 3
+37 3
+36 3
+35 3
+34 3
+33 3
+32 3
+31 3
+30 3
+29 3
+28 3
+27 3
+26 3
+25 3
+24 3
+23 3
+22 3
+21 3
+20 3
+19 3
+18 3
+17 3
+16 3
+15 3
+14 3
+13 3
+12 3
+11 3
+10 3
+9 3
+8 3
+7 3
+6 3
+5 3
+4 3
+3 3
+2 3
+1 3
+0 3
+1 4
+0 5
+0 6
+1 6
+2 6
+3 6
+4 6
+5 6
+6 6
+7 6
+6 5
+7 4
+8 4
+9 4
+10 4
+10 5
+11 6
+12 6
+13 6
+14 6
+15 6
+16 6
+17 6
+18 6
+19 6
+20 6
+21 6
+20 5
+21 4
+22 4
+23 4
+24 4
+24 5
+25 6
+26 6
+27 6
+28 6
+29 6
+30 6
+31 6
+32 6
+33 6
+34 6
+35 6
+36 6
+37 6
+38 6
+39 6
+40 6
+41 6
+42 6
+43 6
+44 6
+45 6
+46 6
+47 6
+47 7
+47 8
+47 9
+46 9
+45 9
+44 9
+43 9
+42 9
+41 9
+40 9
+39 9
+38 9
+37 9
+36 9
+35 9
+34 9
+33 9
+32 9
+31 9
+30 9
+29 9
+28 9
+27 9
+27 8
+26 8
+25 8
+24 9
+24 9
+24 10
+23 10
+23 11
+23 12
+22 12
+21 12
+20 12
+19 11
+19 10
+18 9
+17 9
+16 9
+15 9
+14 9
+13 9
+12 9
+12 9
+13 10
+12 11
+12 12
+13 12
+13 13
+13 14
+12 15
+12 16
+11 16
+10 16
+9 16
+8 15
+8 14
+7 13
+7 12
+6 11
+6 10
+5 9
+4 9
+3 9
+2 9
+1 9
+0 9
+1 10
+0 11
+0 12
+1 12
+2 12
+3 12
+4 12
+5 12
+6 12
+7 12
+8 12
+8 12
+7 13
+8 14
+8 15
+9 16
+10 16
+11 16
+12 16
+12 15
+13 14
+13 13
+13 12
+14 12
+15 12
+16 12
+17 12
+18 12
+19 12
+20 12
+21 12
+22 12
+22 12
+21 13
+21 14
+20 13
+19 13
+19 14
+18 15
+18 16
+18 17
+19 18
+19 19
+20 19
+21 19
+22 19
+23 18
+23 17
+23 18
+23 19
+24 19
+25 19
+26 19
+27 18
+27 17
+28 16
+28 15
+29 14
+29 13
+30 12
+31 12
+32 12
+33 12
+34 12
+35 12
+36 12
+37 12
+38 12
+39 12
+40 12
+41 12
+42 12
+43 12
+44 12
+45 12
+46 12
+47 12
+47 13
+47 14
+47 15
+46 15
+45 15
+44 15
+43 15
+42 15
+41 15
+41 14
+40 14
+39 14
+38 15
+37 15
+36 15
+35 15
+34 15
+33 15
+32 15
+31 15
+30 15
+29 15
+28 15
+27 15
+27 15
+28 16
+27 17
+27 18
+26 19
+25 19
+24 19
+23 19
+22 19
+21 19
+20 19
+19 19
+19 18
+18 17
+18 16
+18 15
+17 15
+16 15
+15 15
+14 15
+13 15
+12 15
+12 15
+12 16
+11 16
+10 16
+9 16
+8 15
+7 15
+6 15
+5 15
+4 15
+3 15
+2 15
+1 15
+0 15
+1 16
+0 17
+0 18
+1 18
+2 18
+3 18
+4 18
+5 18
+6 18
+5 17
+6 16
+7 16
+8 16
+9 16
+9 17
+10 16
+11 16
+12 16
+12 17
+13 18
+14 18
+15 18
+16 18
+17 18
+18 18
+19 18
+19 18
+19 19
+20 19
+21 19
+22 19
+23 18
+23 18
+23 19
+24 19
+25 19
+26 19
+27 18
+28 18
+29 18
+30 18
+31 18
+32 18
+33 18
+34 18
+35 18
+36 18
+37 18
+38 18
+38 18
+38 19
+39 20
+40 20
+41 20
+42 20
+42 19
+43 18
+44 18
+45 18
+46 18
+47 18
+47 19
+47 20
+47 21
+46 21
+45 21
+44 21
+43 21
+42 21
+41 21
+40 21
+39 21
+38 21
+37 21
+36 21
+36 20
+35 20
+34 20
+33 21
+32 21
+31 21
+30 21
+29 21
+28 21
+27 21
+26 21
+25 21
+24 21
+23 21
+22 21
+21 21
+20 21
+19 21
+18 21
+17 21
+16 21
+15 21
+14 21
+13 21
+12 21
+12 21
+12 22
+11 22
+10 22
+9 22
+8 22
+7 22
+6 22
+5 21
+4 21
+3 21
+2 21
+1 21
+0 21
+1 22
+0 23
+0 24
+1 24
+2 24
+3 24
+4 24
+5 24
+6 24
+7 24
+6 23
+7 22
+8 22
+9 22
+10 22
+10 23
+11 24
+12 24
+13 24
+14 24
+15 24
+16 24
+17 24
+18 24
+19 24
+20 24
+21 24
+22 24
+23 24
+24 24
+25 24
+26 24
+27 24
+28 24
+29 24
+30 24
+31 24
+32 24
+31 24
+30 25
+30 26
+30 27
+31 28
+31 29
+32 29
+33 29
+34 29
+35 28
+35 27
+36 26
+37 26
+37 25
+38 24
+39 24
+40 24
+41 24
+42 24
+43 24
+44 24
+45 24
+46 24
+47 24
+47 25
+47 26
+47 27
+46 27
+45 27
+44 27
+43 27
+42 27
+41 27
+40 27
+39 27
+38 27
+37 27
+36 27
+35 27
+35 27
+35 28
+34 29
+33 29
+32 29
+31 29
+31 28
+30 27
+29 27
+28 27
+27 27
+26 27
+25 27
+24 27
+23 27
+22 27
+21 27
+20 27
+19 27
+18 27
+17 27
+16 27
+15 27
+14 27
+13 27
+12 27
+11 27
+12 27
+13 28
+12 29
+12 30
+11 31
+10 31
+9 31
+8 31
+8 30
+7 29
+7 28
+6 27
+5 27
+4 27
+3 27
+2 27
+1 27
+0 27
+1 28
+0 29
+0 30
+1 30
+2 30
+3 30
+4 30
+5 30
+5 29
+6 29
+7 29
+8 30
+8 30
+8 31
+9 31
+10 31
+11 31
+12 30
+13 30
+14 30
+15 30
+16 30
+17 30
+18 30
+18 30
+17 31
+18 32
+18 33
+19 33
+20 33
+21 33
+22 32
+22 31
+23 30
+24 30
+25 30
+26 30
+27 30
+28 30
+29 30
+30 30
+31 30
+32 30
+33 30
+34 30
+35 30
+36 30
+37 30
+38 30
+39 30
+40 30
+41 30
+42 30
+43 30
+44 30
+45 30
+46 30
+47 30
+47 31
+47 32
+47 33
+46 33
+45 33
+44 33
+43 33
+42 33
+41 33
+40 33
+39 33
+40 32
+39 31
+38 31
+37 31
+36 31
+36 32
+35 33
+34 33
+33 33
+32 33
+31 33
+30 33
+29 33
+28 33
+27 33
+26 33
+25 33
+24 33
+23 33
+22 33
+21 33
+20 33
+19 33
+18 33
+17 33
+16 33
+15 33
+14 33
+13 33
+12 33
+11 33
+10 33
+9 33
+8 33
+8 33
+8 34
+7 35
+6 35
+5 35
+4 35
+4 34
+3 33
+2 33
+1 33
+0 33
+1 34
+0 35
+0 36
+1 36
+2 36
+3 36
+4 36
+5 36
+6 36
+7 36
+8 36
+9 36
+10 36
+11 36
+12 36
+13 36
+14 36
+15 36
+16 36
+17 36
+18 36
+18 35
+19 35
+19 34
+19 33
+20 33
+21 33
+22 33
+23 34
+23 35
+24 36
+25 36
+26 36
+27 36
+28 36
+29 36
+29 35
+30 35
+31 35
+32 36
+33 36
+34 36
+35 36
+36 36
+36 36
+36 37
+37 37
+38 37
+39 37
+40 36
+41 36
+42 36
+43 36
+44 36
+45 36
+46 36
+47 36
+47 37
+47 38
+47 39
+46 39
+45 39
+44 39
+43 39
+42 39
+41 39
+40 39
+39 39
+38 39
+38 39
+38 39
+38 40
+37 41
+37 42
+36 42
+35 42
+34 42
+33 41
+33 40
+32 39
+32 39
+32 40
+31 41
+30 41
+29 41
+28 41
+28 40
+27 39
+26 39
+25 39
+24 39
+23 39
+22 39
+21 39
+21 39
+21 40
+20 41
+19 41
+18 41
+17 41
+17 40
+16 39
+15 39
+14 39
+13 39
+12 39
+11 39
+10 39
+9 39
+8 39
+7 39
+6 39
+5 39
+4 39
+3 39
+2 39
+1 39
+0 39
+1 40
+0 41
+0 42
+1 42
+2 42
+3 42
+4 42
+5 42
+6 42
+7 42
+8 42
+9 42
+10 42
+11 42
+12 42
+13 42
+14 42
+15 42
+16 42
+17 42
+18 42
+19 42
+20 42
+21 42
+22 42
+23 42
+24 42
+25 42
+26 42
+27 42
+28 42
+29 42
+30 42
+31 42
+32 42
+33 42
+34 42
+35 42
+36 42
+37 42
+38 42
+39 42
+40 42
+41 42
+42 42
+43 42
+44 42
+45 42
+46 42
+47 42
+47 43
+47 44
+47 45
+46 45
+45 45
+44 45
+43 45
+42 45
+41 45
+40 45
+39 45
+38 45
+37 45
+36 45
+35 45
+34 45
+33 45
+32 45
+31 45
+30 45
+29 45
+28 45
+27 45
+26 45
+25 45
+24 45
+23 45
+22 45
+21 45
+20 45
+19 45
+18 45
+17 45
+16 45
+15 45
+14 45
+13 45
+12 45
+11 45
+10 45
+9 45
+8 45
+7 45
+6 45
+5 45
+4 45
+3 45
+2 45
+1 45
+0 45
diff --git a/ConsoleApp/Output/HexTest.png b/ConsoleApp/Output/HexTest.png
new file mode 100644
index 0000000..0dccbf7
Binary files /dev/null and b/ConsoleApp/Output/HexTest.png differ
diff --git a/ConsoleApp/PathPlanners/IReactivePathPlanner.cs b/ConsoleApp/PathPlanners/IReactivePathPlanner.cs
index 68375a1..404d781 100644
--- a/ConsoleApp/PathPlanners/IReactivePathPlanner.cs
+++ b/ConsoleApp/PathPlanners/IReactivePathPlanner.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using ConsoleApp.Maps;
using HexCore;
namespace ConsoleApp.PathPlanners
@@ -6,5 +7,6 @@ namespace ConsoleApp.PathPlanners
public interface IReactivePathPlanner
{
Queue ReactiveHexPath { get; }
+ void GenerateReactiveHexPath(IHexMap hexMap, Queue optimalPath, Coordinate2D vehicleCurrentHexCell);
}
}
\ No newline at end of file
diff --git a/ConsoleApp/PathPlanners/PathPlanner.cs b/ConsoleApp/PathPlanners/PathPlanner.cs
index 5f50a66..d195b27 100644
--- a/ConsoleApp/PathPlanners/PathPlanner.cs
+++ b/ConsoleApp/PathPlanners/PathPlanner.cs
@@ -55,7 +55,7 @@ namespace ConsoleApp.PathPlanners
return path;
}
-
+
public Queue GenerateOptimalHexPath(IHexMap hexMap, IVehicle vehicle)
{
var currentPostion = vehicle.CurrentHexCell;
@@ -64,55 +64,44 @@ namespace ConsoleApp.PathPlanners
var path = new List();
while (!finished)
{
+ //Heading East
if (currentHeading == GlobalDirection.East)
{
path.AddRange(hexMap.Graph.GetShortestPath(
currentPostion,
- new Coordinate2D(hexMap.Width, currentPostion.Y, hexMap.OffsetType),
+ new Coordinate2D(hexMap.Width-1, currentPostion.Y, hexMap.OffsetType),
hexMap.DefaultMovement));
- currentPostion = new Coordinate2D(hexMap.Width, currentPostion.Y, hexMap.OffsetType);
+ currentPostion = new Coordinate2D(hexMap.Width-1, currentPostion.Y, hexMap.OffsetType);
}
-
- else if(currentHeading == GlobalDirection.West)
+ //Heading West
+ else if (currentHeading == GlobalDirection.West)
{
path.AddRange(hexMap.Graph.GetShortestPath(
currentPostion,
new Coordinate2D(0, currentPostion.Y, hexMap.OffsetType),
hexMap.DefaultMovement));
currentPostion = new Coordinate2D(0, currentPostion.Y, hexMap.OffsetType);
-
+
}
- if (currentPostion.Y + vehicle.DetectorRadius * 2 > hexMap.Height)
+ //Check for finish
+ if (currentPostion.Y + (vehicle.DetectorRadius * 2) >= hexMap.Height - 1)
{
finished = true;
break;
}
- Coordinate2D tmpPosition;
- if(currentHeading == GlobalDirection.East)
- tmpPosition = new Coordinate3D(
- currentPostion.To3D().X-1,
- currentPostion.To3D().Y,
- currentPostion.To3D().Z+1).To2D(hexMap.OffsetType);
- else
- tmpPosition = new Coordinate3D(
- currentPostion.To3D().X,
- currentPostion.To3D().Y-1,
- currentPostion.To3D().Z+1).To2D(hexMap.OffsetType);
- while (hexMap.Graph.GetRange(currentPostion, vehicle.DetectorRadius*2).Contains(tmpPosition))
+ //Move Up edges of map
+ var tmpPosition = currentPostion;
+ var range = hexMap.Graph.GetRange(currentPostion, vehicle.DetectorRadius * 2);
+ for (var i = currentPostion.Y; i < currentPostion.Y + vehicle.DetectorRadius * 2; i++)
{
- if(currentHeading == GlobalDirection.East)
- tmpPosition = new Coordinate3D(
- tmpPosition.To3D().X-1,
- tmpPosition.To3D().Y,
- tmpPosition.To3D().Z+1).To2D(hexMap.OffsetType);
- else
- tmpPosition = new Coordinate3D(
- tmpPosition.To3D().X,
- tmpPosition.To3D().Y-1,
- tmpPosition.To3D().Z+1).To2D(hexMap.OffsetType);
+ var newCoord = new Coordinate2D(currentPostion.X, i, hexMap.OffsetType);
+ if (range.Contains(newCoord))
+ tmpPosition = newCoord;
+
}
+
path.AddRange(hexMap.Graph.GetShortestPath(
currentPostion,
tmpPosition,
@@ -122,9 +111,11 @@ namespace ConsoleApp.PathPlanners
currentHeading = GlobalDirection.West;
else
currentHeading = GlobalDirection.East;
-
-
+
+
+
}
+
return new Queue(path);
}
}
diff --git a/ConsoleApp/PathPlanners/ReactivePathPlanner.cs b/ConsoleApp/PathPlanners/ReactivePathPlanner.cs
index a77e9b2..258bd4d 100644
--- a/ConsoleApp/PathPlanners/ReactivePathPlanner.cs
+++ b/ConsoleApp/PathPlanners/ReactivePathPlanner.cs
@@ -1,20 +1,44 @@
using System.Collections.Generic;
+using ConsoleApp.Maps;
using HexCore;
namespace ConsoleApp.PathPlanners
{
public class ReactivePathPlanner : IReactivePathPlanner
{
- public Queue ReactiveHexPath { get; }
+ private Queue _reactiveHexPath;
+ public Queue ReactiveHexPath => _reactiveHexPath;
+
public ReactivePathPlanner()
{
- ReactiveHexPath = new Queue();
+ _reactiveHexPath = new Queue();
}
-
- public void GenerateReactiveHexPath(Graph graph, ref List optimalPath, Coordinate2D minePosition)
+ public void GenerateReactiveHexPath(IHexMap hexMap, Queue optimalPath,
+ Coordinate2D vehicleCurrentHexCell)
{
+ //Clean out any old path
+ _reactiveHexPath.Clear();
+ //If the optimal path is empty well we are done, otherwise pop 1
+ if (!optimalPath.TryDequeue(out var convergentPoint))
+ return;
+
+ //Dequeue until the cell is not blocked
+ while (hexMap.Graph.IsCellBlocked(convergentPoint))
+ {
+ //if optimal path is empty were done and we can not clear around this position, otherwise
+ //lest pop another.
+ if (!optimalPath.TryDequeue(out convergentPoint))
+ return;
+ }
+
+ var reactivePath = hexMap.Graph.GetShortestPath(vehicleCurrentHexCell, convergentPoint, hexMap.DefaultMovement);
+ foreach (var node in reactivePath)
+ {
+ _reactiveHexPath.Enqueue(node);
+ }
}
+
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Program.cs b/ConsoleApp/Program.cs
index 4cc3a51..d90d0e7 100644
--- a/ConsoleApp/Program.cs
+++ b/ConsoleApp/Program.cs
@@ -1,4 +1,8 @@
using System;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Threading;
using ConsoleApp.Maps;
namespace ConsoleApp
@@ -11,11 +15,15 @@ namespace ConsoleApp
static void Main(string[] args)
{
_bootstrapper = BootStrapper.BootstrapSystem(new CoreModule());
+ var simResults = _bootstrapper.Resolve();
_userConsole = new UserConsole();
Initialization();
+ simResults.WriteResults();
Console.WriteLine("Program Completed");
}
+
+
private static void Initialization()
{
_userConsole.PrintStartMenu();
diff --git a/ConsoleApp/Sim/DetectionHead.cs b/ConsoleApp/Sim/DetectionHead.cs
index a510d3c..f9d4c12 100644
--- a/ConsoleApp/Sim/DetectionHead.cs
+++ b/ConsoleApp/Sim/DetectionHead.cs
@@ -10,7 +10,16 @@ namespace ConsoleApp.Sim
Graph graph,
Coordinate2D centerCoordinate,
int detectorRadius,
- GlobalDirection direction) => graph.GetRange(centerCoordinate, detectorRadius);
+ int vehicleTurnRadius)
+ {
+ var detectorCells = graph.GetRange(centerCoordinate, detectorRadius);
+ // var vehicleCells = graph.GetRange(centerCoordinate, vehicleTurnRadius);
+ // foreach (var vehicleCell in vehicleCells)
+ // {
+ // detectorCells.Remove(vehicleCell);
+ // }
+ return detectorCells;
+ }
public static List GetCoveredCells(
ISquareMap squareMap,
diff --git a/ConsoleApp/Sim/IVehicle.cs b/ConsoleApp/Sim/IVehicle.cs
index 3db6ae0..95c1a01 100644
--- a/ConsoleApp/Sim/IVehicle.cs
+++ b/ConsoleApp/Sim/IVehicle.cs
@@ -1,4 +1,5 @@
using ConsoleApp.Maps;
+using HexCore;
namespace ConsoleApp.Sim
{
@@ -6,11 +7,9 @@ namespace ConsoleApp.Sim
{
int Length { get; }
int Width { get; }
- int DetectorOffset { get;}
+ int TurnRadius { get; }
int DetectorRadius { get;}
- HexCore.Coordinate2D CurrentHexCell { get; set; }
- Heading HexHeading { get; set; }
- Heading SquareHeading { get; set; }
+ Coordinate2D CurrentHexCell { get; set; }
ICell CurrentSquareCell { get; set; }
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Sim/Vehicle.cs b/ConsoleApp/Sim/Vehicle.cs
index e4cc62d..e1424a2 100644
--- a/ConsoleApp/Sim/Vehicle.cs
+++ b/ConsoleApp/Sim/Vehicle.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Collections.Generic;
using ConsoleApp.Maps;
namespace ConsoleApp.Sim
@@ -6,12 +8,9 @@ namespace ConsoleApp.Sim
{
public int Length { get; }
public int Width { get; }
-
- public int DetectorOffset { get;}
+ public int TurnRadius { get; }
public int DetectorRadius { get;}
public HexCore.Coordinate2D CurrentHexCell { get; set; }
- public Heading HexHeading { get; set; }
- public Heading SquareHeading { get; set; }
public ICell CurrentSquareCell { get; set; }
@@ -20,12 +19,17 @@ namespace ConsoleApp.Sim
public Vehicle(IJsonDeserializor jsonDeserializor)
{
var config = jsonDeserializor.DeserializeObject("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Sim/VehicleConfiguration.json");
- Length = config.Length;
- Width = config.Width;
- DetectorRadius = config.DetectorRadius;
- DetectorOffset = config.DetectorOffset;
- CurrentHexCell = default;
- CurrentSquareCell = default;
+ var length = config.Length;
+ length *= 100;
+ Length = (int)Math.Ceiling((decimal)length/ 25);
+ var width = config.Width;
+ width *= 100;
+ Width = (int)Math.Ceiling((decimal)width/ 25);
+ DetectorRadius = (int)Math.Floor(((decimal)config.DetectorRadius * 100)/25)/2;
+ TurnRadius = (int)Math.Ceiling(Math.Sqrt(Math.Pow(config.Length, 2) * Math.Pow(config.Width, 2))/2);
+ // if (DetectorRadius <= TurnRadius)
+ // throw new ArgumentException("Detection radius must be larger than the vehicle turn radius");
+
}
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Sim/VehicleConfiguration.cs b/ConsoleApp/Sim/VehicleConfiguration.cs
index 74c2b50..91b47a0 100644
--- a/ConsoleApp/Sim/VehicleConfiguration.cs
+++ b/ConsoleApp/Sim/VehicleConfiguration.cs
@@ -5,6 +5,5 @@ namespace ConsoleApp.Sim
public int Length { get; set; }
public int Width { get; set; }
public int DetectorRadius { get; set; }
- public int DetectorOffset { get; set; }
}
}
\ No newline at end of file
diff --git a/ConsoleApp/Sim/VehicleConfiguration.json b/ConsoleApp/Sim/VehicleConfiguration.json
index adb580b..8db1cfd 100644
--- a/ConsoleApp/Sim/VehicleConfiguration.json
+++ b/ConsoleApp/Sim/VehicleConfiguration.json
@@ -1,6 +1,5 @@
{
- "Length": 3,
- "Width": 2,
- "DetectorRadius": 3,
- "DetectorOffset": 2
-}
\ No newline at end of file
+ "Length": 1,
+ "Width": 1,
+ "DetectorRadius": 1
+}
diff --git a/ConsoleApp/SimRunner.cs b/ConsoleApp/SimRunner.cs
index be04c2d..66a089d 100644
--- a/ConsoleApp/SimRunner.cs
+++ b/ConsoleApp/SimRunner.cs
@@ -1,11 +1,16 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
using System.Threading;
using System.Threading.Tasks;
using ConsoleApp.Maps;
using ConsoleApp.PathPlanners;
using ConsoleApp.Sim;
using HexCore;
+using ImTools;
+using Microsoft.VisualBasic;
namespace ConsoleApp
{
@@ -14,25 +19,28 @@ namespace ConsoleApp
private IMapFactory _mapFactory;
private IVehicle _vehicle;
- private int _cellWidth;
private IPathPlanner _pathPlanner;
private IMineMap _mineMap;
private IReactivePathPlanner _reactivePathPlanner;
+ private HashSet hexBombsFound = new HashSet();
+ private List testingPath = new List();
+ private ISimulationResults _simulationResults;
- public SimRunner(IMapFactory mapFactory, IVehicle vehicle, IPathPlanner pathPlanner, IReactivePathPlanner reactivePathPlanner)
+ public SimRunner(IMapFactory mapFactory, IVehicle vehicle, IPathPlanner pathPlanner, IReactivePathPlanner reactivePathPlanner, ISimulationResults simulationResults)
{
-
- _cellWidth = mapFactory.CellWidth;
_mapFactory = mapFactory;
_vehicle = vehicle;
_pathPlanner = pathPlanner;
_reactivePathPlanner = reactivePathPlanner;
+ _simulationResults = simulationResults;
}
public void Run()
{
_mineMap = _mapFactory.GetMineMap();
+ _simulationResults.Mines = _mineMap.PlacedMines;
+ _simulationResults.TotalBombs = _mineMap.TotalBombs;
SquareSimulation();
HexSimulation();
// while(!squareTask.IsCompleted && !hexTask.IsCompleted){Thread.Sleep(500);}
@@ -44,9 +52,92 @@ namespace ConsoleApp
var hexMap = _mapFactory.GetHexMap();
_vehicle.CurrentHexCell = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight);
var optimalPath = _pathPlanner.GenerateOptimalHexPath(hexMap, _vehicle);
- var reactivePath = _reactivePathPlanner.ReactiveHexPath;
+ var finished = false;
+ var totalMoves = 0;
+ while (!finished)
+ {
+ totalMoves += 1;
+ _simulationResults.HexPath.Add(_vehicle.CurrentHexCell);
+
+ var detectionCells = DetectionHead.GetCoveredCells(hexMap.Graph, _vehicle.CurrentHexCell, _vehicle.DetectorRadius, _vehicle.TurnRadius);
+ //Check Cells for mine
+ var detection = CheckCells(detectionCells);
+ //mark as cleared
+ hexMap.Graph.SetCellsTerrainType(detectionCells, hexMap.ClearedTerrain);
+ //Handle any detections
+ if (detection)
+ {
+ _reactivePathPlanner.GenerateReactiveHexPath(hexMap, optimalPath, _vehicle.CurrentHexCell);
+ }
+
+ //If the reactive Planner is not empty, empty it before the optimal.
+ if (_reactivePathPlanner.ReactiveHexPath.TryDequeue(out var next))
+ _vehicle.CurrentHexCell = next;
+ //Else we will work off of the optimal path
+ else
+ {
+ //If the optimal path is empty we are done otherwise pop.
+ if (!optimalPath.TryDequeue(out var nextOptimal))
+ {
+ finished = true;
+ break;
+ }
+
+ if (hexMap.Graph.IsCellBlocked(nextOptimal))
+ {
+ _reactivePathPlanner.GenerateReactiveHexPath(hexMap, optimalPath, _vehicle.CurrentHexCell);
+ }
+ else
+ _vehicle.CurrentHexCell = nextOptimal;
+ }
+ }
+
+
+ //Debugging information
+ var (cleared, uncleared) = CoveredCells();
+ _simulationResults.HexClearedCells = cleared;
+ _simulationResults.HexUnClearedCells = uncleared;
+ _simulationResults.HexTotalMoves = totalMoves;
+ _simulationResults.HexBombsFound = hexBombsFound.Count;
}
-
+
+ private (int, int) CoveredCells()
+ {
+ var cleared = 0;
+ var uncleared = 0;
+ var hexMap = _mapFactory.GetHexMap();
+ foreach (var cellState in hexMap.Graph.GetAllCells())
+ {
+ if (cellState.TerrainType.Id == hexMap.ClearedTerrain.Id)
+ cleared++;
+ if (cellState.TerrainType.Id == hexMap.UnclearedTerrain.Id)
+ uncleared++;
+ }
+
+ return (cleared, uncleared);
+ }
+
+
+ private bool CheckCells(List detectionCells)
+ {
+ var found = false;
+ foreach (var cell in detectionCells.Where(cell => _mineMap.GetCell(cell.X, cell.Y)))
+ {
+ if (!hexBombsFound.Add(cell)) continue;
+ BlockCells(cell);
+ found = true;
+ }
+ return found;
+ }
+
+ private void BlockCells(Coordinate2D cell)
+ {
+ var hexMap = _mapFactory.GetHexMap();
+ var cellsToBlock = hexMap.Graph.GetRange(cell, _vehicle.Width / 2);
+ hexMap.Graph.BlockCells(cellsToBlock);
+
+ }
+
private void SquareSimulation()
{
diff --git a/ConsoleApp/SimulationResults.cs b/ConsoleApp/SimulationResults.cs
new file mode 100644
index 0000000..c2a2ca8
--- /dev/null
+++ b/ConsoleApp/SimulationResults.cs
@@ -0,0 +1,104 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using ConsoleApp.Maps;
+using HexCore;
+
+namespace ConsoleApp
+{
+ public class SimulationResults : ISimulationResults
+ {
+ public int HexTotalMoves { get; set; }
+ public int HexBombsFound { get; set; }
+ public int TotalBombs { get; set; }
+ public List HexPath { get; set; }
+ public List HexMappedBombs { get; set; }
+ public List Mines { get; set; }
+ public int HexClearedCells { get; set; }
+ public int HexUnClearedCells { get; set; }
+
+ public SimulationResults()
+ {
+ HexTotalMoves = 0;
+ HexBombsFound = 0;
+ TotalBombs = 0;
+ HexPath = new List();
+ HexMappedBombs = new List();
+ Mines = new List| ();
+ HexClearedCells = 0;
+ HexUnClearedCells = 0;
+ }
+
+ public void WriteResults()
+ {
+ WriteData();
+ WriteMines();
+ WritePaths();
+ WriteDetectedMines();
+ GenerateImages();
+ }
+
+ private static void GenerateImages()
+ {
+ var file = Path.Combine("./",Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"HexPlot.py");
+ ProcessStartInfo startInfo = new ProcessStartInfo()
+ {
+ FileName = "python3",
+ Arguments = file,
+ UseShellExecute = true
+ };
+ Process proc = new Process()
+ {
+ StartInfo = startInfo,
+ };
+ proc.Start();
+ while (!proc.HasExited)
+ {
+ Thread.Sleep(500);
+ }
+ }
+
+ private void WriteData()
+ {
+ using(TextWriter tw = new StreamWriter("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/Data.txt"))
+ {
+ tw.WriteLine($"General:");
+ tw.WriteLine($"\t Total Mines: {TotalBombs}");
+ tw.WriteLine($"Hex: ");
+ tw.WriteLine($"\t Total Moves: {HexTotalMoves}");
+ tw.WriteLine($"\t Bombs Found: {HexBombsFound}");
+ tw.WriteLine($"\t Cleared Cell Count: {HexClearedCells}");
+ tw.WriteLine($"\t Uncleared Cell Count: {HexUnClearedCells}");
+ }
+ }
+
+ private void WriteMines()
+ {
+ using(TextWriter tw = new StreamWriter("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/Mines.txt"))
+ {
+ foreach (var s in Mines)
+ tw.WriteLine($"{s.X} {s.Y}");
+ }
+ }
+
+ private void WriteDetectedMines()
+ {
+ using(TextWriter tw = new StreamWriter("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/HexDetectedMines.txt"))
+ {
+ foreach (Coordinate2D s in HexMappedBombs)
+ tw.WriteLine($"{s.X} {s.Y}");
+ }
+ }
+
+ private void WritePaths()
+ {
+ using(TextWriter tw = new StreamWriter("/Users/brady.bodily/Documents/Repositories/CS5890_Robot_Intelligence/RobotIntelFinal/ConsoleApp/Output/HexPath.txt"))
+ {
+ foreach (Coordinate2D s in HexPath)
+ tw.WriteLine($"{s.X} {s.Y}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ConsoleApp/UserConsole.cs b/ConsoleApp/UserConsole.cs
index f59b44e..1eae039 100644
--- a/ConsoleApp/UserConsole.cs
+++ b/ConsoleApp/UserConsole.cs
@@ -22,9 +22,9 @@ namespace ConsoleApp
public static void PrintInvalidInput() => Console.WriteLine($"Invalid input try again \n");
- public (int width, int height) GetMapDimensions()
+ public (int width, int height) GetMapDimensions()
{
- Console.WriteLine($"Enter map height: ");
+ Console.WriteLine($"Enter map width: ");
var x = GetUserInput();
if (!int.TryParse(x, out var width))
| | | | | | |