Now radar feature uses BFS algorithm | Bug fix

master
shoaib11120 2022-01-24 14:05:00 +05:30
parent eb61d2d109
commit daabcb53fa
1 changed files with 65 additions and 22 deletions

View File

@ -2,11 +2,14 @@
using StardewValley; using StardewValley;
using StardewValley.Objects; using StardewValley.Objects;
using StardewValley.TerrainFeatures; using StardewValley.TerrainFeatures;
using System.Diagnostics;
namespace stardew_access.Game namespace stardew_access.Game
{ {
// Custom enum for category /// <summary>
/// This is a custom enum class and contains the name of groups the objects are divided into for the feature
/// </summary>
public class CATEGORY public class CATEGORY
{ {
private string _typeKeyWord; private string _typeKeyWord;
@ -32,8 +35,8 @@ namespace stardew_access.Game
public static CATEGORY Buildings = new CATEGORY("building"); public static CATEGORY Buildings = new CATEGORY("building");
public static CATEGORY MineItems = new CATEGORY("mine item"); public static CATEGORY MineItems = new CATEGORY("mine item");
public static CATEGORY Chests = new CATEGORY("chest"); public static CATEGORY Chests = new CATEGORY("chest");
public static CATEGORY WaterTiles = new CATEGORY("water");
public static CATEGORY Others = new CATEGORY("other"); public static CATEGORY Others = new CATEGORY("other");
public static CATEGORY WaterTiles = new CATEGORY("water");
} }
@ -90,6 +93,9 @@ namespace stardew_access.Game
public async void Run() public async void Run()
{ {
Stopwatch sw = new Stopwatch();
sw.Start();
if(MainClass.radarDebug) if(MainClass.radarDebug)
MainClass.monitor.Log($"\n\nRead Tile started", StardewModdingAPI.LogLevel.Debug); MainClass.monitor.Log($"\n\nRead Tile started", StardewModdingAPI.LogLevel.Debug);
@ -99,36 +105,73 @@ namespace stardew_access.Game
closed.Clear(); closed.Clear();
furnitures.Clear(); furnitures.Clear();
npcs.Clear(); npcs.Clear();
FindTile(currPosition, currPosition, range);
BFS(currPosition, range);
if(MainClass.radarDebug) if(MainClass.radarDebug)
MainClass.monitor.Log($"\nRead Tile stopped\n\n", StardewModdingAPI.LogLevel.Debug); MainClass.monitor.Log($"\nRead Tile stopped\n\n", StardewModdingAPI.LogLevel.Debug);
sw.Stop();
MainClass.monitor.Log($"Time:{sw.ElapsedMilliseconds}ms", StardewModdingAPI.LogLevel.Debug);
await Task.Delay(delay); await Task.Delay(delay);
isRunning = false; isRunning = false;
} }
public void FindTile(Vector2 position, Vector2 center, int limit) /// <summary>
/// Search the area using Breadth First Search algorithm(BFS).
/// </summary>
/// <param name="center">The starting point.</param>
/// <param name="limit">The limiting factor or simply radius of the search area.</param>
public void BFS(Vector2 center, int limit)
{ {
if (Math.Abs(position.X - center.X) > limit) Queue<Vector2> toSearch = new Queue<Vector2>();
return; List<Vector2> searched = new List<Vector2>();
if (Math.Abs(position.Y - center.Y) > limit) int []dirX = { -1, 0, 1, 0 };
return; int []dirY = { 0, 1, 0, -1 };
if (closed.Contains(position)) int count = 0;
return;
closed.Add(position); toSearch.Enqueue(center);
CheckTile(position); searched.Add(center);
Vector2 northPosition = new(position.X, position.Y-1); while (toSearch.Count > 0)
Vector2 eastPosition = new(position.X+1, position.Y); {
Vector2 westPosition = new(position.X-1, position.Y); Vector2 item = toSearch.Dequeue();
Vector2 southPosition = new(position.X, position.Y+1); CheckTile(item);
count++;
FindTile(northPosition, center, limit); for(int i = 0; i < 4; i++)
FindTile(eastPosition, center, limit); {
FindTile(westPosition, center, limit); Vector2 dir = new Vector2(item.X+dirX[i], item.Y+dirY[i]);
FindTile(southPosition, center, limit);
if (isValid(dir, center, searched, limit))
{
toSearch.Enqueue(dir);
searched.Add(dir);
}
}
}
}
/// <summary>
/// Checks if the provided tile position is within the range/radius and whether the tile has already been checked or not.
/// </summary>
/// <param name="item">The position of the tile to be searched.</param>
/// <param name="center">The starting point of the search.</param>
/// <param name="searched">The list of searched items.</param>
/// <param name="limit">The radius of search</param>
/// <returns></returns>
public bool isValid(Vector2 item, Vector2 center, List<Vector2> searched, int limit)
{
if (Math.Abs(item.X - center.X) > limit)
return false;
if (Math.Abs(item.Y - center.Y) > limit)
return false;
if(searched.Contains(item))
return false;
return true;
} }
public void CheckTile(Vector2 position) public void CheckTile(Vector2 position)
@ -285,10 +328,10 @@ namespace stardew_access.Game
if (CurrentPlayer.getNextTile().Equals(position)) if (CurrentPlayer.getNextTile().Equals(position))
return; return;
if (!radarFocus && (exclusions.Contains(category.ToString()) || exclusions.Contains(searchQuery.ToLower().Trim()))) if (!radarFocus && (exclusions.Contains(category.ToString().ToLower().Trim()) || exclusions.Contains(searchQuery.ToLower().Trim())))
return; return;
if (radarFocus && !(focus.Contains(category.ToString())) || focus.Contains(searchQuery.ToLower().Trim())) if (radarFocus && !(focus.Contains(category.ToString().ToLower().Trim()) || focus.Contains(searchQuery.ToLower().Trim())) )
return; return;
if (MainClass.radarDebug) if (MainClass.radarDebug)