Wednesday, July 30, 2014

Two player game program - e.g. TIC TAC TOE...

This is an abstract State class
public abstract class State {
 
  // This method is abstract, the extending class has to give the implementation
  // It will return a list of all the possible children from the current state.
  public abstract List<State> getChildren();
  public abstract String getTurn();
  public abstract void setTurn(String turn);
 
  // Find out who is the winner from the current state.
  public abstract String getWinner();
 
  // Check if the game has been finished or not.
  public abstract boolean isGameOver();
 
  // I have given the implementation specifically for TIC-TAC-TOE.
  // You can override this functionality in the extending class according to your game requirements.
  // 
  // This function will give the score of the current state.
  // Then you can compare it with its siblings to check which state will be better to move to..
  //
 public int minimax()
 {
  
  if(!getWinner().equals(""))
  {
   if("X".equalsIgnoreCase(getWinner()))
   {
    return 1;
   }
   if("O".equalsIgnoreCase(getWinner()))
   {
    return -1;
   }
   if("draw".equalsIgnoreCase(getWinner()))
   {
    return 0;
   }
  }
  List<State> children = getChildren();
  if(getTurn().equals("X"))
  {
   int maxScore = -100;
   for(State child : children)
   {
    int childScore = child.minimax();
    if(childScore > maxScore)
    {
     maxScore = childScore;
    }
   }
   return maxScore;
  }
  else
  {
   int minScore = 100;
   for(State child : children)
   {
    int childScore = child.minimax();
    if(childScore < minScore)
    {
     minScore = childScore;
    }
   }
   return minScore;   
  }

 }
}

Extend the above State class and give some implementations...as follows:
Lets assume the class to be TttState...
We'll override the abstract methods of the parent class State..

Give a member variable that'll hold the current state of your game...In my case, I have taken it as array..

// This variable is going to hold the current state of your game.
 // It can be any depending on your game requirements...
 private String state[][] = null ;

Give a copy constructor

public TttState(State x)
 {
  TttState tState = (TttState)x;
  state = new String[3][3];
  for(int i=0;i<=2; i++)
  {
   for(int j=0; j<=2;j++)
   {
    this.state[i][j]=tState.state[i][j];
   }
  }
  this.turn = x.getTurn();
 }
Give a default constructor
public TttState() {
  state = new String[3][3];
  for(int i=0;i<=2; i++)
  {
   for(int j=0; j<=2;j++)
   {
    this.state[i][j]="";
   }
  }
  this.turn = "X";
 }
Give a toString implementation, so that you can print the current state
public String toString()
 {
  StringBuilder sb = new StringBuilder("");
  for(int i=0;i<=2; i++)
  {
   for(int j=0; j<=2;j++)
   {
    if(state[i][j].equals(""))
    {
     sb.append("-");
    }
    else
    {
     sb.append(state[i][j]);
    }
    sb.append("\t");
   }
   sb.append("\n");
  }
  return sb.toString();
 }
