public void TestSingleByteSprite() { Trace.WriteLine("Testing a sprite with just one byte"); // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0xAA }; var initialState = SpriteGeneratorState.Init(data); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // The fastest way to draw a single byte at the current location should be // // TCS // SHORT A // LDA #$AA // PHA // LONG A = 13 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(5, solution.Count()); Assert.AreEqual(13, (int)solution.Last().PathCost); }
public void TestLines_1_To_2() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); var sprite = new List <SpriteByte> { new SpriteByte(0x11, 0x00, 3), new SpriteByte(0x11, 0x00, 4), new SpriteByte(0x10, 0x0F, 5), new SpriteByte(0x11, 0x00, 162), new SpriteByte(0x11, 0x00, 163), new SpriteByte(0x11, 0x00, 164), new SpriteByte(0x20, 0x0F, 165), }; // Act : solve the problem var initialState = SpriteGeneratorState.Init(sprite); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert : The initial state IS the goal state (47 cycles is the currrent best solution) WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); }
public void TestSingleWordSprite() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0xAA, 0x55 }; var initialState = SpriteGeneratorState.Init(data); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // The fastest way to draw a single word at the current location should be // // TCS // LDA #$55AA // STA 0,s = 10 cycles // // Alternate // // ADC #1 // TCS // PEA #$55AA = 10 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(3, solution.Count()); Assert.AreEqual(10, (int)solution.Last().PathCost); }
public void TestConsecutiveWordSpriteWithMask() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0x01, 0x11, 0x22, 0x11, 0x33 }; var mask = new byte[] { 0xF0, 0x00, 0x00, 0x00, 0x00 }; var initialState = SpriteGeneratorState.Init(data, mask); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // The fastest way to render this data should be // // ADC #4 // TCS // PEA $3311 // PEA $2211 // LDA 0,s // AND #$00F0 // ORA #$1101 // STA 0,s = 31 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(31, (int)solution.Last().PathCost); }
public void TestConsecutiveWordSprite() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0xAA, 0x55, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; var initialState = SpriteGeneratorState.Init(data); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // The fastest way to draw a consecutive words should be // // ADC #7 // TCS // PEA $6655 // PEA $4433 // PEA $2211 // PEA $55AA = 25 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(6, solution.Count()); Assert.AreEqual(25, (int)solution.Last().PathCost); }
public void TestSinglePixelMask() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0x01, 0x11 }; var mask = new byte[] { 0xF0, 0x00 }; var initialState = SpriteGeneratorState.Init(data, mask); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // Solution should be a single 16-bit RMW // // TCS // LDA 0,s // AND #$00F0 // ORA #$1101 // STA 0,s = 18 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(18, (int)solution.Last().PathCost); }
public void TestSingleByteWithMask() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0x00, 0x11 }; var mask = new byte[] { 0xFF, 0x00 }; var initialState = SpriteGeneratorState.Init(data, mask); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // Solution should be same as regular single-byte sprite, except // the store happens at offset 1, instead of 0. // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(5, solution.Count()); Assert.AreEqual(14, (int)solution.Last().PathCost); }
public void TestOverlappingWrite() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new byte[] { 0x11, 0x22, 0x22 }; var initialState = SpriteGeneratorState.Init(data); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert // // Solution should be 18 cycles // // TCS // LDA #$2211 // STA 0,s // LDA #$2222 // STA 1,s = 18 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(18, (int)solution.Last().PathCost); }
public void TestThreeLineSprite() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var data = new[] { new SpriteByte(0x11, 0), new SpriteByte(0x11, 160), new SpriteByte(0x11, 320) }; var initialState = SpriteGeneratorState.Init(data); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Current best solution // // TCS ; 2 cycles // SEP #$10 ; 3 cycles // LDA #$11 ; 2 cycles // PHA ; 3 cycles // STA A1,s ; 4 cycles // REP #$10 ; 3 cycles // TSC ; 2 cycles // ADC #321 ; 3 cycles // TCS ; 2 cycles // SEP #$10 ; 3 cycles // LDA #$11 ; 2 cycles // PHA ; 3 cycles // REP #$10 ; 3 cycles //; Total Cost = 35 cycles // // Once other register caching becomes available, this should be able to be improved to // // TCS ; 2 cycles // SEP #$20 ; 3 cycles // LDX #$11 ; 2 cycles // PHX ; 3 cycles // ADC #160 ; 3 cycles // TCS ; 2 cycles // PHX ; 3 cycles // ADC #161 ; 3 cycles // TCS ; 2 cycles // PHX ; 3 cycles // REP #$20 ; 3 cycles //; Total Cost = 29 cycles // Write out the solution WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(35, (int)solution.Last().PathCost); }
public void TestFirstLine() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); var sprite = new List <SpriteByte> { new SpriteByte(0x11, 0x00, 3), new SpriteByte(0x11, 0x00, 4), new SpriteByte(0x10, 0x0F, 5) }; // Act : solve the problem var solution = search.Search(problem, SpriteGeneratorState.Init(sprite)); // Assert : The initial state IS the goal state WriteOutSolution(solution); }
public void TestEmptySprite() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(); // Act : solve the problem var initialState = SpriteGeneratorState.Init(Enumerable.Empty <SpriteByte>()); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert : The initial state IS the goal state WriteOutSolution(solution, initialHeuristic); initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); Assert.AreEqual(1, solution.Count()); }
public void TestLines_1_To_4() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(200); // max budget of 200 cycles var sprite = new List <SpriteByte> { new SpriteByte(0x11, 0x00, 3), new SpriteByte(0x11, 0x00, 4), new SpriteByte(0x10, 0x0F, 5), new SpriteByte(0x11, 0x00, 162), new SpriteByte(0x11, 0x00, 163), new SpriteByte(0x11, 0x00, 164), new SpriteByte(0x20, 0x0F, 165), new SpriteByte(0x01, 0xF0, 321), new SpriteByte(0x11, 0x00, 322), new SpriteByte(0x11, 0x00, 323), new SpriteByte(0x12, 0x00, 324), new SpriteByte(0x20, 0x0F, 325), new SpriteByte(0x01, 0xF0, 481), new SpriteByte(0x11, 0x00, 482), new SpriteByte(0x11, 0x00, 483), new SpriteByte(0x11, 0x00, 484), new SpriteByte(0x11, 0x00, 485), new SpriteByte(0x11, 0x00, 486) }; // Act : solve the problem var initialState = SpriteGeneratorState.Init(sprite); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert : The initial state IS the goal state WriteOutSolution(solution); }
public void TestLines_1_To_3() { // Arrange var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = SpriteGeneratorSearchProblem.Create(100); // max budget of 100 cycles var sprite = new List <SpriteByte> { new SpriteByte(0x11, 0x00, 3), new SpriteByte(0x11, 0x00, 4), new SpriteByte(0x10, 0x0F, 5), new SpriteByte(0x11, 0x00, 162), new SpriteByte(0x11, 0x00, 163), new SpriteByte(0x11, 0x00, 164), new SpriteByte(0x20, 0x0F, 165), new SpriteByte(0x01, 0xF0, 321), new SpriteByte(0x11, 0x00, 322), new SpriteByte(0x11, 0x00, 323), new SpriteByte(0x12, 0x00, 324), new SpriteByte(0x20, 0x0F, 325) }; // Act : solve the problem var initialState = SpriteGeneratorState.Init(sprite); var initialHeuristic = problem.Heuristic(initialState); var solution = search.Search(problem, initialState); // Assert : The initial state IS the goal state WriteOutSolution(solution); // TCS ; 2 cycles // LDA 04,s ; 5 cycles // AND #$0F00 ; 3 cycles // ORA #$1011 ; 3 cycles // STA 04,s ; 5 cycles // LDA #$1111 ; 3 cycles // STA 03,s ; 5 cycles // STA A2,s ; 5 cycles // LDA A4,s ; 5 cycles // AND #$0F00 ; 3 cycles // ORA #$2011 ; 3 cycles // STA A4,s ; 5 cycles // TSC ; 2 cycles // ADC #321 ; 3 cycles // TCS ; 2 cycles // LDA 00,s ; 5 cycles // AND #$00F0 ; 3 cycles // ORA #$1101 ; 3 cycles // STA 00,s ; 5 cycles // LDA 03,s ; 5 cycles // AND #$0F00 ; 3 cycles // ORA #$2012 ; 3 cycles // STA 03,s ; 5 cycles // LDA #$1211 ; 3 cycles // STA 02,s ; 5 cycles //; Total Cost = 94 cycles initialHeuristic.Should().BeLessOrEqualTo(solution.Last().PathCost); }
static void Main(string[] args) { var data = new List <byte>(); var mask = new List <byte>(); var filename = (string)null; Color?maskColor = null; int? maxCycles = null; var sprite = new List <SpriteByte>(); bool verbose = false; var p = new FluentCommandLineParser(); p.Setup <List <string> >('d', "data") .Callback(_ => data = _.Select(s => Convert.ToByte(s, 16)).ToList()); p.Setup <List <string> >('m', "mask") .Callback(_ => mask = _.Select(s => Convert.ToByte(s, 16)).ToList()); p.Setup <string>('i', "image") .Callback(_ => filename = _); p.Setup <string>('l', "limit") .Callback(_ => maxCycles = int.Parse(_)); p.Setup <string>('v', "verbose") .Callback(_ => verbose = true); p.Setup <string>("bg-color") .Callback(_ => maskColor = Color.FromArgb(0xFF, Color.FromArgb(Convert.ToInt32(_, 16)))); p.Parse(args); Console.WriteLine("Manual data has " + data.Count + " bytes"); Console.WriteLine("Manual mask has " + mask.Count + " bytes"); Console.WriteLine("Input filename is " + filename); Console.WriteLine("Image mask color is " + (maskColor.HasValue ? maskColor.ToString() : "(none)")); // Set the global state var problem = SpriteGeneratorSearchProblem.CreateSearchProblem(); var search = maxCycles.HasValue ? SpriteGeneratorSearchProblem.Create(maxCycles.Value) : SpriteGeneratorSearchProblem.Create(); SpriteGeneratorState initialState = null; // Handle the difference command line cases if (!String.IsNullOrEmpty(filename)) { var bitmap = new Bitmap(filename); var record = BrutalDeluxeClassifier.Decompose(bitmap, maskColor); record.Data.Dump(); Console.WriteLine(); record.Mask.Dump(); Console.WriteLine(); record.Classes.Dump(); //initialState = SpriteGeneratorState.Init(sprite); } else if (data.Count == mask.Count) { initialState = SpriteGeneratorState.Init(data, mask); } else { initialState = SpriteGeneratorState.Init(data); } //var solution = search.Search(problem, initialState); //WriteOutSolution(solution); }