Category: Code

Android API & Java

So I’m kinda pissed

I bought a new Android HTC Desire HD which I’m fairly happy with.

I bought it with the intent of developing an application over the next year as part of my FYP for college.
During my dabbling in the first few hours, I began to realize why I hate Java and its every growing obscure complexity.

Lets look at 3 separate blunders from a fundamental level, in learning this new technology.

1.

First of all, lets leave Java aside a moment and focus on the Android.
intent, view, remoteview, activity, context, ApplicationContext, ActionBar, Fragment, IntentService, ListActivity …

If your a programmer and never looked at the Android API your probably wondering what these mean exactly?
EXACTLY – epic fail number one, this is the type of stuff you would expect from the Java community,
bizarre names to describe b****y windows and controls!

Coming from the Linux world i have no problem with odd programs with odd names, you get quiet used to it.  But to be fair in a programming world, the concepts, techniques etc are all the same regardless of the language.

That said, why change the name of Window / Frame / whatever to Activity, an activity could mean 200 bloody things!

From the Android API
” An activity is a single, focused thing that the user can do. Almost all activities interact with the user,
so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View). “

It’s a f******g window, why oh why did you have to go with these bizarre names,
as you get further into the API the names just get weired and weirder, its like learning French, who cares about French! This reminds me of SOAP in Java, JAX-WS, POJO, SEI, WSDL, GlassFish
and the list goes on with every increasing obscurity to define very simple web concepts.

2.

One more thing on Android API that i really wish they would get rid of
‘@‘ what about @?

As you start too look through the Java XML files, you start seeing all these @’s’
Soon enough, after some files, you realize that the @ symbol is some whatever overloaded depending on the context.

One moment its referencing a string element and in another an actual XML file.
As your code is ever growing, you start to see @‘s all over the place.
Your following @‘s along and by the time to find what exactly you’ve been trying to figure out,
You can’t remember were you were @.

3.

Modifiability, extensibility and dependency management.
Many of the controls which i have describe are implemented from almost concrete implementations.
Which means its very difficult to overload anything or change the behavior of a widget to do what you want.

Not only this, but when the API changes it breaks all previous code, and suddenly your left with code samples
on the android site, that simply don’t work, and you spend half your time figuring out what has changed in order to fix it!

Conclusion

These guys could actually learn something from Microsoft.
Yes these guys took Java and made something usable out of it C#.

Take a look at Windows Presentation Foundation Applications. The XAML makes sense
and the attributes of the elements make sense..


Konane MiniMax Algorythm

As part of intelligent systems i wrote a minimax algorithm

Here my implementation

Note* I’ve already submitted this, wouldn’t recommend you pawn it off as your own!

This report explains the implementation

import java.util.ArrayList;
import ie.ul.konane.Konane;
import ie.ul.konane.KonaneMove;
import ie.ul.konane.Player;

/**
 * MiniMax DFS Implementation to play Konane
 *
 * @author David O Neill ( 0813001 )
 * @version 4.0
 */

public class C0813001 extends Player
{
	private Konane currentState;

	/**
	 * Constructor
	 *
	 * @param pName ( The name Associated with the user )
	 */

	public C0813001( String pName )
	{
		super( pName );
	}

	/* (non-Javadoc)
	 * @see ie.ul.konane.Player#initialize(char)
	 */

	@Override
	public void initialize( char pColour )
	{
		this.name = "0813001";
		this.colour = pColour;
	}

	/**
	 * Instantiates the tree and gets the best move
	 *
	 * @return KonaneMove ( the next best move )
	 */

	private KonaneMove decideMyMove()
	{
		KonaneMove move = null;

		if( this.currentState.generateMoves( this.colour ).size() == 0 )
		{
			KonaneMove gameOver = new KonaneMove( 0 , 0 );
			gameOver.lostGame();
			return gameOver;
		}

		try
		{
			Tree tree = new Tree( this.currentState , this.colour );
			move = tree.getNextMove();
		}
		catch ( Exception e )
		{
			move = this.currentState.generateMoves( this.colour ).get( 0 );
			System.out.println( e.getMessage() );
			e.printStackTrace();
		}

		return move;
	}

