Page 2 of 2

Posted: Sat Apr 18, 2009 1:26 pm
by remzi
im new at this to how should i start with

Posted: Sat Oct 17, 2009 5:12 pm
by kenan
I COME FROM CHINA

Posted: Sun Apr 11, 2010 6:09 pm
by laz0r
Sorry if I'm being stupid, but surely since boardX is initialised to -1, then in findSolutionPath, the line

Code: Select all

startX = r.nextInt(boardX);
is going to throw an error? (trying to get the next random number with a negative seed)

Posted: Sun Apr 11, 2010 7:13 pm
by CodeX
The initial value of boardX is 0 (by default), -1 is assigned to StartX & StartY. boardX is also assigned before it gets to it's first use so it doesn't have to rely on the default unless a bad username/pass is used as the flow goes main->go->input2level<assignment here>->solve, with an invalid username or password the result of the query to the website is "invalid user" or "invalid password" so the loop that looks through the response wont find the key line which it assigns the values by so if it were to get to a random.nextInt(int) the worst you can get is r.nextInt(0) which I think returns 0.

Posted: Sun Apr 11, 2010 7:15 pm
by laz0r
Ah, thanks!

Re: Sample Solving Program

Posted: Mon Oct 03, 2011 7:48 pm
by Bliss
adum wrote: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
    }
}
Just wanted to ask in which line do we put the params name and password ?? I am confused :S
Shoud we make another class and run mcs from it ?

Posted: Tue Oct 04, 2011 6:32 am
by CodeX
The username and password aren't hardcoded, they are passed via the command line (inside the main method, line 19) into the class' name and pw variables (defined on line 10), these are then used in the solve and go methods which in turn pass data to the server via GET.
Hooray for having a quick look at the code