Yet Another Blog!

As we work, we invent new tools, new ideas. Being associated with this "Information technology / Software Industry" for about 5 years now, would like to share a few tools and ideas, developed out of interest or needs. Therefore this blog.

Wednesday, March 17, 2010

Travian Roman Guide
[Please read if you are a Roman otherwise ignore]


I will be short and sweet. I have played as Romans in .comx-es. and teutons in ".in" servers initially as duals. I will share my experience with the tribe, ROMANS as I have played duals with some of the best ROMAN players.

An inspiring and very practical guide which I had studied long long back which I think is essential for a ROMAN is:

http://forum.travian.com/showthread.php?t=67436

So here is my little secret :
___________________________________________________________________

1. "GROWTH AND POPULATION" :

>> In the start, build barracks, no stable.

>> Reach level 7-8 tiles as soon as possible.

>> If your population is 400 you should ideally have 450 troops in the following ratio (this is till your tiles reach 7-8): Legs: 250, Prets: 200.

>> Do not attack Gauls in early stages.

>> Remember : Romans troops are very costly and you cannot lose them to "TRAPS".

>> Defend when needed.

>> User your 50 Legs to raid teutons.

>> Have a feeling that TEUTONS are FILTHY targets and GAULS are your freinds (you can pair with one Gaul).

>> Have 3 crannies.

>> Raid and raid using the 50 Legs.

>> Never keep those 50 legs in your villa (raid 214 X 7).
___________________________________________________________________

2. "CROSS ROAD" :

>> When you have reached tile levels 8-9. Decide whether to be offensive or defensive.
___________________________________________________________________
>> OFFENSIVE GUIDE :
___________________________________________________________________
>> Build a stable, academy, blacksmith.

>> Research "Equites Imperatoris."

>> Do not build, Imperians, they are not really needed at the moment.

>> Build a Equites Imperatoris Hero and 100 EIs at lvl 10.

>> Upgrade, blacksmith for EIs at least at lvl 2.

>> Upgrade, Market/Main Bulding and embassy to gain CPs.

>> If you are nearing level 10 tiles look for a cropper (for gold users in long term it does not matter).

>> Raid and raid and lot using EI(s) raiding will be slow but effective.

>> Gradually build the second village.

>> If you want to make the second village the capital make it and quickly build stable, academy, blacksmith.

>> Upgrade stable, academy and blacksmith.

>> Observation: Only good teutons research Spearmen early so for a long time only EI(s) will do.

The EI advantage: "They are not the fastest troops, but are a HORROR for unprepared enemies." Defending EI(s) is not advisable and not easy. Make use of your EI(s) to fullest.

>> Never raid oasis with "Imperians", use the EI advantage. Use combat simulator to see for yourself.

>> Observation: Romans do not, research "Equites Caesaris" saying its too costly this is a fatal mistake.

The EC advantage: "The Equites Caesaris are the heavy cavalry of Rome. They are very well armored and DEAL GREAT AMOUNTS OF DAMAGE."

I would advice Romans(offensive) to build Armoury and upgrade EC(s) in it, this will be beneficial when your are as-sleep and your troops aren't moving and somebody attacks you. EC's will take all the damage.

>> Gradually when you see that people are building cavalry defense unit, research "Imperians" (1.2 times your Cavalry).

>> Gradually add other villas to supply resources.

>> Move to a point where Imperian : Equites Imperatoris : Equites Caesaris is in ratio "5:3:1".

>> Keep raiding TEUTONS around you to keep a check on their troop count.

>> If somebody is growing kill his troops and make him a farm.

>> On s4.in with 90 EIs and 15 ECs. I have killed 300 Clubs, 60 Spears, 151 Axes and 10 Scouts and 15 Catas. Without losing much! (an A@rrows member who was growing).

>> Research Catas and Rams, and irritate(raid) weak teutons around you and have fun!

>> Keep growing tiles and troops to maintain the pop:troop ratio as 1:1.2-1.5 (for a hammer).

