Program: 56113
Project: 56113
Buggy source:
@Override protected void action(){
switch (state) {
case AGGRESSIVE:
    break;
case HITTING:
  hitEnemy(enemy);
if (state != ESoldierState.HITTING) {
  break;
}
if (enemy.getHealth() <= 0) {
enemy=null;
changeStateTo(ESoldierState.SEARCH_FOR_ENEMIES);
break;
}
case SEARCH_FOR_ENEMIES:
IAttackable oldEnemy=enemy;
enemy=super.getStrategyGrid().getEnemyInSearchArea(getAttackPosition(),super.getMovable(),getSearchDistance(isInTower));
if (oldEnemy != null && oldEnemy != enemy) {
inSaveGotoMode=false;
}
if (enemy == null) {
if (defending) {
building.towerDefended(this);
defending=false;
}
changeStateTo(ESoldierState.AGGRESSIVE);
break;
}
if (isEnemyAttackable(enemy,isInTower)) {
super.lookInDirection(EDirection.getApproxDirection(super.getPos(),enemy.getPos()));
startAttackAnimation(enemy);
changeStateTo(ESoldierState.HITTING);
}
 else if (!isInTower) {
changeStateTo(ESoldierState.SEARCH_FOR_ENEMIES);
goToEnemy(enemy);
}
break;
case INIT_GOTO_TOWER:
if (super.getPos().equals(building.getDoor()) || super.goToPos(building.getDoor())) {
changeStateTo(ESoldierState.GOING_TO_TOWER);
}
 else {
building.requestFailed(this.movableType);
building=null;
state=ESoldierState.AGGRESSIVE;
}
break;
case GOING_TO_TOWER:
if (building.isNotDestroyed() && building.getPlayer() == super.getPlayer()) {
OccupyerPlace place=building.addSoldier(this);
super.setPosition(place.getPosition().calculatePoint(building.getDoor()));
super.enableNothingToDoAction(false);
super.setVisible(false);
if (isBowman()) {
this.inTowerAttackPosition=building.getTowerBowmanSearchPosition(place);
}
changeStateTo(ESoldierState.AGGRESSIVE);
isInTower=true;
}
 else {
changeStateTo(ESoldierState.AGGRESSIVE);
building=null;
}
break;
}
}

Fixed version (ground truth):
@Override protected void action(){
switch (state) {
case AGGRESSIVE:
    break;
case HITTING:
  hitEnemy(enemy);
if (state != ESoldierState.HITTING) {
  break;
}
if (enemy.getHealth() <= 0) {
enemy=null;
changeStateTo(ESoldierState.SEARCH_FOR_ENEMIES);
break;
}
case SEARCH_FOR_ENEMIES:
IAttackable oldEnemy=enemy;
enemy=super.getStrategyGrid().getEnemyInSearchArea(getAttackPosition(),super.getMovable(),getSearchDistance(isInTower),!defending);
if (oldEnemy != null && oldEnemy != enemy) {
inSaveGotoMode=false;
}
if (enemy == null) {
if (defending) {
building.towerDefended(this);
defending=false;
}
changeStateTo(ESoldierState.AGGRESSIVE);
break;
}
if (isEnemyAttackable(enemy,isInTower)) {
super.lookInDirection(EDirection.getApproxDirection(super.getPos(),enemy.getPos()));
startAttackAnimation(enemy);
changeStateTo(ESoldierState.HITTING);
}
 else if (!isInTower) {
changeStateTo(ESoldierState.SEARCH_FOR_ENEMIES);
goToEnemy(enemy);
}
 else {
changeStateTo(ESoldierState.SEARCH_FOR_ENEMIES);
}
break;
case INIT_GOTO_TOWER:
if (super.getPos().equals(building.getDoor()) || super.goToPos(building.getDoor())) {
changeStateTo(ESoldierState.GOING_TO_TOWER);
}
 else {
building.requestFailed(this.movableType);
building=null;
state=ESoldierState.AGGRESSIVE;
}
break;
case GOING_TO_TOWER:
if (building.isNotDestroyed() && building.getPlayer() == super.getPlayer()) {
OccupyerPlace place=building.addSoldier(this);
super.setPosition(place.getPosition().calculatePoint(building.getDoor()));
super.enableNothingToDoAction(false);
super.setVisible(false);
if (isBowman()) {
this.inTowerAttackPosition=building.getTowerBowmanSearchPosition(place);
}
changeStateTo(ESoldierState.AGGRESSIVE);
isInTower=true;
}
 else {
changeStateTo(ESoldierState.AGGRESSIVE);
building=null;
}
break;
}
}