Started readme.md, WIP commit for collecting all rewards

This commit is contained in:
Rob 2023-07-11 20:30:49 +02:00
parent 167b94e4de
commit fbded5932f
10 changed files with 237 additions and 122 deletions

View File

@ -1,5 +1,4 @@
using Bobo.System.Maze.Bot;
using Bobo.Systems.Maze.Console.Model;
using Bobo.Systems.Maze.Console.Model;
using HightechICT.Amazeing.Client.Rest;
using System.Collections.ObjectModel;
using LogConsole = System.Console;

View File

@ -0,0 +1,55 @@
using Bobo.System.Maze.Bot.Interface;
using HightechICT.Amazeing.Client.Rest;
using Microsoft.Extensions.Logging;
namespace Bobo.System.Maze.Bot
{
public class BumbBot : BaseBot
{
public BumbBot(AmazeingClient mazeClient, ILogger<BaseBot> logger) : base(mazeClient, logger)
{ }
public override async Task<int> Run(MazeInfo maze)
{
if (MazeClient == null)
throw new ArgumentException(nameof(MazeClient));
if (string.IsNullOrWhiteSpace(maze.Name))
throw new ArgumentException(nameof(maze.Name));
Random random = new Random();
Logger.Log(LogLevel.Information, "Entering maze '{MazeName}'", maze.Name);
PossibleActionsAndCurrentScore result = await MazeClient.EnterMaze(maze.Name);
do
{
// select a way to go
MoveAction[] moves = result.PossibleMoveActions.ToArray();
MoveAction[] notExploredMoves = moves.Any(m => !m.HasBeenVisited) ? moves.Where(m => !m.HasBeenVisited).ToArray() : moves;
if (moves.All(m => m.HasBeenVisited))
{
Logger.Log(LogLevel.Debug, "All adjacent tiles have been visited! Selecting next path random.");
}
else
{
Logger.Log(LogLevel.Debug, $"{string.Join(", ", notExploredMoves.Select(m => m.Direction.ToString()))} have not been visited, selecting next move.");
}
int selected = random.Next(notExploredMoves.Length - 1);
MoveAction moveAction = notExploredMoves[selected];
Logger.Log(LogLevel.Debug, $"Moving {moveAction.Direction}, I have {(!moveAction.HasBeenVisited ? "not" : string.Empty)} been here.");
result = await MazeClient.Move(moveAction.Direction);
Logger.Log(LogLevel.Debug, $"New tile has {(!result.CanExitMazeHere ? "no" : string.Empty)} exit.");
} while (!result.CanExitMazeHere);
await MazeClient.ExitMaze();
Logger.Log(LogLevel.Information, $"Exited the maze!");
return 0;
}
}
}

View File

@ -1,47 +0,0 @@
using HightechICT.Amazeing.Client.Rest;
using LogConsole = System.Console;
namespace Bobo.System.Maze.Bot
{
public class BumpBot
{
public static async Task Run(string mazeName, AmazeingClient mazeClient)
{
Random random = new Random();
LogConsole.WriteLine($"Entering maze '{mazeName}'");
PossibleActionsAndCurrentScore result = await mazeClient.EnterMaze(mazeName);
do
{
await Task.Delay(100);
// select a way to go
MoveAction[] moves = result.PossibleMoveActions.ToArray();
MoveAction[] notExploredMoves = moves.Any(m => !m.HasBeenVisited) ? moves.Where(m => !m.HasBeenVisited).ToArray() : moves;
if (moves.All(m => m.HasBeenVisited))
{
LogConsole.WriteLine("All adjacent tiles have been visited! Selecting next path random.");
}
else
{
LogConsole.WriteLine($"{string.Join(", ", notExploredMoves.Select(m => m.Direction.ToString()))} have not been visited, selecting next move.");
}
int selected = random.Next(notExploredMoves.Length - 1);
MoveAction moveAction = notExploredMoves[selected];
LogConsole.WriteLine($"Moving {moveAction.Direction}, I have {(!moveAction.HasBeenVisited ? "not" : string.Empty)} been here.");
result = await mazeClient.Move(moveAction.Direction);
LogConsole.WriteLine($"New tile has {(!result.CanExitMazeHere ? "no" : string.Empty)} exit.");
} while (!result.CanExitMazeHere);
await mazeClient.ExitMaze();
LogConsole.WriteLine($"Exited the maze!");
}
}
}

View File