	/* (non-Javadoc)
	 * @see ie.ul.konane.Player#makeMove(ie.ul.konane.Konane)
	 */

	@Override
	public KonaneMove makeMove( Konane game )
	{
		this.currentState = game;
		KonaneMove m = this.decideMyMove();
		return m;
	}

}

/**
 * MiniMax DFS Implementation to play Konane
 *
 * @author David O Neill ( 0813001 )
 * @version 4.0
 */

class Tree
{
	public static char PLAYER;
	public static char OPPONENT;
	public static int MAXDEPTH;
	public static int MAXVALUE;
	public static int MINVALUE;
	public static char heurisitic;
	private Node head;

	/**
	 * Java's version of a static constructor
	 */

	static
	{
		Tree.MAXDEPTH = 4;
		Tree.MAXVALUE = Integer.MAX_VALUE - ( Tree.MAXDEPTH * 5000 );
		Tree.MINVALUE = Integer.MIN_VALUE + ( Tree.MAXDEPTH * 5000 );
		Tree.heurisitic = 'b';
	}

	/**
	 * Constructor for the Tree
	 *
	 * @param board ( the current Konane )
	 * @param me ( the char representing my color )
	 */

	public Tree( Konane board , char me )
	{
		Tree.PLAYER = me;
		Tree.OPPONENT = ( me == 'w' ) ? 'b' : 'w';
		this.head = new Node( board );
	}

	/**
	 * After the tree has completed evaluating itself
	 * This is use to get the move that was pushed to the top
	 *
	 * @return KonaneMove ( the best move )
	 */

	public KonaneMove getNextMove()
	{
		return this.head.getBestChild().getLastMove();
	}
}

/**
 * MiniMax DFS Implementation to play Konane
 *
 * @author David O Neill ( 0813001 )
 * @version 4.0
 */

class Node
{
	private boolean max;

	private Konane currentBoard;
	private int currentDepth = 0;

	private ArrayList< Node > nextNodes = null;
	private ArrayList< KonaneMove > nextMoves = null;

	private KonaneMove moveThatCreatedState = null;
	private Node parentNode = null;
	private Node bestChildNode = null;

	private int heuristicValue = 0;

	/**
	 * Default constructor for the Head	 *
	 * This is the current state ( not considered a move )
	 * Begins the recursive generation of the Tree
	 *
	 * @param board ( Konane the current state )
	 */

	public Node( Konane board )
	{
		this.max = false;
		this.nextNodes = new ArrayList< Node >();
		this.currentBoard = board;
		this.currentDepth = 0;
		this.generateNextNodes( Tree.PLAYER , this.max );
	}

	/**
	 * Overloaded constructor
	 * Recursively generates next moves until MAXDEPTH is reached
	 * The base case is, if this node's heuristic value is better than its parents
	 * Then push this child Node to its parent's Node
	 *
	 * @param board ( Konane, that was generate for the next possible move )
	 * @param depth ( The depth of this Node )
	 * @param isMax ( Indicates whether its a min or max node )
	 * @param move ( The KonaneMove that generated this state )
	 * @param parent ( The parent of this state )
	 * @param whichPlayer ( The player at this depth )
	 */

	public Node( Konane board , int depth , boolean isMax , KonaneMove move , Node parent , char whichPlayer )
	{
		this.parentNode = parent;
		this.moveThatCreatedState = move;
		this.max = isMax;
		this.currentDepth = depth;
		this.nextNodes = new ArrayList< Node >();
		this.currentBoard = board;
		this.generateNextNodes( whichPlayer , this.max );

		if( parent.getBestChild() == null )
		{
			parent.setHeurisiticValue( this.heuristicValue , this );
		}
		else
		{
			if( this.max )
			{
				if( this.heuristicValue > parent.getHeurisiticValue() )
				{
					parent.setHeurisiticValue( this.heuristicValue , this );
				}
			}
			else
			{
				if( this.heuristicValue < parent.getHeurisiticValue() )
				{
					parent.setHeurisiticValue( this.heuristicValue , this );
				}
			}
		}
		this.nextMoves.clear();
		this.nextNodes.clear();
	}

