diff --git a/Game1/Sources/Crops/Crops.cs b/Game1/Sources/Crops/Crops.cs index a3560b1..97132da 100644 --- a/Game1/Sources/Crops/Crops.cs +++ b/Game1/Sources/Crops/Crops.cs @@ -285,7 +285,7 @@ class Crops overhead = 0.0f; } - r = (1.0f - productionRate) * 2; + r = (1.0f - productionRate) * 4; g = 0.0f + productionRate; b = 0.0f + (float)Math.Pow((double)overhead * 10, 2); a = 255; @@ -314,6 +314,11 @@ class Crops return ProductionRate; } + public float getProductionRate() + { + return ProductionRate; + } + public float compareToDatset(float i, float j) { if (i < j) diff --git a/Game1/Sources/Crops/Farm.cs b/Game1/Sources/Crops/Farm.cs index b04c28c..7c4ab53 100644 --- a/Game1/Sources/Crops/Farm.cs +++ b/Game1/Sources/Crops/Farm.cs @@ -12,6 +12,7 @@ class Farm private Random r; private CropTypesHolder PresetCrops = new CropTypesHolder(); private int Update; + private Astar astar = new Astar(); //initializes the crops @@ -41,6 +42,24 @@ class Farm crops[i, j].init(); } } + int dirtCount = 0; + for (int i = 0; i < 99; i++) + { + for (int j = 0; j < 99; j++) + { + if (crops[i, j].getStatus() == 2) + { + dirtCount++; + if (!astar.isReachable(crops, new Vector2((int)i, (int)j), housepos)) + { + crops[i, j].setStatus(1); + dirtCount--; + } + } + } + } + if (dirtCount == 0) + init(Size, housepos); } public void updateFarm(Vector2 Size) diff --git a/Game1/Sources/ML/MLModel.cs b/Game1/Sources/ML/MLModel.cs index a6aebe2..7a1870a 100644 --- a/Game1/Sources/ML/MLModel.cs +++ b/Game1/Sources/ML/MLModel.cs @@ -11,12 +11,12 @@ using Microsoft.ML.Trainers.LightGbm; class MLModel { private static MLContext mlContext = new MLContext(seed: 1); - private static string path = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/Fertilizer_Prediction.csv"; - private static string modelpath = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/MLmodel"; - private static string report = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/report"; - private static string pathBig = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/BigFertPredict.csv"; - private static string modelpathBig = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/MLmodelBig"; - private static string reportBig = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/report_BigModel"; + private static string path = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/Fertilizer_Prediction.csv"; + private static string modelpath = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/MLmodel"; + private static string report = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/report"; + private static string pathBig = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/BigFertPredict.csv"; + private static string modelpathBig = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/MLmodelBig"; + private static string reportBig = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/report_BigModel"; // Loading data, creatin and saving ML model for smaller dataset (100) public static void CreateModel() diff --git a/Game1/Sources/Pathing/A-Star/Astar.cs b/Game1/Sources/Pathing/A-Star/Astar.cs index 2e0ec31..357f39c 100644 --- a/Game1/Sources/Pathing/A-Star/Astar.cs +++ b/Game1/Sources/Pathing/A-Star/Astar.cs @@ -42,9 +42,9 @@ class Astar var adjacentNodes = new List() { - new Nodes(new Vector2(currentPos.X, currentPos.Y+1), 0), + new Nodes(new Vector2(currentPos.X, currentPos.Y - 1), 0), new Nodes(new Vector2(currentPos.X + 1, currentPos.Y), 1), - new Nodes(new Vector2(currentPos.X, currentPos.Y - 1), 2), + new Nodes(new Vector2(currentPos.X, currentPos.Y + 1), 2), new Nodes(new Vector2(currentPos.X - 1, currentPos.Y), -1), }; @@ -163,4 +163,65 @@ class Astar return path; } + public bool isReachable(Crops[,] crops, Vector2 targetPos, Vector2 start) + { + Rotation = 0; + int g = 0; + int direction = ConvertRotation(); + Path path = new Path(); + MinHeap openList = new MinHeap(); + MinHeap closedList = new MinHeap(); + Nodes target = new Nodes(targetPos); + Nodes startPos = new Nodes(tractorPos, direction); + Nodes current = null; + + openList.Insert(startPos); + + while (openList.GetSize() > 0) + { + current = openList.getMin(); + closedList.Insert(current); + openList.removeMin(); + direction = current.getDirection(); + + if (current.getCords() == target.getCords()) + break; + + var adjacentNodes = GetAdjacentNodes(current.getCords()); + foreach (var adjacentNode in adjacentNodes) + { + if (closedList.Exists(adjacentNode.getCords())) // check if adjacent node is on closed list, if it is, skip it + continue; + g = current.getG() + crops[(int)adjacentNode.getCords().X, (int)adjacentNode.getCords().Y].getCostOnMovement() + CalculateRotationCost(direction, adjacentNode.getDirection()); // calculate g - cost from start point + if (!(openList.Exists(adjacentNode.getCords()))) // if adjacent node is not on open list, add it + { + adjacentNode.setG(g); + adjacentNode.setH(ComputeHScore(adjacentNode.getCords(), target.getCords())); + adjacentNode.calculateF(); + adjacentNode.setParent(current); + openList.Insert(adjacentNode); + } + else + { + if (g + adjacentNode.getH() < adjacentNode.getF()) // check if adjacent node is a better path than the current one + { + adjacentNode.setG(g); + adjacentNode.calculateF(); + adjacentNode.setParent(current); + } + } + + } + } + + openList.deleteHeap(); + closedList.deleteHeap(); + + if (current.getCords() != targetPos) + return false; + else + return true; + } + + } \ No newline at end of file diff --git a/Game1/Sources/Smart/AI.cs b/Game1/Sources/Smart/AI.cs index 1910b5d..50cc358 100644 --- a/Game1/Sources/Smart/AI.cs +++ b/Game1/Sources/Smart/AI.cs @@ -54,10 +54,12 @@ class AI int testsize = 2; Path newTarget; Nodes nodes; + if (astar.GetAdjacentNodes(tractorPos).Count == 0) nodes = new Nodes(housePos); else nodes = astar.GetAdjacentNodes(tractorPos)[0]; + if (tractorPos != housePos) if (inventory.getWeight() == inventory.getMaxWeight() || inventory.isMissingFertilizer()) { @@ -71,9 +73,9 @@ class AI { if (farm.getCrop(x, y).getStatus() >= 2 && tractorPos != new Vector2(x, y)) { - if (farm.getCrop(x, y).getStatus() != 2 && (farm.getCrop(x, y).isSaturated(5) || !farm.getCrop(x, y).belowCapacity())) + if (farm.getCrop(x, y).getStatus() != 2 && (farm.getCrop(x, y).getProductionRate() > 0.99f || !farm.getCrop(x, y).belowCapacity())) { - //do nothing + //skip growing fields with high production rate } else { @@ -84,22 +86,16 @@ class AI } } } - if (count > 0) break; - else if (queue.getCount() == 0) - { - astar.update(farm.getCrops(), Size, tractorPos, housePos, nodes.getCords(), Rotation); - return newTarget = astar.FindPath(true); - } - else //if (tractorPos != housePos) - return newTarget = GetMaxFNode(Math.Min(queue.getCount(), testsize), queue); } + if (queue.getCount() == 0) { astar.update(farm.getCrops(), Size, tractorPos, housePos, nodes.getCords(), Rotation); return newTarget = astar.FindPath(true); - } - newTarget = GetMinFNode(Math.Min(testsize, count), queue); + } + + newTarget = GetMinFNode(Math.Min(testsize, queue.getCount()), queue); queue = null; return newTarget; @@ -115,12 +111,11 @@ class AI if (farm.getCrop(x, y).getStatus() >= 2) { fertilizer = fertilizerHolder.GetFertilizer(Engine.PredictFertilizer(farm.getCrop(x, y), farm.getPresetCropTypes(farm.getCrop(x, y).getCropType()))); - while (!(farm.getCrop(x, y).isSaturated()) && farm.getCrop(x, y).belowCapacity() && inventory.useItem(fertilizerHolder.GetFertilizerID(fertilizer.Name), 0)) + while (!(farm.getCrop(x, y).isSaturated(-1)) && farm.getCrop(x, y).belowCapacity() && inventory.useItem(fertilizerHolder.GetFertilizerID(fertilizer.Name), 0)) { farm.getCrop(x, y).Fertilize(fertilizer); fertilizer = fertilizerHolder.GetFertilizer(Engine.PredictFertilizer(farm.getCrop(x, y), farm.getPresetCropTypes(farm.getCrop(x, y).getCropType()))); WaitTwoFrames = true; - //System.Threading.Thread.Sleep(5); } } if (farm.getCrop(x, y).getCropTimer() == 1) @@ -142,32 +137,29 @@ class AI private int calculateSoilScore(int x, int y) { - int score = 0; - int statusScore = 0; - int timerScore = 0; - int saturationScore = 0; + int score = 1; + int statusScore = 1; + int timerScore = 1; + int saturationScore = 1; + int productionRateScore = 1; int aproxDistance = (int)(Math.Abs(x - tractorPos.X) + Math.Abs(y - tractorPos.Y)); - CropTypesHolder holder = new CropTypesHolder(); - holder.init(); Crops crop = farm.getCrop(x, y); - SoilProperties soilP = crop.getSoilProperties(); int cropType = crop.getCropType(); - CropTypes avgHold = holder.getPresetCropTypes(cropType); - - if (crop.getStatus() == 2) - statusScore = 50; - else if (crop.getStatus() == 3) - statusScore = -100; - else - statusScore = 1; if (crop.getCropTimer() == 1) timerScore = 100; - else - statusScore = 0; - score = (int)(crop.getProductionRate(avgHold) * 10); + productionRateScore = (int)(crop.getProductionRate() * 25); + score = (int)(crop.getProductionRate() * -50); + + if (crop.getStatus() == 2) + { + statusScore = 50; + productionRateScore = 0; + } + else if (crop.getStatus() == 3) + statusScore = -100; if (!crop.isSaturated(2)) saturationScore = 5;