@ -0,0 +1,20 @@
using HightechICT.Amazeing.Client.Rest;
using Microsoft.Extensions.Logging;
namespace Bobo.System.Maze.Bot.Interface
{
public abstract class BaseBot
{
protected ILogger Logger { get; }
protected AmazeingClient MazeClient { get; }
public BaseBot(AmazeingClient mazeClient, ILogger logger)
{
MazeClient = mazeClient;
Logger = logger;
}
public abstract Task<int> Run(MazeInfo maze);
}
}

View File

@ -1,84 +1,159 @@
using HightechICT.Amazeing.Client.Rest;
using Bobo.System.Maze.Bot.Interface;
using HightechICT.Amazeing.Client.Rest;
using Microsoft.Extensions.Logging;
using LogConsole = System.Console;
namespace Bobo.System.Maze.Bot
{
public class SimpleBot
public class SimpleBot : BaseBot
{
public static async Task<int> Run(MazeInfo maze, AmazeingClient mazeClient, ILogger logger)
private Stack<Direction> Directions { get; set; } = new Stack<Direction>();
private List<List<Direction>> ExitDirections { get; set; } = new List<List<Direction>>();
private List<List<Direction>> CollectionPointDirections { get; set; } = new List<List<Direction>>();
public SimpleBot(AmazeingClient mazeClient, ILogger logger) : base(mazeClient, logger)
{ }
public override async Task<int> Run(MazeInfo maze)
{
if (mazeClient == null)
throw new ArgumentException(nameof(mazeClient));
if (MazeClient == null)
throw new ArgumentException(nameof(MazeClient));
if (string.IsNullOrWhiteSpace(maze.Name))
throw new ArgumentException(nameof(maze.Name));
Random random = new Random();
logger.Log(LogLevel.Information, "Entering maze '{MazeName}'", maze.Name);
PossibleActionsAndCurrentScore result = await mazeClient.EnterMaze(maze.Name);
Stack<Direction> directions = new Stack<Direction>();
Logger.Log(LogLevel.Information, "Entering maze '{MazeName}'", maze.Name);
PossibleActionsAndCurrentScore result = await MazeClient.EnterMaze(maze.Name);
int collected = 0;
do
{
if (result.PossibleMoveActions.All(m => m.HasBeenVisited))
{
logger.Log(LogLevel.Debug, "All adjacent tiles have been visited! Going back.");
Direction direction = directions.Pop();
switch (direction)
{
case Direction.Left:
direction = Direction.Right;
break;
case Direction.Right:
direction = Direction.Left;
break;
case Direction.Up:
direction = Direction.Down;
break;
case Direction.Down:
direction = Direction.Up;
break;
}
logger.Log(LogLevel.Debug, "Moving {Direction}, I have been here.", direction);
result = await mazeClient.Move(direction);
Logger.Log(LogLevel.Debug, "All adjacent tiles have been visited! Going back.");
result = await MoveBackOne();
}
else
{
MoveAction[] notVisited = result.PossibleMoveActions.Where(m => !m.HasBeenVisited).ToArray();
logger.Log(LogLevel.Debug, $"{string.Join(", ", notVisited.Select(m => m.Direction.ToString()))} have not been visited, selecting next move.");
Logger.Log(LogLevel.Debug, $"{string.Join(", ", notVisited.Select(m => m.Direction.ToString()))} have not been visited, selecting next move.");
int selected = random.Next(notVisited.Length - 1);
MoveAction moveAction = notVisited[selected];
logger.Log(LogLevel.Debug, $"Moving {moveAction.Direction}, I have {(!moveAction.HasBeenVisited ? "not" : string.Empty)} been here.");
Logger.Log(LogLevel.Debug, $"Moving {moveAction.Direction}, I have {(!moveAction.HasBeenVisited ? "not" : string.Empty)} been here.");
result = await mazeClient.Move(moveAction.Direction);
result = await MazeClient.Move(moveAction.Direction);
directions.Push(moveAction.Direction);
Directions.Push(moveAction.Direction);
}
if (result.CanCollectScoreHere && result.CurrentScoreInHand > 0)
// if this is an exit, copy the path so we know how to get there
if (result.CanExitMazeHere)
{
ExitDirections.Add(new List<Direction>(Directions));
}
// if this is a collection point, copy the path so we know how to get there
if (result.CanCollectScoreHere)
{
CollectionPointDirections.Add(new List<Direction>(Directions));
List<Direction> list = new List<Direction>(Directions);
}
Logger.Log(LogLevel.Debug, $"New tile has {(!result.CanExitMazeHere ? "no" : string.Empty)} exit.");
} while (maze.PotentialReward != result.CurrentScoreInHand
&& CollectionPointDirections.Any()
&& ExitDirections.Any());
do
{
// create a list of the directions to the current point
List<Direction> fromStart = new List<Direction>(Directions);
// see what collection point is closest (if multiple)
List<Direction> collectionPointDirections = CollectionPointDirections.First();
int collectionCommonPointFromStart = int.MaxValue;
foreach(List<Direction> cdp in CollectionPointDirections)
{
int lowest = fromStart.Count() < cdp.Count() ? fromStart.Count() : cdp.Count();
int lastCommonIndex = 0;
// start from index 0 and work up to the lowest size
for (lastCommonIndex = 0; lastCommonIndex < lowest; lastCommonIndex++)
{
if (fromStart[lastCommonIndex] != cdp[lastCommonIndex])
{
// not common, break loop
break;
}
}
if (lastCommonIndex < collectionCommonPointFromStart)
{
collectionPointDirections = cdp;
collectionCommonPointFromStart = lastCommonIndex;
}
}
// first go back to the common index
for (int returnMoves = 0; returnMoves < fromStart.Count - collectionCommonPointFromStart; returnMoves ++)
{
await MoveBackOne();
}
for (int toCollectionIndex = collectionCommonPointFromStart + 1; toCollectionIndex < collectionPointDirections.Count(); toCollectionIndex++)
{
result = await MazeClient.Move(collectionPointDirections[toCollectionIndex]);
}
// go to collection
if (result.CanCollectScoreHere)
{
collected += result.CurrentScoreInHand;
await mazeClient.CollectScore();
await MazeClient.CollectScore();
}
logger.Log(LogLevel.Debug, $"New tile has {(!result.CanExitMazeHere ? "no" : string.Empty)} exit.");
// go to exit
}
while (!result.CanExitMazeHere);
} while (!result.CanExitMazeHere);
await MazeClient.ExitMaze();
await mazeClient.ExitMaze();
logger.Log(LogLevel.Information, "Collected {Collected}!", collected);
logger.Log(LogLevel.Information, "Exited maze {MazeName}!", maze.Name);
Logger.Log(LogLevel.Information, "Collected {Collected}!", collected);
Logger.Log(LogLevel.Information, "Exited maze {MazeName}!", maze.Name);
return collected;
}
private Task<PossibleActionsAndCurrentScore> MoveBackOne()
{
Direction direction = Directions.Pop();
switch (direction)
{
case Direction.Left:
direction = Direction.Right;
break;
case Direction.Right:
direction = Direction.Left;
break;
case Direction.Up:
direction = Direction.Down;
break;
case Direction.Down:
direction = Direction.Up;
break;
}
Logger.Log(LogLevel.Debug, "Moving {Direction}, I have been here.", direction);
return MazeClient.Move(direction);
}
}
}