	/**
	 * Gets the list of possible moves
	 * And generates the next Node states for each move
	 *
	 * @param whichPlayer ( The player at this depth )
	 * @param isMax ( is max or min )
	 */

	private void generateNextNodes( char whichPlayer , boolean isMax )
	{
		Konane newBoard;
		Node tempNode;
		KonaneMove possibleMove;

		this.nextMoves = this.currentBoard.generateMoves( whichPlayer );

		this.calculateHeuristicValue();

		if( this.currentDepth == Tree.MAXDEPTH )
		{
			return;
		}
		else
		{
			for ( int counter = 0 ; counter < this.nextMoves.size() ; counter++ )
			{
				newBoard = new Konane( this.currentBoard );
				possibleMove = new KonaneMove( this.nextMoves.get( counter ) );

				try
				{
					newBoard.makeMove( whichPlayer , possibleMove );
				}
				catch ( Exception e )
				{
					e.printStackTrace();
				}

				tempNode = new Node( newBoard , this.currentDepth + 1 , !isMax , possibleMove , this , ( whichPlayer == Tree.PLAYER ) ? Tree.OPPONENT : Tree.PLAYER );
				this.nextNodes.add( tempNode );
			}
		}
	}

	/**
	 * Calculates the heuristic value of this Node
	 */

	private void calculateHeuristicValue()
	{
		int mymoves = 1;
		int opmoves = 1;
		int heuristic = this.currentDepth;
		int mypieces = this.currentBoard.countSymbol( Tree.PLAYER );
		int oppieces = this.currentBoard.countSymbol( Tree.OPPONENT );

		if( this.currentDepth > 0 )
		{
			mymoves = ( this.max ) ? this.parentNode.getParentMoveCount() + 1 : this.nextMoves.size() + 1;
			opmoves = ( this.max ) ? this.nextMoves.size() + 1 : this.parentNode.getParentMoveCount() + 1;
		}

		if( this.currentDepth != Tree.MAXDEPTH && this.nextMoves.size() == 0 )
		{
			heuristic += ( this.max == true ) ? Tree.MAXVALUE : Tree.MINVALUE;
		}

		if( Tree.heurisitic == 'a' )
		{
			heuristic += ( int ) Math.round( mymoves - ( opmoves * 3 ) );
		}
		else if( Tree.heurisitic == 'b' )
		{
			heuristic += mymoves - opmoves;
		}
		else if( Tree.heurisitic == 'c' )
		{
			heuristic += ( int ) Math.round( mymoves / ( opmoves * 3 ) );
		}
		else if( Tree.heurisitic == 'd' )
		{
			heuristic += ( int ) Math.round( mymoves / opmoves );
		}
		else if( Tree.heurisitic == 'e' )
		{
			heuristic += ( int ) Math.round( mypieces / ( oppieces * 3 ) );
		}
		else if( Tree.heurisitic == 'f' )
		{
			heuristic += ( int ) Math.round( mypieces / oppieces );
		}
		else
		{
			heuristic += this.nextMoves.size();
		}

		this.heuristicValue = heuristic;
	}

	/**
	 * Gets a count of the moves for this Node
	 * @return ( number of possible moves )
	 */

	public int getParentMoveCount()
	{
		return this.nextMoves.size();
	}

	/**
	 * Gets the heuristic of this Node
	 *
	 * @return ( Heuristic Value )
	 */

	public int getHeurisiticValue()
	{
		return this.heuristicValue;
	}

	/**
	 * Gets the move that created this state
	 *
	 * @return ( The move )
	 */

	public KonaneMove getLastMove()
	{
		return this.moveThatCreatedState;
	}