Override the method getWinner() as follows
public String getWinner()
 {
  // ROW CHECK BEGINS 
  if(state[0][0].equalsIgnoreCase("X") && state[0][1].equalsIgnoreCase("X") && state[0][2].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[0][0].equalsIgnoreCase("O") && state[0][1].equalsIgnoreCase("O") && state[0][2].equalsIgnoreCase("O"))
  {
   return "O";
  }
  if(state[1][0].equalsIgnoreCase("X") && state[1][1].equalsIgnoreCase("X") && state[1][2].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[1][0].equalsIgnoreCase("O") && state[1][1].equalsIgnoreCase("O") && state[1][2].equalsIgnoreCase("O"))
  {
   return "O";
  }
  if(state[2][0].equalsIgnoreCase("X") && state[2][1].equalsIgnoreCase("X") && state[2][2].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[2][0].equalsIgnoreCase("O") && state[2][1].equalsIgnoreCase("O") && state[2][2].equalsIgnoreCase("O"))
  {
   return "O";
  }
  
  // COLUMN CHECK BEGINS 
  if(state[0][0].equalsIgnoreCase("X") && state[1][0].equalsIgnoreCase("X") && state[2][0].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[0][0].equalsIgnoreCase("O") && state[1][0].equalsIgnoreCase("O") && state[2][0].equalsIgnoreCase("O"))
  {
   return "O";
  }
  if(state[0][1].equalsIgnoreCase("X") && state[1][1].equalsIgnoreCase("X") && state[2][1].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[0][1].equalsIgnoreCase("O") && state[1][1].equalsIgnoreCase("O") && state[2][1].equalsIgnoreCase("O"))
  {
   return "O";
  }
  if(state[0][2].equalsIgnoreCase("X") && state[1][2].equalsIgnoreCase("X") && state[2][2].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[0][2].equalsIgnoreCase("O") && state[1][2].equalsIgnoreCase("O") && state[2][2].equalsIgnoreCase("O"))
  {
   return "O";
  }
  // DIAGNONAL CHECKS 
  if(state[0][0].equalsIgnoreCase("X") && state[1][1].equalsIgnoreCase("X") && state[2][2].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[0][0].equalsIgnoreCase("O") && state[1][1].equalsIgnoreCase("O") && state[2][2].equalsIgnoreCase("O"))
  {
   return "O";
  }
  
  if(state[0][2].equalsIgnoreCase("X") && state[1][1].equalsIgnoreCase("X") && state[2][0].equalsIgnoreCase("X"))
  {
   return "X";
  }
  if(state[0][2].equalsIgnoreCase("O") && state[1][1].equalsIgnoreCase("O") && state[2][0].equalsIgnoreCase("O"))
  {
   return "O";
  }  
  int nonBlank = 0;
  for(int i=0;i<=2;i++)
  {
   for(int j=0;j<=2;j++)
   {
    if(!state[i][j].equals(""))
    {
     nonBlank++;
    }
   }
  }
  if(nonBlank==9)
  {
   return "draw";
  }
  
  return "";
 }
Override the method isGameOver()
public boolean isGameOver()
 {
  if(!getWinner().equals("") && !getWinner().equals("draw"))
  {
   return true;
  }
  else
  {
   return false;
  }
 }
Override the method getChildren()
@Override
 public List<State> getChildren() {
  List<State> children = new ArrayList<State>();
  if(turn.equals("X"))
  {
   for(int i=0;i<=2; i++)
   {
    for(int j=0; j<=2;j++)
    {
     if(state[i][j].equals(""))
     {
      TttState child = new TttState(this);
      child.state[i][j]="X";
      String newTurn = "O";
      child.setTurn(newTurn);
      children.add(child);
     }
    }
   }
  }
  else
  {
   for(int i=0;i<=2; i++)
   {
    for(int j=0; j<=2;j++)
    {
     if(state[i][j].equals(""))
     {
      TttState child = new TttState(this);
      child.state[i][j]="O";
      String newTurn = "X";
      child.setTurn(newTurn);
      children.add(child);
     }
    }
   }
  }
  return children;
 }
Override getTurn and setTurn
public String getTurn() {
  return turn;
 }

 public void setTurn(String turn) {
  this.turn = turn;
 }
Your main program will look something like this:
public static void main(String args[])
 {
  TttState x = new TttState();
  System.out.println("WINNER : " + x.getWinner());
  x.setTurn("X");
  Scanner sc = new Scanner(System.in);
  while(!x.isGameOver())
  {
   String xIndex = sc.nextLine();
   String yIndex = sc.nextLine();
   int xint = Integer.parseInt(xIndex);
   int yint = Integer.parseInt(yIndex);
   x.getState()[xint][yint]="X";
   x.setTurn("O");
   int minScore = 100;
   List<State> children = x.getChildren();
   TttState bestMove = new TttState(x);
   for(State child : children)
   {
    int childScore = child.minimax();
    // We are using < because we are always evaluating
    // the best move from the options that O player has....
    if(childScore < minScore)
    {
     minScore = childScore;
     bestMove = (TttState)child;
     bestMove.setTurn("X");
    }
   }
   System.out.print(bestMove);
   x = bestMove;
  }
  System.out.println("GAME OVER...");

 }