View File

@ -1,32 +1,33 @@
using HightechICT.Amazeing.Client.Rest;
using LogConsole = System.Console;
using Bobo.System.Maze.Bot.Interface;
using HightechICT.Amazeing.Client.Rest;
using Microsoft.Extensions.Logging;
namespace Bobo.System.Maze.Bot
{
public class SimplerBot
public class SimplerBot : BaseBot
{
public static async Task<int> Run(string mazeName, AmazeingClient mazeClient)
{
if (mazeClient == null)
throw new ArgumentException(nameof(mazeClient));
public SimplerBot(AmazeingClient mazeClient, ILogger logger) : base(mazeClient, logger)
{ }
if (string.IsNullOrWhiteSpace(mazeName))
throw new ArgumentException(nameof(mazeName));
public override async Task<int> Run(MazeInfo maze)
{
if (MazeClient == null)
throw new ArgumentException(nameof(MazeClient));
if (string.IsNullOrWhiteSpace(maze.Name))
throw new ArgumentException(nameof(maze.Name));
Random random = new Random();
LogConsole.WriteLine($"Entering maze '{mazeName}'");
PossibleActionsAndCurrentScore result = await mazeClient.EnterMaze(mazeName);
Logger.Log(LogLevel.Information, "Entering maze '{MazeName}'", maze.Name);
PossibleActionsAndCurrentScore result = await MazeClient.EnterMaze(maze.Name);
Stack<Direction> directions = new Stack<Direction>();
int collected = 0;
do
{
//await Task.Delay(500);
if (result.PossibleMoveActions.All(m => m.HasBeenVisited))
{
//LogConsole.WriteLine("All adjacent tiles have been visited! Going back.");
Logger.Log(LogLevel.Debug, "All adjacent tiles have been visited! Going back.");
Direction direction = directions.Pop();
switch (direction)
@ -46,20 +47,20 @@ namespace Bobo.System.Maze.Bot
}
//LogConsole.WriteLine($"Moving {direction}, I have been here.");
Logger.Log(LogLevel.Debug, "Moving {Direction}, I have been here.", direction);
result = await mazeClient.Move(direction);
result = await MazeClient.Move(direction);
}
else
{
MoveAction[] notVisited = result.PossibleMoveActions.Where(m => !m.HasBeenVisited).ToArray();
//LogConsole.WriteLine($"{string.Join(", ", notVisited.Select(m => m.Direction.ToString()))} have not been visited, selecting next move.");
Logger.Log(LogLevel.Debug, $"{string.Join(", ", notVisited.Select(m => m.Direction.ToString()))} have not been visited, selecting next move.");
int selected = random.Next(notVisited.Length - 1);
MoveAction moveAction = notVisited[selected];
//LogConsole.WriteLine($"Moving {moveAction.Direction}, I have {(!moveAction.HasBeenVisited ? "not" : string.Empty)} been here.");
Logger.Log(LogLevel.Debug, $"Moving {moveAction.Direction}, I have {(!moveAction.HasBeenVisited ? "not" : string.Empty)} been here.");
result = await mazeClient.Move(moveAction.Direction);
result = await MazeClient.Move(moveAction.Direction);
directions.Push(moveAction.Direction);
}
@ -67,17 +68,17 @@ namespace Bobo.System.Maze.Bot
if (result.CanCollectScoreHere && result.CurrentScoreInHand > 0)
{
collected += result.CurrentScoreInHand;
await mazeClient.CollectScore();
await MazeClient.CollectScore();
}
//LogConsole.WriteLine($"New tile has {(!result.CanExitMazeHere ? "no" : string.Empty)} exit.");
Logger.Log(LogLevel.Debug, $"New tile has {(!result.CanExitMazeHere ? "no" : string.Empty)} exit.");
} while (!result.CanExitMazeHere);
await mazeClient.ExitMaze();
await MazeClient.ExitMaze();
LogConsole.WriteLine($"Collected {collected}!");
LogConsole.WriteLine($"Exited maze {mazeName}!");
Logger.Log(LogLevel.Information, "Collected {Collected}!", collected);
Logger.Log(LogLevel.Information, "Exited maze {MazeName}!", maze.Name);
return collected;
}

View File

@ -1,5 +1,6 @@
// See https://aka.ms/new-console-template for more information
using Bobo.System.Maze.Bot;
using Bobo.System.Maze.Bot.Interface;
using HightechICT.Amazeing.Client.Rest;
using Microsoft.Extensions.Logging;
using Serilog;
@ -40,10 +41,10 @@ if (!registered)
logger.Log(LogLevel.Information, $"Player '{username}' registered", username);
logger.Log(LogLevel.Information, $"Starting SimplerBot");
BaseBot bot = new SimplerBot(mazeClient, logger);
foreach (MazeInfo maze in mazes)
{
int collected = await SimpleBot.Run(maze, mazeClient, logger);
int collected = await bot.Run(maze);
logger.Log(LogLevel.Information, $"Collected {collected}/{maze.PotentialReward}", collected, maze.PotentialReward);
}

View File

@ -3,10 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bobo.System.Maze.Console", "Bobo.Systems.Maze.Console\Bobo.System.Maze.Console.csproj", "{8E397C0A-34CF-4A55-94B5-889CBE8BDD1F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bobo.System.Maze.Console", "Bobo.System.Maze.Console\Bobo.System.Maze.Console.csproj", "{8E397C0A-34CF-4A55-94B5-889CBE8BDD1F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bobo.System.Maze.Bot", "Bobo.System.Maze.Bot\Bobo.System.Maze.Bot.csproj", "{754FC8DB-342D-4A5E-8193-E665D6F0DE02}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{A0604FAF-75B5-497B-9639-EE340A1509F2}"
ProjectSection(SolutionItems) = preProject
readme.md = readme.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

6
readme.md Normal file
View File

@ -0,0 +1,6 @@
# Hightech ICT Maze runner/bot
## Bots
The bot solutions can be found here (./Bobo.System.Maze.Bot)
Currently there are 2 working bots