	/**
	 * Sets the parent of a Node's, Heuristic value and besctChild
	 *
	 * @param betterHeuristicValue ( the heuristic of the child )
	 * @param betterChildNode ( the child )
	 */

	public void setHeurisiticValue( int betterHeuristicValue , Node betterChildNode )
	{
		this.heuristicValue = betterHeuristicValue;
		this.bestChildNode = betterChildNode;
	}

	/**
	 * Gets the parent of a Node
	 *
	 * @return ( the parent Node )
	 */

	public Node getParent()
	{
		return this.parentNode;
	}

	/**
	 * Gets the best child from a Node
	 * Typically used with the Head
	 *
	 * @return ( the best child )
	 */

	public Node getBestChild()
	{
		return this.bestChildNode;
	}

}

UL Clashing Timetable

So i got bored!,

I made this application that will fetch modules, courses or just plane students
timetables and overlay them onto one timetable showing free times.

You never know might come in handy?!

Download Visual Studio 2010 Solution


C# Mysql Project

I wrote this application as part of Database Systems module

Features

  1. Syntax highlighting
  2. SQL Validation
  3. File Management
  4. history
  5. much much more

If you want to extend it to work with other databases
just implement a concrete implementation of SQLDatabase

Download Visual Studio 2010 Solution


Rooting && Flashing the HTC Desire HD

One of the perks of flashing, is better battery life and more responsiveness

This is were i learned ( for HTC DESIRE HD ) REVOLUTION ROM
http://forum.xda-developers.com/showthread.php?t=984045

BEFORE YOU START

In general you want USB debugging on
you find it in the settings somewhere on your phone ( google it )

ROOT

 

  1. Market Place Download – VISIONary
  2. open VISIONary , hit TEMPROOT
  3. if successful hit PERMROOT

POSSIBLE DOWNGRADE

 

  1. If fail then stop
  2. go to the HD revolution page and read, If you need to downgrade, then follow the instructions on that page to do it

CHANGING THE BOOT LOADER

 

  1. Market Place Download – Rom manager
  2. Rom manager will replace your recovery boot loader with clockwork
  3. if you want to see the boot loader, turn off the phone, holding the ( VOL +- ) and POWER ( comes on about 10 seconds later )
  4. the HTC boot manager will load, using the VOL +- to navigate up / down, POWER button to select RECOVERY
  5. the RECOVERY menu has a few options

S-ENG OFF && S-RADIO OFF

 

  1. http://forum.xda-developers.com/showthread.php?t=855403
  2. http://forum.xda-developers.com/showthread.php?t=857537

BACKUP BEFORE FLASHING

 

  1. Choose BACKUP from the recovery menu – it will backup your current ROM SDCARD
  2. When the backup is complete, choose reboot
  3. Market Place Download – APN BACKUP AND RESORE
  4. Open APN and slect BACKUP to BACKUP your Mobile Providers Settings – it will save them to your SDCARD

GETTING READY FOR THE FLASH

 

  1. You should have the following
  2. ROOT ?
  3. Clockwork bootloader
  4. A BACKUP of your current rom
  5. APN BACKUP
  6. USB DEDUGGING ENABLED

THE FLASH

 

  1. Given that your new ROM (REVOLUTION) is on your SDCARD
  2. reboot and go to recovery
  3. Choose WIPE DATA
  4. DO NOT TURN OFF PHONE
  5. Choose restore from zip file
  6. choose REVOLUTION
  7. pop a champagne cork
  8. reboot and your done

POST FLASH

 

  1. Restore APN Settings, you can go onto your Cell Provider and put in these settings manually ( but we already backed them up )
  2. Download Andriod SDK
  3. SET HTC to CHARGE ONLY
  4. go to SDK folder / bin
  5. open up your browser and download APN BACKUP and restore to your pc
  6. put the APK installer file into the SDK folder
  7. CMD > sdb install ./APN installer.apk
  8. its now on your phone, you can use it to restore your APN settings