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 int Rotation; private PriorityQueueC5 PriorityQueueC5; private Astar astar = new Astar(); private Random r = new Random(); public void init() { inventory.initInventorySystem(); inventory.addItem(1, 1); inventory.addItem(1, 1); inventory.addItem(3, 1); inventory.addItem(5, 1); inventory.addItem(7, 1); inventory.addItem(7, 1); inventory.addItem(10, 1); inventory.addItem(10, 1); inventory.useItem(10, 1); } 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 Vector2 newTarget() { PriorityQueueC5 queue = new PriorityQueueC5(); int score = 0; int count = 0; int testsize = 2; Vector2 newTarget; 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() == 3 && farm.getCrop(x, y).getCropTimer() != 1) { if (housePos == tractorPos) { score = calculateSoilScore(x, y); queue.AddToQueue(x, y, score); count++; } //do nothing } else { score = calculateSoilScore(x, y); queue.AddToQueue(x, y, score); count++; } } } if (count > 0) break; else if (tractorPos != housePos) return housePos; /* else if (tractorPos == housePos) { List temp = astar.GetAdjacentNodes(tractorPos); return temp[0].getCords(); } */ } newTarget = GetMinFNode(Math.Min(testsize, count), queue); return newTarget; } public Farm changeCropStatus() { if (farm.getCrop((int)tractorPos.X, (int)tractorPos.Y).getCropTimer() == 1) { farm.setCropStatus(tractorPos.X, tractorPos.Y); } return farm; } public Inventory getInventory() { return inventory; } private int calculateSoilScore(int x, int y) { int score = 0; int statusScore = 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 = 25; else if (crop.getStatus() == 3) statusScore = 5; else if (crop.getStatus() == 4) statusScore = -10; else statusScore = 1; float[] currentValue = { soilP.Temperature, soilP.Humidity, soilP.Moisture, soilP.Nitrogen, soilP.Potassium, soilP.Phosphorous }; float[] targetAvg = { avgHold.Temparature, avgHold.Humidity, avgHold.Moisture, avgHold.Nitrogen, avgHold.Potassium, avgHold.Phosphorous }; float[,] minMax = { {22,30}, {22*1.9f, 30*2.1f}, {20, 70}, {4, 55}, {0, 28}, {0, 60} }; //probably should make it dynamic float[] normVal = normArray(minMax, currentValue); float[] normAvg = normArray(minMax, targetAvg); for (int i = 0; i < normVal.Count(); i++) { score = score + (int)Math.Round(System.Convert.ToDouble(10*(1 - Math.Abs(normAvg[i] - normVal[i])))); } return score + (-aproxDistance * 3) + statusScore; } private float[] normArray(float[,] minMax, float[] values) { float[] temp = new float[values.Count()]; if (minMax.GetLength(0) != values.Count()) throw new InvalidOperationException("Values and their MinMax arrays are not of the same length!"); for (int i = 0; i < values.Count(); i++) temp[i] = norm(minMax[i, 0], minMax[i, 1], values[i]); return temp; } private float norm(float min, float max, float val) { return ((val - min) / (max - min)); } public Vector2 GetMinFNode(int testSize, PriorityQueueC5 queue) { int index = 0; int min = 999; Path path = new Path(); List entryList = new List(); 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); path = astar.FindPath(false); Nodes tempF = new Nodes(path.getByIndex(0)); if (min > tempF.getF()) { min = tempF.getF(); index = i; } } PQEntry minEntry = entryList[index]; entryList.RemoveAt(index); //add the non-minimum entries back to the queue. queue.AddAll(entryList); return minEntry.Coordinates; } }