>> When your troop count(cavalry) reaches 1000s, then go for the Horse Drinking Trough.

>> When a HDT is done you will have the strongest cavalry on the server.

>> From random attack experiments by my friends it was proven that a well developed EI/EC becomes 1.1-1.6 times better in terms of attack then the Teutonic Knight.
___________________________________________________________________
3. "CITY WALL THE GREAT WALL OF CHINA" :
___________________________________________________________________
>> It is better to have higher levels of wall in your villa. For Romans its a defense blessing providing the highest, defense bonus.

>> When you have grown your tiles to 10 its time to have 15 level wall with defenses.

>> I managed "http://s4.travian.in/berichte.php?id=5235270" by having a lvl 12 wall.

The above is based on my personal experience, comments are welcome, you may follow, or you may find a better path.

If you find a better path please share that.

-- nutroy (http://s4.travian.in/)

Saturday, April 4, 2009

Watch Your Tongue!

Serialization :  When being asked, what is SERIALIZATION, I get answers which are really annoying. The following are some samples :)
  • "The process of writing the state of an object to a file!"
  • "Saving the object's state to the file system!"
  • "Writing the state of an object to a file using streams basically output streams!"
Only to a file? What about saving the object's state in a database? Will saving in database not involve 'Serialization'? The above answers are more ridiculous than they actually seem.

Big question, what is it? The following is a closer one to what actually it is :

