Program a Racing Car CONGRATULATIONS to @kuroineko. Wins the bounty for excellent speed (672 moves) on the Gauntlet track.
LEADER:* Nimi scoring a lightweight 2129. Other entries are larger but showing some serious speed.
*Leader may change due to later entries.
Your task is to write a small program that can drive a racing car fast.
Rules
Your program will read in an image of the track. You can start your car on any
yellow pixel, and you must finish by crossing any black pixel. The path of your
car must be only on the grey ((c,c,c) where 30 &lt;= c &lt;= 220) track.
Your car will move in a straight line each turn with velocity v made up of
integers vx and vy (starting with (0,0)). At the start of each turn your program
can change vx and vy such that:
abs(vx2-vx1) + abs(vy2-vy1) &lt;= 15
Update: Increased maximum acceleration to 15.
Your program
will then plot a straight line from your current location to (location + v) in
white with a blue dot at the start. If a pixel under this line is black, you
have finished the race. Otherwise, if all the pixels under that line are grey or yellow, you may continue to the next turn.
Your program must output the track image with your path in white and blue added.
Additional Output (added 2015-01-15):
If you wish to compete for the win or the bonus, your program should also output your list of points (the blue dots) for the City or Gauntlet respectively. Include the list of points with your answer (for verification). The points should look like: (x0,y0), (x1,y1), ... (xn,yn). You can use white space freely including '\n' characters to fit the data on the page.
You may use third party image reading and writing, line drawing and pixel access libraries. You can't use path-finding libraries. If you wish you can convert the PNG images into other graphics formats (such as GIF, JPG, BMP) if you need to.
A few tracks to drive on
A simple track to start out:

A Race Track:

An Obstacle Course:

The City:

Nightmare Track: The Gauntlet (if the others are too easy)

Scoring
Your score will be based on your result on the City track. Points are equal to
your program length in bytes plus 10 points for each turn your racing car took
to finish. Lowest score wins. Please include your City track run image with your
answer - we would like to see your driving style.
Please use a title for your answer in the format:
&lt;Racing Driver or Team Name&gt; &lt;Language&gt; &lt;Score&gt; eg: Slowpoke Perl 5329
Your program must be able to drive on any track image following the above rules.
You must not hardcode the optimum path or any parameters of the test tracks. The
other standard loopholes apply.
Similar challenges
This is a similar puzzle to one posed by Martin: To Vectory! – The Vector Racing Grand Prix. This puzzle has a number of differences:

Driving through walls is not allowed.
You can use unlimited memory and time.
You do not have to run somebody else's code on your computer.
You do not have to download anything except one image.
The size of your code counts in scoring. Smaller is better.
You plot your solution on the track image.
You can easily create your own tracks with a paint package.
The higher resolution encourages more realistic braking and cornering.
Acceleration of 15 creates about 450 possibilities per turn. This makes BFS less feasible and encourages new interesting algorithms.

This puzzle should inspire a new round of programmers to try solutions and allow programmers with old solutions to rethink them in the new environment.
FirstRacer Java (5825 + 305*10 = 8875)

Just to have a start. Needs 305 segments on City.

This Java program does it pipelined:


read the image
A* (A star)



2.1 Build the A* search landscape.
2.2. Track back looking only for the best *direct* 8 neighbor cells (N,S,E,W,NE,NW,SE,SW). This finds the shortest track t0 pixelwise.



stay on t0 and optimize it for speed by eliminating pixels. Fullfilling the constraint by never be faster than 7 (this translates to keep at least every 7th pixel).
draw the track into the image
show the resulting image.


package race;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.WindowConstants;

public class AStar {

    private static BufferedImage img;
    private static int Width;
    private static int Height;
    private static int[][] cost;
    private static int best=Integer.MAX_VALUE;
    private static Point pBest;

