using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; class AI { private Vector2 tractorPos; private Vector2 housePos; private Farm farm; private Vector2 Size; private Vector2 targetPos; private Inventory inventory = new Inventory(); private FertilizerHolder fertilizerHolder = new FertilizerHolder(); private int Rotation; private Astar astar = new Astar(); private Random r = new Random(); public void init() { inventory.initInventorySystem(); } public void update(Farm newFarm, Vector2 newSize, Vector2 newTractorPos, Vector2 newHousePos, Vector2 newtargetPos, int rotation) { tractorPos = new Vector2((int)newTractorPos.X, (int)newTractorPos.Y); housePos = new Vector2((int)newHousePos.X, (int)newHousePos.Y); targetPos = newtargetPos; farm = newFarm; Size = newSize; Rotation = rotation; astar.update(farm.getCrops(), Size, tractorPos, housePos, rotation); } public void drawInventory(Input input, SpriteBatch spriteBatch, SpriteFont Bold, Cargo itemStorageDefined) { inventory.printItems(input, spriteBatch, Bold); } public Path newTarget() { PriorityQueueC5 queue = new PriorityQueueC5(); int score = 0; int count = 0; int testsize = 2; Path newTarget; if (tractorPos != housePos) if (inventory.getWeight() == inventory.getMaxWeight() || inventory.isMissingFertilizer()) { astar.update(farm.getCrops(), Size, tractorPos, housePos, housePos, Rotation); return astar.FindPath(true); } while (true) { for (int x = 0; x < Size.X; x++) for (int y = 0; y < Size.Y; y++) { 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())) { //do nothing } else { score = calculateSoilScore(x, y); queue.AddToQueue(x, y, score); if (farm.getCrop(x, y).getCropTimer() == 1 || farm.getCrop(x, y).getStatus() == 2) count++; } } } if (count > 0) break; else //if (tractorPos != housePos) return newTarget = GetMaxFNode(testsize, queue); } newTarget = GetMinFNode(Math.Min(testsize, count), queue); queue = null; return newTarget; } public Farm changeCropStatus() { int x = (int)tractorPos.X; int y = (int)tractorPos.Y; Fertilizer fertilizer = new Fertilizer(); fertilizerHolder.init(); 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)) { farm.getCrop(x, y).Fertilize(fertilizer); fertilizer = fertilizerHolder.GetFertilizer(Engine.PredictFertilizer(farm.getCrop(x, y), farm.getPresetCropTypes(farm.getCrop(x, y).getCropType()))); //System.Threading.Thread.Sleep(5); } } if (farm.getCrop(x, y).getCropTimer() == 1) { farm.setCropStatus(tractorPos.X, tractorPos.Y); if (farm.getCrop(x, y).getStatus() == 2) { inventory.addItem(farm.getCrop(x, y).getCropType() - 1, 1); } } return farm; } public Inventory getInventory() { return inventory; } private int calculateSoilScore(int x, int y) { int score = 0; int statusScore = 0; int timerScore = 0; int saturationScore = 0; 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); if (!crop.isSaturated(2)) saturationScore = 5; else { saturationScore = -100; } return score + (-aproxDistance * 5) + statusScore + timerScore + saturationScore; } private float norm(float min, float max, float val) { return ((val - min) / (max - min)); } public Path GetMinFNode(int testSize, PriorityQueueC5 queue) { int index = 0; int min = 9999; Path path = new Path(); List entryList = new List(); Path[] pathList = new Path[testSize]; for (int i = 0; i < testSize; i++) { entryList.Add(queue.DeleteMax()); } for (int i = 0; i < testSize; i++) { Nodes temp = new Nodes(entryList[i].Coordinates); astar.update(farm.getCrops(), Size, tractorPos, housePos, temp.getCords(), Rotation); path = astar.FindPath(false); pathList[i] = path; Nodes tempF = new Nodes(path.getByIndex(0)); if (min > tempF.getF()) { min = tempF.getF(); index = i; } } return pathList[index].FlipArray(); } public Path GetMaxFNode(int testSize, PriorityQueueC5 queue) { int index = 0; int max = -9999; Path path = new Path(); List entryList = new List(); Path[] pathList = new Path[testSize]; for (int i = 0; i < testSize; i++) { entryList.Add(queue.DeleteMax()); } for (int i = 0; i < testSize; i++) { Nodes temp = new Nodes(entryList[i].Coordinates); astar.update(farm.getCrops(), Size, tractorPos, housePos, temp.getCords(), Rotation); path = astar.FindPath(false); pathList[i] = path; Nodes tempF = new Nodes(path.getByIndex(0)); if (max < tempF.getF()) { max = tempF.getF(); index = i; } } return pathList[index].FlipArray(); } public void reloadCargo() { inventory.clearInventory(); inventory.fillWithFertilizer(); } }