"Object serialization is the process of saving an object's state to a sequence of bytes, as well as the process of rebuilding those bytes into a live object at some future time."  
                               (- Extract from Sun's Technical Article)

     So, where is this 'serialization' needed? The answer is simple when we write any information to the disc, we write as bytes or when we transfer information via wire to machines, we transfer as bytes. Hence, to save an object's state or to transfer an object's state via wire, we need to express the object's state as a sequence of bytes.

Also at the receiver's end we need to construct some meaningfull information out of those bytes, or when we re-read the bytes from the storage device. Hence the whole process of serialization.

     We should not encourage the use of 'de-serialization', because the whole process of state to bytes and then bytes to state gives it a complete meaning, which is serialization.

Transaction: What do we mean by a TRANSACTION? comming soon...


Hello World!

Could we write a simple program to continously print "Hello... ...World" in a single line, but "Hello... " and "...World" being print by different threads? This question was asked to me by one of my collegue (thanks to Saikat Manna).

Here is as an attempt (pardon me Saikat, is anything wrong! :D) :

import static java.lang.System.out;

/**
 * @author Kaushik Roy
 *
 */
public final class HelloWorldThread {
private static volatile String state = "HELLO";
/**
* @author Kaushik Roy
*
*/
static class HelloThread implements Runnable {
private Object  mutex;
/**
   * @see java.lang.Runnable#run()
*/
@Override
public void run() {
while (true) {
if ("HELLO".equals(state)) {
synchronized (mutex) {
out.print("Hello ... ");
state = "WORLD";
try {
mutex.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
  }
/**
* @param mutex
*/
public HelloThread(Object mutex) {
this.mutex = mutex;
}
  }
/**
* @author Kaushik Roy
*
*/
static class WorldThread implements Runnable {
private Object          mutex;
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while (true) {
if ("WORLD".equals(state)) {
synchronized (mutex) {
out.println(" ... World");
state = "HELLO";
mutex.notify();
}
}
}
}
/**
* @param mutex
*/
public WorldThread(Object mutex) {
this.mutex = mutex;
}
}
/**
* @param args
*/
public static void main(String[] args) {
Object mutex = new Object();

new Thread(new HelloThread(mutex)).start();
new Thread(new WorldThread(mutex)).start();
}
}

Hope this works! Here goes the sample 'output':

Hello ...  ... World
Hello ...  ... World
Hello ...  ... World
Hello ...  ... World
Hello ...  ... World
Hello ...  ... World
Hello ...  ... World
Hello ...  ... World
Hello ...  ... World

Nothing great about the output. This is a very simple example illustrating the use of wait( ) and notify( ) methods with a mutex. Sun tutorial's Producer-Consumer example is a better one.

PS: This article is for Kiran Wali.

Sunday, February 22, 2009

Hibernate's dirty check and mutables.

Consider a sample table with the following definition:

create table SHOPPING_ORDER (
ID BIGINT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(255) NOT NULL,
DESCRIPTION VARCHAR(255) NOT NULL,
PLACED_DATE TIMESTAMP NOT NULL,
PRIMARY KEY(ID)
);

The class for the data object of hibernate would look like:
// Generated Feb 22, 2009 6:51:39 PM by Hibernate Tools 3.2.1.GA
import static javax.persistence.GenerationType.IDENTITY;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
* ShoppingOrder generated by hbm2java
*/
@Entity
@Table(name = "shopping_order", catalog = "blog")
public class ShoppingOrder implements java.io.Serializable {

/**
*
*/
private static final long serialVersionUID = -5795228501571594686L;

private Long id;
private String name;
private String description;
private Date placedDate;

public ShoppingOrder() {
}

public ShoppingOrder(String name, String description, Date placedDate) {
this.name = name;
this.description = description;
this.placedDate = placedDate;
}

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID", unique = true, nullable = false)
public Long getId() {
return this.id;
}

public void setId(Long id) {
this.id = id;
}

@Column(name = "NAME", nullable = false)
public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

@Column(name = "DESCRIPTION", nullable = false)
public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "PLACED_DATE", nullable = false, length = 19)
public Date getPlacedDate() {
return this.placedDate;
}

public void setPlacedDate(Date placedDate) {
this.placedDate = placedDate;
}

}

Now lets try to create new shopping orders and save them to the database:

public class ShoppingOrders {
private Timestamp timestamp = new Timestamp(System.currentTimeMillis());

/**
* @param name
* @param description
* @return
*/
public ShoppingOrder createOrders(String name, String description) {
ShoppingOrder order = new ShoppingOrder();
order.setName(name);
order.setDescription(description);
timestamp.setTime(System.currentTimeMillis());
order.setPlacedDate(timestamp);
return order;
}

/**
* @param args
*/
public static void main(String[] args) {
Session openSession = HibernateUtils.getSessionFactory().openSession();
Transaction beginTransaction = openSession.beginTransaction();

ShoppingOrders orders = new ShoppingOrders();

for (int i = 0; i < 500; i++) {
openSession.save(orders.createOrders("Name" + i, "Description" + i));

}

beginTransaction.commit();
openSession.close();
HibernateUtils.getSessionFactory().close();
}
}




Hmm.., everything looks fine?

If you enable the "hibernate.show_sql" flag to see the SQL queries being executed, you will see SQL updates being fired apart from the SQL inserts which were expected. Oops!, where did these SQL updates come from, we were merely creating new "ShoppingOrder"(s)!

If you have noticed the "java.sql.Timestamp"'s (a mutable class) instance is being shared among all the "ShoppingOrder"(s) that are being created. On each creation and save of a "ShoppingOrder", the "setTime( )" method is being called on the mutable instance.

Say after 'N' "save( )" calls, hibernate flushes the session, on the creation of next "ShoppingOrder" when the "setTime( )" method is called it will make the already attached instances of "ShoppingOrder" dirty! This will trigger the updates which we discovered.

Thumb rule, whenever we associate a mutable instance to a DO's intance, to be on the defensive, we should clone it and associate the copy.

In this case if the method, "setPlacedDate(java.sql.Date)" of the data object "ShoppingOrder" is modified as the following,
public void setPlacedDate(Date placedDate) {
this.placedDate = new Timestamp(placedDate.getTime());
}
then, the problem of updates would get rectified!

We should also do a defensive copy in the constructor of the data object "ShoppingOrder".

public ShoppingOrder(String name, String description, Date placedDate) {
this.name = name;
this.description = description;
this.placedDate = new TimeStamp(placedDate.getTime());
}
Why... :)

Followers

Archives