mirror of
https://github.com/lscharen/iigs-sprite-compiler.git
synced 2024-12-21 16:30:15 +00:00
Begin adding ability to load images from command line. Additional tests; start to move toward graph search and then IDA*
This commit is contained in:
parent
5fe12243ad
commit
0a26e62c73
@ -62,6 +62,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="HeuristicTests.cs" />
|
||||
<Compile Include="RegisterTests.cs" />
|
||||
<Compile Include="StateTests.cs" />
|
||||
<Compile Include="Tests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
32
SpriteCompiler.Test/StateTests.cs
Normal file
32
SpriteCompiler.Test/StateTests.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using SpriteCompiler.Problem;
|
||||
using SpriteCompiler.AI;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace SpriteCompiler.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class StateTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestStateEquivalence()
|
||||
{
|
||||
// States are used in HashSet, so we need to
|
||||
// test that two instances of the same state
|
||||
// are recognized as equivalent
|
||||
var state1 = new SpriteGeneratorState();
|
||||
var state2 = new SpriteGeneratorState();
|
||||
|
||||
Assert.AreEqual(state1, state2);
|
||||
|
||||
var set = new HashSet<SpriteGeneratorState>();
|
||||
set.Add(state1);
|
||||
|
||||
Assert.IsTrue(set.Contains(state2));
|
||||
}
|
||||
}
|
||||
}
|
@ -103,8 +103,8 @@ namespace SpriteCompiler.Test
|
||||
// Write out the solution
|
||||
WriteOutSolution(solution);
|
||||
|
||||
//Assert.AreEqual(3, solution.Count());
|
||||
//Assert.AreEqual(10, (int)solution.Last().PathCost);
|
||||
Assert.AreEqual(6, solution.Count());
|
||||
Assert.AreEqual(25, (int)solution.Last().PathCost);
|
||||
}
|
||||
|
||||
private void WriteOutSolution(IEnumerable<SpriteGeneratorSearchNode> solution)
|
||||
|
@ -47,8 +47,9 @@
|
||||
while (!fringe.Empty)
|
||||
{
|
||||
var node = fringe.Remove();
|
||||
#if DEBUG
|
||||
Console.WriteLine(string.Format("Removed {0} from the queue with g = {1}, c(n, n') = {2}", node.State, node.PathCost, node.StepCost));
|
||||
|
||||
#endif
|
||||
if (problem.IsGoal(node.State))
|
||||
{
|
||||
return Solution(node);
|
||||
|
@ -16,7 +16,7 @@ namespace SpriteCompiler.AI
|
||||
|
||||
/// <summary>
|
||||
/// Generic graph search. See page 83 in Russell and Norvig. This only works in informed
|
||||
/// search if the heuristic is admissible.However, if a heuristic is not admissible and
|
||||
/// search if the heuristic is admissible. However, if a heuristic is not admissible and
|
||||
/// you still want to use, that means you should know enough to extend this class or write
|
||||
/// your own Search class.
|
||||
/// </summary>
|
||||
|
@ -16,8 +16,10 @@ namespace SpriteCompiler.AI
|
||||
var successors = problem.Successors(node.State);
|
||||
|
||||
// Debug
|
||||
#if DEBUG
|
||||
Console.WriteLine(String.Format("There are {0} successors for {1}", successors.Count(), node));
|
||||
Console.WriteLine(String.Format("This node has a current path cost of {0}", node.PathCost));
|
||||
#endif
|
||||
|
||||
foreach (var successor in successors)
|
||||
{
|
||||
@ -29,8 +31,9 @@ namespace SpriteCompiler.AI
|
||||
next.StepCost = problem.StepCost(node.State, action, state);
|
||||
next.Heuristic = problem.Heuristic(state);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine(" Action = " + next.Action + ", g(n') = " + next.PathCost + ", h(n') = " + next.Heuristic);
|
||||
|
||||
#endif
|
||||
yield return next;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,9 @@
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
#if DEBUG
|
||||
Console.WriteLine("Enqueuing " + item + " with cost " + item.EstCost);
|
||||
#endif
|
||||
queue.Enqueue(item, item.EstCost);
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode() + Tag.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as Register);
|
||||
|
@ -17,7 +17,8 @@
|
||||
public static ISearch<CodeSequence, SpriteGeneratorState, SpriteGeneratorSearchNode, IntegerPathCost> Create()
|
||||
{
|
||||
var expander = new SpriteGeneratorNodeExpander();
|
||||
var strategy = new TreeSearch<CodeSequence, SpriteGeneratorState, SpriteGeneratorSearchNode, IntegerPathCost>(expander);
|
||||
//var strategy = new TreeSearch<CodeSequence, SpriteGeneratorState, SpriteGeneratorSearchNode, IntegerPathCost>(expander);
|
||||
var strategy = new GraphSearch<CodeSequence, SpriteGeneratorState, SpriteGeneratorSearchNode, IntegerPathCost>(expander);
|
||||
|
||||
return new AStarSearch<CodeSequence, SpriteGeneratorState, SpriteGeneratorSearchNode, IntegerPathCost>(strategy);
|
||||
}
|
||||
|
@ -117,6 +117,18 @@
|
||||
;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return
|
||||
A.GetHashCode() +
|
||||
X.GetHashCode() +
|
||||
Y.GetHashCode() +
|
||||
D.GetHashCode() +
|
||||
S.GetHashCode() +
|
||||
P.GetHashCode()
|
||||
;
|
||||
}
|
||||
|
||||
public static bool operator ==(SpriteGeneratorState state1, SpriteGeneratorState state2)
|
||||
{
|
||||
if (((object)state1) == null || ((object)state2) == null)
|
||||
|
@ -4,6 +4,7 @@
|
||||
using SpriteCompiler.Problem;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
public class ApplicationArguments
|
||||
@ -26,11 +27,57 @@
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
byte[] data = null;
|
||||
IEnumerable<SpriteByte> data = null;
|
||||
|
||||
Console.WriteLine(string.Join(", ", args.Select(s => "'" + s + "'")));
|
||||
data = args.Select(s => Convert.ToByte(s, 16)).ToArray();
|
||||
try
|
||||
{
|
||||
data = args.Select((s, i) => new SpriteByte(Convert.ToByte(s, 16), (ushort)i));
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
// If there is only one or two arguments, them marybe the user passed in a file
|
||||
if (args.Length <= 2)
|
||||
{
|
||||
var palette = new Dictionary<Color, int>();
|
||||
int nextIndex = 1;
|
||||
|
||||
// Convert the image / mask to a paletted image
|
||||
var bitmap = new Bitmap(args[0]);
|
||||
int[,] buffer = new int[bitmap.Width, bitmap.Height];
|
||||
|
||||
for (int r = 0; r < bitmap.Height; r++)
|
||||
{
|
||||
for (int w = 0; w < bitmap.Width; w++)
|
||||
{
|
||||
var rgb = bitmap.GetPixel(w, r);
|
||||
|
||||
if (!palette.ContainsKey(rgb))
|
||||
{
|
||||
if (palette.Count >= 15)
|
||||
{
|
||||
throw new Exception("Image cannot have more than 15 unique colors");
|
||||
}
|
||||
palette[rgb] = nextIndex++;
|
||||
}
|
||||
|
||||
buffer[w, r] = palette[rgb];
|
||||
}
|
||||
}
|
||||
|
||||
// Pair up pixles to build bytes
|
||||
var sprite = new List<SpriteByte>();
|
||||
|
||||
for (int r = 0; r < bitmap.Height; r++)
|
||||
{
|
||||
for (int w = 0; w < bitmap.Width; w += 2)
|
||||
{
|
||||
sprite.Add(new SpriteByte((byte)((buffer[w, r] << 4) + buffer[w + 1, r]), (ushort)(r * 160 + (w / 2))));
|
||||
}
|
||||
}
|
||||
|
||||
data = sprite;
|
||||
}
|
||||
}
|
||||
/*
|
||||
return;
|
||||
|
||||
|
BIN
SpriteCompiler/Samples/SpriteX2_000.gif
Normal file
BIN
SpriteCompiler/Samples/SpriteX2_000.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
SpriteCompiler/Samples/SpriteX2_001.gif
Normal file
BIN
SpriteCompiler/Samples/SpriteX2_001.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -43,6 +43,7 @@
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@ -92,6 +93,10 @@
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Content Include="Samples\SpriteX2_000.gif" />
|
||||
<Content Include="Samples\SpriteX2_001.gif" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
Loading…
Reference in New Issue
Block a user