PotatoPlan/Game1/Sources/Smart/AI.cs

238 lines
7.1 KiB
C#
Raw Normal View History

2020-05-05 16:27:45 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
2020-05-06 16:22:30 +02:00
using Microsoft.Xna.Framework.Graphics;
2020-05-05 16:27:45 +02:00
class AI
{
private Vector2 tractorPos;
private Vector2 housePos;
2020-05-06 16:22:30 +02:00
private Farm farm;
2020-05-05 16:27:45 +02:00
private Vector2 Size;
private Vector2 targetPos;
2020-05-06 16:22:30 +02:00
private Inventory inventory = new Inventory();
2020-05-10 01:38:08 +02:00
private FertilizerHolder fertilizerHolder = new FertilizerHolder();
2020-05-05 16:27:45 +02:00
private int Rotation;
2020-05-07 22:09:45 +02:00
private Astar astar = new Astar();
2020-05-05 16:27:45 +02:00
private Random r = new Random();
2020-05-06 16:22:30 +02:00
public void init()
{
inventory.initInventorySystem();
}
2020-05-05 16:27:45 +02:00
2020-05-06 16:22:30 +02:00
public void update(Farm newFarm, Vector2 newSize, Vector2 newTractorPos, Vector2 newHousePos, Vector2 newtargetPos, int rotation)
2020-05-05 16:27:45 +02:00
{
tractorPos = new Vector2((int)newTractorPos.X, (int)newTractorPos.Y);
housePos = new Vector2((int)newHousePos.X, (int)newHousePos.Y);
targetPos = newtargetPos;
2020-05-06 16:22:30 +02:00
farm = newFarm;
2020-05-05 16:27:45 +02:00
Size = newSize;
Rotation = rotation;
2020-05-07 22:09:45 +02:00
astar.update(farm.getCrops(), Size, tractorPos, housePos, rotation);
2020-05-05 16:27:45 +02:00
}
2020-05-06 16:22:30 +02:00
public void drawInventory(Input input, SpriteBatch spriteBatch, SpriteFont Bold, Cargo itemStorageDefined)
{
inventory.printItems(input, spriteBatch, Bold);
}
2020-05-05 16:27:45 +02:00
public Vector2 newTarget()
{
2020-05-07 22:09:45 +02:00
PriorityQueueC5 queue = new PriorityQueueC5();
int score = 0;
2020-05-08 00:35:53 +02:00
int count = 0;
int testsize = 2;
2020-05-07 22:09:45 +02:00
Vector2 newTarget;
2020-05-10 01:38:08 +02:00
if (tractorPos != housePos)
if (inventory.getWeight() == inventory.getMaxWeight() || inventory.isMissingFertilizer())
return housePos;
2020-05-08 00:35:53 +02:00
while (true)
{
for (int x = 0; x < Size.X; x++)
for (int y = 0; y < Size.Y; y++)
2020-05-07 22:09:45 +02:00
{
2020-05-08 00:35:53 +02:00
if (farm.getCrop(x, y).getStatus() >= 2 && tractorPos != new Vector2(x, y))
2020-05-07 22:09:45 +02:00
{
2020-05-10 01:38:08 +02:00
if (farm.getCrop(x, y).isSaturated() || !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++;
}
2020-05-07 22:09:45 +02:00
}
}
2020-05-08 00:35:53 +02:00
if (count > 0)
break;
2020-05-10 01:38:08 +02:00
else //if (tractorPos != housePos)
2020-05-09 15:54:53 +02:00
return newTarget = GetMaxFNode(testsize, queue);
2020-05-08 00:35:53 +02:00
}
newTarget = GetMinFNode(Math.Min(testsize, count), queue);
2020-05-10 01:38:08 +02:00
queue = null;
2020-05-09 15:54:53 +02:00
2020-05-07 22:09:45 +02:00
return newTarget;
2020-05-05 16:27:45 +02:00
}
2020-05-06 16:22:30 +02:00
public Farm changeCropStatus()
{
2020-05-10 01:38:08 +02:00
int x = (int)tractorPos.X;
int y = (int)tractorPos.Y;
Fertilizer fertilizer = new Fertilizer();
fertilizerHolder.init();
if (farm.getCrop(x, y).getCropTimer() == 1)
2020-05-06 16:22:30 +02:00
{
2020-05-10 01:38:08 +02:00
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())));
}
}
2020-05-06 16:22:30 +02:00
farm.setCropStatus(tractorPos.X, tractorPos.Y);
2020-05-10 01:38:08 +02:00
if (farm.getCrop(x, y).getStatus() == 2)
2020-05-09 13:48:28 +02:00
{
2020-05-10 01:38:08 +02:00
inventory.addItem(farm.getCrop(x, y).getCropType() - 1, 1);
2020-05-09 13:48:28 +02:00
}
2020-05-06 16:22:30 +02:00
}
return farm;
}
2020-05-06 20:48:20 +02:00
public Inventory getInventory()
{
return inventory;
}
2020-05-07 22:09:45 +02:00
private int calculateSoilScore(int x, int y)
{
int score = 0;
int statusScore = 0;
2020-05-09 15:54:53 +02:00
int timerScore = 0;
2020-05-10 01:38:08 +02:00
int saturationScore = 0;
2020-05-07 22:09:45 +02:00
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)
2020-05-09 15:54:53 +02:00
statusScore = -100;
2020-05-07 22:09:45 +02:00
else
statusScore = 1;
2020-05-09 15:54:53 +02:00
if (crop.getCropTimer() == 1)
timerScore = 999;
else
statusScore = 0;
2020-05-07 22:09:45 +02:00
2020-05-09 15:54:53 +02:00
score = (int)(crop.getProductionRate(avgHold) * 10);
2020-05-07 22:09:45 +02:00
2020-05-10 01:38:08 +02:00
if (!crop.isSaturated())
saturationScore = 5;
else
{
saturationScore = -100;
}
return score + (-aproxDistance * 5) + statusScore + timerScore + saturationScore;
2020-05-07 22:09:45 +02:00
}
private float norm(float min, float max, float val)
{
return ((val - min) / (max - min));
}
public Vector2 GetMinFNode(int testSize, PriorityQueueC5 queue)
{
int index = 0;
2020-05-09 15:54:53 +02:00
int min = 9999;
2020-05-07 22:09:45 +02:00
Path path = new Path();
List<PQEntry> entryList = new List<PQEntry>();
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;
}
2020-05-09 15:54:53 +02:00
public Vector2 GetMaxFNode(int testSize, PriorityQueueC5 queue)
{
int index = 0;
int max = -9999;
Path path = new Path();
List<PQEntry> entryList = new List<PQEntry>();
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 (max < tempF.getF())
{
max = 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;
}
2020-05-10 01:38:08 +02:00
public void reloadCargo()
{
inventory.clearInventory();
inventory.fillWithFertilizer();
}
2020-05-09 15:54:53 +02:00
2020-05-05 16:27:45 +02:00
}