Page 1 of 2

Sample Solving Program

Posted: Tue May 15, 2007 6:25 pm
by adum
i have written a small and simple Java program to demonstrate how an automatic solver works for the Mortal Coil game. this also features automatic puzzle retrieval and submission (just enter name and pw as command line params). of course, the algorithm isn't the fastest! =)

Code: Select all

import java.io.*;
import java.net.URL;
import java.util.Random;

// program to solve the puzzle at http://www.hacker.org/coil/
public class MortalCoilSolver {
    private static int[][] offsets = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    private static char[] offNames = {'L', 'D', 'R', 'U'};
    private Random r = new Random();
    private static String name, pw;
    private int targetFill, boardX, boardY, startX = -1, startY = -1, board[][];
    private String boardString;

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.out.println("usage:\nMortalCoilSolver name pw\n");
            return;
        }
        name = args[0]; pw = args[1];
        MortalCoilSolver mcs = new MortalCoilSolver();
        while (true) {
            mcs.go();
            Thread.sleep(2000);
        }
    }

    private void go() throws Exception {
        URL u;
        u = new URL("http://www.hacker.org/coil/index.php?name=" + name + "&password=" + pw);
        InputStream is = u.openStream();
        input2level(is);
        System.out.println(this);
        solve();
    }

    public String toString() {
        String s = "";
        for (int j = 0; j < boardY; j++) {
            for (int i = 0; i < boardX; i++) {
                s += board[i][j] > 0 ? 'X' : '.';
            }
            if (j < boardY - 1) s += '\n';
        }
        return s;
    }

    public boolean solve() throws Exception {
        String path = findSolutionPath();
        System.out.println("solved at (" + startX + ", " + startY + ") : " + path);
        URL u;
        u = new URL("http://www.hacker.org/coil/index.php?name=" + name + 
                "&password=" + pw + "&path=" + path + "&x=" + startX + "&y=" + startY);
        InputStream is = u.openStream();
        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        while ((in.readLine()) != null) { }
        is.close();
        return false;
    }
    
    private String findSolutionPath() {
        while (true) { // search until done
            parseBoardString(); // reset board
            startX = r.nextInt(boardX); startY = r.nextInt(boardY); // random start
            if (!goodSquare(startX, startY)) continue;
            int x = startX, y = startY, fill = 1;
            String path = ""; // remember our path
            loop: while (true) {
                int tdir = r.nextInt(4); // choose random direction
                for (int dloop = 0; dloop < 3; dloop++) {
                    int dir = (dloop + tdir) % 4;
                    int offx = offsets[dir][0];
                    int offy = offsets[dir][1];
                    if (!goodSquare(x + offx, y + offy)) continue; // blocked
                    path += offNames[dir];
                    while (true) { // move until we hit something
                        board[x][y] = 2;
                        x += offx; y += offy;
                        if (!goodSquare(x, y)) break;
                        if (++fill == targetFill) return path; // got it
                    }
                    x -= offx; y -= offy; // we went one too far!
                    continue loop;
                }
                break;
            }
        }
    }
    
    private boolean goodSquare(int x, int y) {
        if (x < 0 || y < 0 || x >= boardX || y >= boardY) return false;
        return (board[x][y] == 0);
    }
    
    private void input2level(InputStream is) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        String line;
        while ((line = in.readLine()) != null) {
            if (!line.startsWith("    <param name=\"FlashVars\"")) continue;
            line = line.split("\"")[3]; // get just the value
            String[] ss = line.split("(=|&)"); // split up the name value pairs
            boardX = Integer.parseInt(ss[1]); boardY = Integer.parseInt(ss[3]);
            board = new int[boardX][boardY];
            boardString = ss[5];
            parseBoardString();
        }
        in.close();
    }

    private void parseBoardString() {
        int cnt = 0;
        for (int x = 0; x < boardX; x++)
            for (int y = 0; y < boardY; y++) {
                int a = boardString.charAt(x + y * boardX) == 'X' ? 1 : 0;
                board[x][y] = a;
                cnt += a;
            }
        targetFill = (boardX * boardY) - cnt; // how many squares we need to fill
    }
}

Posted: Fri Jul 13, 2007 5:18 am
by f1r3b4ll2000
umm... how do i use that code? :x i'm new at this.

Posted: Sat Jul 14, 2007 4:47 am
by Captain Segfault
Run it through a Java compiler.

Posted: Sat Jul 14, 2007 5:26 am
by f1r3b4ll2000
Captain Segfault wrote:Run it through a Java compiler.
how would I get a Java compiler? :?

Posted: Sun Jul 15, 2007 8:20 am
by Captain Segfault

Posted: Mon Jul 16, 2007 9:31 am
by Hacksign
hacksign@HackSignLapTop:~$ apt-cache search java|grep compiler
antlr - language tool for constructing recognizers, compilers etc
ecj - standalone version of the Eclipse Java compiler
ecj-bootstrap - standalone version of the Eclipse Java compiler (transitional package)
ecj-bootstrap-gcj - standalone version of the Eclipse Java compiler (transitional package)
ecj-gcj - standalone version of the Eclipse Java compiler (native version)
gcj - The GNU Java compiler
gcj-4.1 - The GNU compiler for Java(TM)


see? u can install ecj or gcj :)

Posted: Thu Dec 27, 2007 9:21 am
by camel
lol i automated the coil game via 100% perl ... from taking screenshots, recursion, moving mouse ... just to find out that youre supposed to automate it ... lolol

take care everyone im off to writing my starcraft hook

Posted: Thu Dec 27, 2007 9:41 am
by camel
hm lets see who beats #1 :-)