    public static void main(String[] args) throws IOException {
        String file = "Q46YG.png";
        img = read(file);
        Width=img.getWidth();
        Height=img.getHeight();

        Vector&lt;Point&gt; track = astar();
        track = optimize(track);
        draw(track);
        System.out.println(10 * track.size());

        JFrame frame = new JFrame(file) {
            public void paint(Graphics g) {
                setSize(Width+17, Height+30+10);
                g.drawImage(img,8,30,null);
            }
        };
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static Vector&lt;Point&gt; optimize(Vector&lt;Point&gt; track) {
        Vector&lt;Point&gt; opt=new Vector&lt;Point&gt;();
        Point p0 = track.get(0);
        Point p1 = track.get(1);
        int v=0;
        opt.add(p0);
        int vx0=p1.x-p0.x, vy0=p1.y-p0.y;
        for (int i = 2; i &lt; track.size(); i++) {
            Point p = track.get(i);
            if (v&lt;7 &amp;&amp; vx0==p.x-p1.x &amp;&amp; vy0==p.y-p1.y) {
                v++;
            } else {
                v=0;
                opt.add(p1);
                vx0=p.x-p1.x;
                vy0=p.y-p1.y;
            }
            p1=p;
        }
        opt.add(p1);
        return opt;
    }

    private static void draw(Vector&lt;Point&gt; track) {
        Graphics2D g = img.createGraphics();
        Point p0 = track.get(0);
        for (int i = 1; i &lt; track.size(); i++) {
            Point p1 = track.get(i);
            g.setColor(Color.WHITE);
            g.drawLine(p0.x, p0.y, p1.x, p1.y);
            img.setRGB(p0.x, p0.y, 0xff0000ff);
            img.setRGB(p1.x, p1.y, 0xff0000ff);
            p0=p1;
        }
    }

    private static Vector&lt;Point&gt; astar() {
        Vector&lt;Point&gt; v0=findStart();
        for(int i=0; ; i++) {
            Vector&lt;Point&gt; v1=next(v0);
            if (v1.size()==0) break;
            v0=v1;
        }
        Vector&lt;Point&gt; track=new Vector&lt;Point&gt;();
        Point p0 = pBest;
        int x0=p0.x, y0=p0.y;
        int c0=cost[x0][y0];
        while(true) {
            int x=x0, y=y0;
            track.add(0, new Point(x, y));
            for (int x1 = x-1; x1 &lt;= x+1; x1++) {
                for (int y1 = y-1; y1 &lt;= y+1; y1++) {
                    int i1=getInfo(x1, y1);
                    if ((i1&amp;2)==2) {
                        int c=cost[x1][y1];
                        if (c0&gt;c) {
                            c0=c;
                            x0=x1;
                            y0=y1;
                        }
                    }
                }
            }
            if(x0==x &amp;&amp;y0==y) break;
        }
        return track;
    }

    private static Vector&lt;Point&gt; next(Vector&lt;Point&gt; v0) {
        Vector&lt;Point&gt; v1=new Vector&lt;Point&gt;();
        for (Point p0 : v0) {
            int x=p0.x, y=p0.y;
            int c0=cost[x][y];
            for (int x1 = x-1; x1 &lt;= x+1; x1++) {
                for (int y1 = y-1; y1 &lt;= y+1; y1++) {
                    int i1=getInfo(x1, y1);
                    if ((i1&amp;2)==2) {
                        int c1=c0+1414;
                        if (x1==x || y1==y) {
                            c1=c0+1000;
                        }
                        int c=cost[x1][y1];
                        if (c1&lt;c) {
                            cost[x1][y1]=c1;
                            Point p1=new Point(x1, y1);
                            v1.add(p1);
                            if (i1==3) {
                                if (best&gt;c1) {
                                    best=c1;
                                    pBest=p1;
                                }
                            }
                        }
                    }
                }
            }

        }
        return v1;
    }

    private static Vector&lt;Point&gt; findStart() {
        cost=new int[Width][Height];
        Vector&lt;Point&gt; v=new Vector&lt;Point&gt;();
        for (int i = 0; i &lt; Width; i++) {
            for (int j = 0; j &lt; Height; j++) {
                if (getInfo(i,j)==1) {
                    cost[i][j]=0;
                    v.add(new Point(i, j));
                } else {
                    cost[i][j]=Integer.MAX_VALUE;
                    pBest=new Point(i, j);
                }
            }
        }
        return v;
    }

    /**
     * 1: You can start your car on any yellow pixel, 
     * 3: and you must finish by crossing any black pixel. 
     * 2: The path of your car must be only on the grey ((c,c,c) where 30 &lt;= c &lt;= 220) track.
     * 0: else
     * 
     * @param x
     * @param y
     * @return
     */
    private static int getInfo(int x, int y) {
        if (x&lt;0 || x&gt;=Width || y&lt;0 || y&gt;=Height) return 0;
        int rgb = img.getRGB(x, y);
        int c=0;
        switch (rgb) {
        case 0xffffff00: c=1; break;
        case 0xff000000: c=3; break;
        default: 
            int r=0xff&amp;(rgb&gt;&gt;16);
            int g=0xff&amp;(rgb&gt;&gt; 8);
            int b=0xff&amp;(rgb&gt;&gt; 0);
            if (30&lt;=r&amp;&amp;r&lt;=220&amp;&amp;r==g&amp;&amp;g==b) c=2;
        }
        return c;
    }

    private static BufferedImage read(String file) throws IOException {
        File img = new File("./resources/"+file);
        BufferedImage in = ImageIO.read(img);
        return in;
    }

}




I think the Race Track gives you a better impression how FirstRacer works.