Package rlforj.util.test

Source Code of rlforj.util.test.AStarTest

package rlforj.util.test;

import java.util.ArrayList;
import java.util.Random;

import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import rlforj.math.Point2I;
import rlforj.pathfinding.AStar;
import rlforj.util.Directions;


public class AStarTest
{

    /**
     * 1000 times
     * Build a random board. Pick 2 random points. Find a path. If a path is
     * returned, check that:
     * 1. It is a valid path (all points are adjacent to each other)
     * 2. No point on the path is an obstacle.
     * 3. If pathfindfind fails, floodfill the map startinf from the start point.
     *    If endpoint is not the same color, path does not exist. Hence check
     *    pathfinding failure.
     * 
     * Not tested:
     * 1. It is the shortest path.
     */
    @Test
    public void testAStarBasic()
    {
        Random rand = new Random();
        for (int i = 0; i < 1000; i++)
        {
            int w = rand.nextInt(80) + 20; //20 - 100
            int h = rand.nextInt(80) + 20; //20 - 100
           
            StringBuilder sb = new StringBuilder();
            // Create mockboard
            for (int k = 0; k < h; k++)
            {
                for (int j = 0; j < w; j++)
                    if (rand.nextInt(100) < 30)// 30% coverage
                        sb.append('#');
                    else
                        sb.append(' ');
                sb.append('\n');
            }
            MockBoard m = new MockBoard(sb.toString());
           
            int startx=-1, starty=-1, endx=-1, endy=-1;
           
            while(true)// We will find 2 points pretty quickly for low % coverage.
            {
                startx = rand.nextInt(w); starty = rand.nextInt(h);
                endx = rand.nextInt(w); endy = rand.nextInt(h);
               
                if (!m.isObstacle(startx, starty) && !m.isObstacle(endx, endy))
                    break;
            }
            AStar algo = new AStar(m, w, h);
           
            Point2I[] path = algo.findPath(startx, starty, endx, endy);
            if (path != null)
            {
                // Check path
                for (Point2I step: path)
                {
                    assertFalse("A point on A* path was an obstacle", m.isObstacle(step.x, step.y));
                }
               
                // Check continuity
                Point2I lastStep = null;
                for (Point2I step: path)
                {
                    if (lastStep == null)
                    {
                        lastStep = step;
                        continue;
                    }
                   
                    assertTrue("Discontinuous path in A*",
                            step.x - lastStep.x <=1 && step.x - lastStep.x >= -1
                            && step.y - lastStep.y <=1 && step.y - lastStep.y >= -1);
                   
                    lastStep = step;
                }
            }
            else
            {
                assertFalse("Path existed but A* failed",
                        floodFillTest(m, startx, starty, endx, endy));
            }
        }
    }

    /**
     * FloodFill the board from point 1 and see if point2 is same color. If not,
     * points are not reachable from each other.
     * @param mb
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    private boolean floodFillTest(MockBoard mb, int x1, int y1, int x2, int y2)
    {
        final int EMPTY=0, FULL=1, COLOR=2;
        int width = mb.getWidth();
        int height = mb.getHeight();
        int[][] board = new int[width][];
        for (int i = 0; i< width; i++)
        {
           
            board[i] = new int[height];
            for (int j = 0; j < height; j++)
            {
                if (mb.isObstacle(i, j))
                    board[i][j] = FULL;
                else
                    board[i][j] = EMPTY;
            }
        }
       
        ArrayList<Point2I> l = new ArrayList<Point2I>(width * height);
        l.add(new Point2I(x1, y1));
        while(!l.isEmpty())
        {
            Point2I p1 = l.remove(l.size() - 1);
            for(Directions d: Directions.N8)
            {
                Point2I p2 = new Point2I(p1.x+d.dx(), p1.y+d.dy());
                if (!mb.contains(p2.x, p2.y) || board[p2.x][p2.y] != EMPTY)
                    continue;
               
                board[p2.x][p2.y] = COLOR;
                l.add(p2);
            }
        }
       
        return (board[x1][y1] == board[x2][y2] && board[x1][y1] == COLOR);
    }
}
TOP

Related Classes of rlforj.util.test.AStarTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.