Sunday 26 December 2010

LetterBloxHack

Situation:
So I found this awesome Robot class in Java that allows you to easily tell the computer where to click or what buttons to press on the keyboard etc. Sounds awesome right? I thought so. At the time I played a lot of games over at http://www.omgpop.com/. If anyone is familiar with LetterBlox, it's basically boggle. They give you some letters and from those letters you have to create words. Words are worth some value of points depending on rarity and size. The highest points win.

tl;dr Plays letterblox for you.

Solution:
This is part of the miGamer package I am working on. As we were having tournaments at university for who can play this game the best, and because it is easier, I went with another GIUless application. For this to work you must edit the code. As I am doing software engineering, having Eclipse open in the background was the norm. This allowed me to edit and run my program quickly and easily.

Notes:
  1. To prevent an outright win, I have not perfected the program. That is it won't do every single combination.
  2. Due to computer system restrictions and to prevent overloading the site, at most 10 combinations are attempted in a second.
  3. To use the application you must change the char[] letters = {'F', 'A', 'D', 'R', 'T', 'S'}; to the letters produced for each round.
  4. The application has a short delay before it starts to type the 'words' in. During this delay you should alt-Tab back to the game and click on the game. Otherwise you will see text typed into whatever is currently open.
  5. Due to the game being clever I have allowed the application to attempt typing multiples of the same letter, even if there is only one. This will simply leave off the last occurrences. This causes some of the problems with missing some words, see note 1 for why this has not been fixed.
  6. Again to due problems with typing when the game is over, this once caused my account to be disabled and ip suspended on the site, the application terminates after 60 seconds regardless of how far it has actually gotten to all attempts.
  7. A suggestion I have had is rather than typing hundreds of incorrect or repeated answers, is to store a dictionary of words and use a look up to see if the word exists before typing. This, however, would cause the program to run a lot slower and finding the same dictionary used by the game would also be very difficult.
  8. Again this code uses very little object oriented design ans so had I known how to do this in C, I would have.
The solution is in no way a perfect solution to the play the game. Although while using the application I have not lost a single match and so I believe it to be effective enough for the purpose it is built.

Code:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class LetterBloxHack extends Robot implements ActionListener{
 // The timer allows a combination to be created every .1 seconds
 private final Timer TIMER;
 // The counter allows the timer to be stopped after 1 minute
 private long counter = 0;
 // An array of the letters
 private int[] LETTERS;
 // An array of the order of the letters
 private int[] press;
 // The current length of word
 private int size = 1;

 /**
  * Creates the LetterBloxHack object and begins after .5 seconds
  * @param letters the letters to be sorted
  * @throws AWTException
  * @throws InterruptedException
  */
 private LetterBloxHack(char[] letters) throws AWTException, InterruptedException {
  super();
  // Sets the timer with a 50 millisecond delay
  TIMER = new Timer(0, this);
  // Initialises the LETTERS field
  this.LETTERS = new int[letters.length];
  for (int i = 0; i < letters.length; i++){
   this.LETTERS[i] = letters[i];
  }
  // Initialises the press field
  press = new int[letters.length];
  for (int i : press){
   i = 0;
  }
  press[0]--;
  // Short pause
  Thread.sleep(500);
  // Begins the timer
  TIMER.start();
 }

 /**
  * Starts the program.
  * The letters to be sorted are inputed here by the user.
  * @param args
  * @throws AWTException
  * @throws InterruptedException
  */
 public static void main(String[] args) throws AWTException, InterruptedException {
  char[] letters = {'F', 'A', 'D', 'R', 'T', 'S'};
  LetterBloxHack hack = new LetterBloxHack(letters);
 }
 /**
  * Performs a sort every .1 seconds
  */
 public void actionPerformed(ActionEvent arg0) {
  // Increments the counter to stop after 1800 computations
  counter++;
  if (counter > 1800){
   TIMER.stop();
  }

  // Increment the first pointer
  press[0]++;

  try{
   for (int i = 0; i < size; i++){
    // Checks if a pointer is above the maximum
    if (press[i] >= LETTERS.length){
     press[i] = 0;
     press[i + 1]++;
     if (size == (i + 1)){
      size = (i + 2);
      for (int j = 0; j < size; j++){
       press[j] = 0;
      }
     }
    }
   }

   //  Types the characters
   for (int i = 0; i < size; i++){
    keyPress(LETTERS[press[i]]);
    keyRelease(LETTERS[press[i]]);
   }
   //  Types an enter
   keyPress(10);
   keyRelease(10);
  } catch (ArrayIndexOutOfBoundsException e){
   //  Catches an exception that will represent the end of the sorting
   TIMER.stop();
  }
 }

}

2 comments:

  1. Awesome find man, glad you worked the program out, wish I knew how to program.

    ReplyDelete
  2. Don't have much use for this myself but it's an impressive bit of code.

    ReplyDelete