Posted: Thu Dec 27, 2007 9:31 pm
by pingoo
Oh, dudes.. Mortal Coiled seemed like a perfect way to exercise my lazy brain. And now I see it was nothing but a "programming challenge" :oops: Great ideea! I'll stick around for a while, looks like there's much to learn from you, guys. At the moment I know little about source code and hacking...but I am more willing to feed my curiosity than to spend a week on a deserted island with three gorgeous blondes. Hugs and kisses!

Posted: Thu Jun 26, 2008 9:30 am
by cdizzle420
pingoo wrote:but I am more willing to feed my curiosity than to spend a week on a deserted island with three gorgeous blondes.
what... are you gay or something?

smear the queer!!!

Posted: Thu Jun 26, 2008 5:15 pm
by Allosentient
maybe you've never met a hacker before

hacking

Posted: Sun Oct 12, 2008 4:21 pm
by johneilpower
it will be great...

:twisted:

Re: Sample Solving Program

Posted: Wed Jan 28, 2009 6:43 pm
by Project hash brown
[quote="adum"]i have written a small and simple Java program to demonstrate how an automatic solver works for the Mortal Coil game. this also features automatic puzzle retrieval and submission (just enter name and pw as command line params). of course, the algorithm isn't the fastest! =)

[code]
import java.io.*;
import java.net.URL;
import java.util.Random;

// program to solve the puzzle at http://www.hacker.org/coil/
public class MortalCoilSolver {
private static int[][] offsets = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
private static char[] offNames = {'L', 'D', 'R', 'U'};
private Random r = new Random();
private static String name, pw;
private int targetFill, boardX, boardY, startX = -1, startY = -1, board[][];
private String boardString;

public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.out.println("usage:\nMortalCoilSolver name pw\n");
return;
}
name = args[0]; pw = args[1];
MortalCoilSolver mcs = new MortalCoilSolver();
while (true) {
mcs.go();
Thread.sleep(2000);
}
}

private void go() throws Exception {
URL u;
u = new URL("http://www.hacker.org/coil/index.php?name=" + name + "&password=" + pw);
InputStream is = u.openStream();
input2level(is);
System.out.println(this);
solve();
}

public String toString() {
String s = "";
for (int j = 0; j < boardY; j++) {
for (int i = 0; i < boardX; i++) {
s += board[i][j] > 0 ? 'X' : '.';
}
if (j < boardY - 1) s += '\n';
}
return s;
}

public boolean solve() throws Exception {
String path = findSolutionPath();
System.out.println("solved at (" + startX + ", " + startY + ") : " + path);
URL u;
u = new URL("http://www.hacker.org/coil/index.php?name=" + name +
"&password=" + pw + "&path=" + path + "&x=" + startX + "&y=" + startY);
InputStream is = u.openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
while ((in.readLine()) != null) { }
is.close();
return false;
}

private String findSolutionPath() {
while (true) { // search until done
parseBoardString(); // reset board
startX = r.nextInt(boardX); startY = r.nextInt(boardY); // random start
if (!goodSquare(startX, startY)) continue;
int x = startX, y = startY, fill = 1;
String path = ""; // remember our path
loop: while (true) {
int tdir = r.nextInt(4); // choose random direction
for (int dloop = 0; dloop < 3; dloop++) {
int dir = (dloop + tdir) % 4;
int offx = offsets[dir][0];
int offy = offsets[dir][1];
if (!goodSquare(x + offx, y + offy)) continue; // blocked
path += offNames[dir];
while (true) { // move until we hit something
board[x][y] = 2;
x += offx; y += offy;
if (!goodSquare(x, y)) break;
if (++fill == targetFill) return path; // got it
}
x -= offx; y -= offy; // we went one too far!
continue loop;
}
break;
}
}
}

private boolean goodSquare(int x, int y) {
if (x < 0 || y < 0 || x >= boardX || y >= boardY) return false;
return (board[x][y] == 0);
}

private void input2level(InputStream is) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = in.readLine()) != null) {
if (!line.startsWith(" <param name="FlashVars"")) continue;
line = line.split(""")[3]; // get just the value
String[] ss = line.split("(=|&)"); // split up the name value pairs
boardX = Integer.parseInt(ss[1]); boardY = Integer.parseInt(ss[3]);
board = new int[boardX][boardY];
boardString = ss[5];
parseBoardString();
}
in.close();
}

private void parseBoardString() {
int cnt = 0;
for (int x = 0; x < boardX; x++)
for (int y = 0; y < boardY; y++) {
int a = boardString.charAt(x + y * boardX) == 'X' ? 1 : 0;
board[x][y] = a;
cnt += a;
}
targetFill = (boardX * boardY) - cnt; // how many squares we need to fill
}
}
[/code][/quote]


How long dis that take you? Do you know and good web sites that could teach me the basics?

Posted: Sat Jan 31, 2009 1:17 pm
by lechat
well...

http://java.sun.com/docs/books/tutorial/
http://www.java2s.com/Tutorial/Java/CatalogJava.htm
http://www.javabeginner.com/

The control question: what is the difference between the Abstract Class and the Interface?

Posted: Tue Apr 14, 2009 12:28 am
by CoreEvil
I wrote a little program to help me debug algorithmic problems with my solver, it reads a set of generated paths from a file, and lets you navigate through them while updating the board, so you can watch the progression of an algorithm through a map, you can also stop at any point and continue playing manually using arrow keys from where the solver ended. If anyone is interested, let me know and I'll post a link to the code.
(It's not a solver, it assumes that you already have a method for generating paths, if you don't , then it's not gonna be very helpful)
Here is a screen cap:
http://img178.imageshack.us/img178/1108/mcap.jpg