Monday, July 7, 2014

Things to remember while creating Custom Exception in Java

Things to remember while creating Custom Exception in Java

1) Don’t' use Exception to control application behaviour. Exception handling is very expensive as it require native calls to copy stacktrace, each time exception is created.

2) While creating custom exception, prefer to create an unchecked, Runtime exception than a checked exception, especially if you know that client is not going to take any reactive action other than logging.

3) If your custom exception is created by passing another exception, then always contain original Exception as source; use constructor which takes Exception rather than only message String.

4) Apart from providing default no argument constructor on your custom Exception class, consider providing at least two more constructors, one which should accept a failure message and other which can accept another Throwable as cause.

5) If possible avoid creating custom Exception and re-use existing, standard Exception classes from JDK itself. Most of the time you will realize that all you need is a form of IllegalArgumentException or ParseException or something similar.

6) While defining custom Exception, one of the most common mistake programmer make is to think that constructor is inherited from java.lang.Exception class, for example they think that their Exception class will automatically inherit default no argument constructor and the one which takes a String message. This is not true. Constructor is not inherited in Java, not even default constructor. It's actually added by compiler rather than inherited from parent class. That's why I have declared two constructor, one with String parameter and other as Throwable parameter :

public NoSuchProductException(String message, int productId) 
{ 
    super(message); 
    this.productId = productId; 
} 
public NoSuchProductException(String message, int productId, Throwable cause) 
{ 
    super(message, cause); 
    this.productId = productId; 
}

This is actually standard way of creating custom Exception in Java. In order to save time, you can even create template of above class in Eclipse IDE.

7) For readable code, it's good practice to append the string Exception to the names of all classes that inherit (directly or indirectly) from the Exception class e.g. instead of naming your class IncorrectPassword, name it IncorrectPasswordException.

There is lot more given on the following link:
http://javarevisited.blogspot.in/2014/06/how-to-create-custom-exception-in-java.html

How to use decorator pattern, when the class to decorate is final

I have an inbuilt class in java - String
Now I have made 3 classes
  1. AddHashCode
  2. ToLowerCase
  3. AddLength


I want to create a class, which has toString method overridden while selecting one or more of the above classes.

For example:
I want a class, which has toString method, which has the features of AddHashCode and ToLowerCase
or
I want a class, which has toString method, which has the features of all of the above classes.

So, lets do it with Decorator Pattern.

But the problem with Decorator Pattern is, that the classes you create must implement the String class.....But String class is final..
So I have tweaked the Decorator Design Pattern a bit, though it closely resembles the purpose of Decorator design pattern.

Create the following three classes

Class AddHashCode

public class AddHashCode {
 private String t ;
 public AddHashCode(String s)
 {
  t = s;
 }
 public String toString()
 {
  return t.toString() + ":" + t.hashCode();
 }
}

Class ToLowerCase

public class ToLowerCase {
 String ac;
 public ToLowerCase(String ac)
 {
  this.ac = ac;
 }
 public String toString()
 {
  return ac.toString().toLowerCase();
 }
}


Class AddLength

public class AddLength{
 private String t ;
 public AddLength(String s)
 {
  t = s;
 }
 public String toString()
 {
  return t.toString() + ":"+t.toString().length();
 }
}

Use this as follows:
public class Main {
 public static void main(String[] args)
 {
                // Limitation and difference here will be, that on the LHS, the class used is ToLowerCase
                // and cannot be a String as was the case with usual Decorators.
  ToLowerCase x = new ToLowerCase
                                    (new AddHashCode
                                         (new String("YOGESH").toString()).toString());
  System.out.println(x.toString());
  AddHashCode y = new AddHashCode
                                    (new ToLowerCase
                                         (new AddLength(new String("YOGESH").toString())
                                    .toString())
                                .toString());
  System.out.println(y.toString());
 }
}