Amazon Interview Question for SDE1s


Country: India
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
3
of 3 vote

I am not sure what's the best solution for this. The below is my example.

public abstract class Monster
    {
        public int m_Health;// <=0 means die/disappear
        public int m_Level;// 1-100
        public float m_Defense;
        public string m_Name;

        public abstract int GetStatus();

        public abstract int Hit(int nDamage);
      
    }

    public class Monster1 : Monster
    {
        public Monster1(string sName, int health, int level)
        {
            m_Health = health;
            m_Name = sName;
            m_Level = level;

            //Eg. level is 1, so defense is 99% * damage, if level is 99, then defense is 1% * damage, very hard to kill the monster
            m_Defense = ((float)(100 - m_Level) / (float)100);
        }
        public override int Hit(int nDamage)
        {
            if (m_Health < 1)
            {
                return 0;//oops, die!
            }          

            m_Health -= (int)(nDamage * m_Defense);
            return GetStatus();
        }

        public override int GetStatus()
        {
            if (m_Health > 0)
            {
                Console.WriteLine("I am still alive [" + m_Health.ToString() + "], be careful!!");
            }
            else
            {
                Console.WriteLine("oops, die!");
            }
            return m_Health;
        }

    }

    public abstract class Weapon
    {
        public int m_Damage;// 1 bullet causes how many damage for the monster
        public int m_Level;// 1-100
        public int m_Ammo;
        public float m_AttackRate;
        public string m_Name;

        public abstract int Shot();

    }

    public class Weapon1 : Weapon
    {        

        public Weapon1(string sName, int level,int Damage, int ammo)
        {
            m_Damage = Damage;
            m_Name = sName;
            m_Level = level;
            m_Ammo = ammo;
            m_AttackRate = ((float)((float)m_Level / 100) + 1);
        }

        public override int Shot()
        {
            int nRet = 0;

            if (m_Ammo < 1) //no more bullets
            {
                Console.WriteLine("oops, run out of bullets!");
                return nRet;
            }
            m_Ammo -= 1;

            nRet = (int)(m_AttackRate * m_Damage);

            return nRet;
        }

    }
    //Maybe need an abstract class for hero, but ..., ignore it
    public class Heros
    {
        public void ShotMonster(Weapon wp, Monster ms)
        {
            for (int i = 0; i < 11; i++)
            {
                ms.Hit(wp.Shot());
            }
            
        }
    }

    public class TetGame
    {
        public static void TestGame1()
        {
            Weapon wp1 = new Weapon1("Gun", 5, 100, 10);
            Monster ms1 = new Monster1("Ghost", 300, 5);

            Heros ho1 = new Heros();
            ho1.ShotMonster(wp1,ms1);
        }
    }

Output:

I am still alive [202], be careful!!
I am still alive [104], be careful!!
I am still alive [6], be careful!!
oops, die!
oops, run out of bullets!

- Jasonhuangx March 11, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
2
of 2 vote

At first glance, this question appeals for inheritance but before using inheritance, it is important to understand what deviations are possible from base functionality. The question doesn't clearly speak about that. If properties of class will be same, there is no need for inheritance.

Different weapons have different predefined damage. We can define Weapon class with following properties -

public class Weapon{ 
    String name;
    int damagingEffect; 
    int bulletsLeft;
 
    public Weapon(name, damagingEffect, bulletsLeft) {// initialize all}

    // returns damaging effect
    public int fireWeapon() {
         if (bulletsLeft == 0) {
            throw new OutOfAmmoException(name);
         }
         bulletsLeft--;
         return damagingEffect;
    }

    public void reload(int newBullets) {
         bullets+= newBullets;
    }
}

As the game initializes, different instances of this class can represent different weapons.
Example
Weapon gun = new Weapon("gun", 3, 100);
Weapon rocketLauncher = new Weapon("Rocket Launcher", 50, 20);
Weapon missile = new Weapon("Missile", 100, 5);


Hero is initialized with Set of Weapons. He can use one as current.

public class Hero {
	Map<String, Weapon> weapons = new HashMap<String, Weapon>();
        Weapon currentWeapon;
        
        public Hero(Set<Weapon> weapons) {
           for(Weapon weapon:weapons) 
              this.weapons.put(weapon.name(), weapon);
           currentWeapon = weapons.get(0);
        }       
      
        public void setCurrentWeapon(String name) {
           if (!weapons.contains(name)) {
              throw new NoSuchWeaponException(name);
           }
           currentWeapon = weapons.get(name);
        }
 
        // returns damaging effect
        public int fire() {
           return currentWeapon.fireWeapon();
        }

        public boolean isUnArmed() {
            // check and return true if all weapons are out of bullets
        }
}

Monster can captured in a same class.

public class Monster {
    String name;
    int health;

    public Monster(String name, int health) {// initialize}

    // returns true if dead
    public boolean damageHealth(int damageEffect) {
       health-=damageEffect;
       return isDead();
    }

    public boolean isDead() { 
       return health<=0;
    } 
}

Example monsters -
Monster yeti = new Monster("Yeti", 20);
Monster dino = new Monster("Dinosaur", 40);


Then you initialize the Game, where all action is happening. Each level will have different instance of game class.

public class Game {
   Hero hero;
   int level;
   Map<String, Monster> monsters;
   enum LevelResult {WON, LOST, PLAYING};

   public Game(Hero hero, Set<Monster> monsters, int level) {//initialize}

   public void doEncounter(String monsterName) {
       Monster monster = monsters.get(monsterName);
       boolean isDead = monster.damageHealth(hero.fire());
       if (monster.isDead()) {
           monsters.remove(monsterName);
       }
   } 

   public void misFire() {
       hero.fire(); // didn't hit any monster
   }

   public LevelResult getLevelResult() {
       if (mosters.isEmpty()) { 
          return LevelResult.WON;
       } else if (hero.isUnArmed()) {
          return LevelResult.LOST;
       } else {
          return LevelResult.PLAYiNG;
       }
   }
}

- Harsh May 18, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Instead of doing that you could (and I think you should) do

//Maybe need an abstract class for hero, but ..., ignore it
    public class Heros
    {
	public Weapon weapon;

	public void setWeapon(Weapon weapon) {
		this.weapon = weapon;
	}

        public void ShotMonster(Monster ms)
        {
            for (int i = 0; i < 11; i++)
            {
                ms.Hit(this.wp.Shot()); // I dont know if it's the correct syntax
            }
            
        }
    }

    public class TetGame
    {
        public static void TestGame1()
        {
            Weapon wp1 = new Weapon1("Gun", 5, 100, 10);
            Monster ms1 = new Monster1("Ghost", 300, 5);

            Heros ho1 = new Heros();
            ho1.ShotMonster(wp1,ms1);
        }
    }

You could also make a MonsterFactory and a WeaponFactory to have more flexibility on how you create your Monsters/Weapons.

- Fernando April 07, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

game code:
class Game
{
private List<Monster> _monster;
private List<Weapon> _weapon;
public void initGame()
{
_monster = new List<Monster>(){
MonCreator.getInstance().CreateMonster("Normal ghost", new NormalLevel()),
MonCreator.getInstance().CreateMonster("Master ghost", new MasterLevel()),
MonCreator.getInstance().CreateMonster("Normal tiger", new NormalLevel()),
MonCreator.getInstance().CreateMonster("Master tiger", new MasterLevel()),};

_weapon = new List<Weapon>(){
WeapCreator.getInstance().CreateWeap("China arraw"),
WeapCreator.getInstance().CreateWeap("China arraw"),
WeapCreator.getInstance().CreateWeap("China arraw"),
WeapCreator.getInstance().CreateWeap("AK47 gun"),
WeapCreator.getInstance().CreateWeap("AK47 gun")};
}
public void play()
{
foreach (Weapon w in _weapon)
{
foreach (Monster m in _monster)
w.Shoot(m);
}
foreach (Monster m in _monster)
m.GetStatus();
}
}

class MonCreator
{
static private MonCreator _creator;
static public MonCreator getInstance()
{
if (null == _creator)
_creator = new MonCreator();
return _creator;
}
public Monster CreateMonster(string name, Level lv)
{
if (name.IndexOf("ghost") >= 0)
return new Monster(name, 50, 50, lv);
if (name.IndexOf("tiger") >= 0)
return new Monster(name, 30, 80, lv);
return new Monster(name, 30, 30, lv);
}
}
class WeapCreator
{
static private WeapCreator _creator;
static public WeapCreator getInstance()
{
if (null == _creator)
_creator = new WeapCreator();
return _creator;
}
public Weapon CreateWeap(string name)
{
if (name.IndexOf("arrow") >= 0)
return new Weapon(name, 0.6, 20);
if (name.IndexOf("gun") >= 0)
return new Weapon(name, 0.9, 100);
return new Weapon(name, 0.3, 20);
}
}
class Monster
{
private int _life;
private double _speed;
private Level _level;
private string _Name;
public double Speed() { return _speed * _level.Move(); }
public void Hit(int dam) { _life -= (int)(dam*_level.Defence()); }
public Monster(string name, int life, double speed, Level lv) { _Name = name; _life = life; _speed = speed; _level = lv; }
public void GetStatus() {
if(_life <=0)
System.Console.WriteLine("{0} is dead", _Name);
else
System.Console.WriteLine("{0} life is :{1}, and speed is: {2}",_Name,_life,_speed);
}
}
class Weapon
{
private double _acurate;
private int _damage;
private string _Name;
public Weapon(string name, double acurate, int damage) { _acurate = acurate; _Name = name; _damage = damage; }
public void Shoot(Monster monster)
{
Random r = new Random();
int temp = r.Next(100);
if(temp*_acurate > monster.Speed())
monster.Hit(_damage);
}
}

class Level
{
public virtual double Move() { return 1.0; }
public virtual double Defence() { return 1.0; }
}
class NormalLevel : Level
{
public override double Move() { return 1.0; }
public override double Defence() { return 1.0; }
}
class MasterLevel : Level
{
public override double Move() { return 1.5; }
public override double Defence() { return 0.7; }
}
clint code:
{
Game _game = new Game();
_game.initGame();
_game.play();
}

- Richard Xia April 15, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I used a strategy pattern to represent different Level of monster, It is complex, then decorator pattern maybe more suitable.
output like:

Normal ghost is dead
Master ghost is dead
Normal tiger is dead
Master tiger life is :30, and speed is: 80

- Anonymous April 15, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

We’ll use Flyweight design pattern for this game to create Monsters or Weapons. It’ll help us a lot because weapon or monster are not going to change their appearance or properties, all that can happen to them is extrinsic properties.
We’ll have a Monster Base class. Now Ghost, Demon, Sorceror etc. ae the concrete classes derived from this class. Same Design will be followed for Weapon class also. Each weapon class will also define the damage it’ll cause to monster.
We’ll have a Player class.
We’ll have a Game class which maintains the resource pool for the already created object. Any new request will be satisfied from this pool. Say once a monster is created and returned, we need t devise a mechanism where any loss to this monster is visible to this monster only and not to any other sharing monster. So we’ll have to use some extrinsic functions that don’t operate on this object but take help of this object. Say we use a wrapper object (Decorator Design Pattern) which contains this object and health information. When health is 0, the wrapper object dies and forgets the shared monster object but doesn’t delete it. I think shared pointers will come handy here. We’ll save a lot of cost by sharing mosnters and weapons among thousand of monster and weapon objects.

Now comes the point that monster and weapon properties will change based upon level. I think that we can assign this extra responsibility to the Wrapper classes. These wrapper classes can be created using Decorator Design Pattern. Game Class will work only with the Decorator object. So once a monster or weapon is requested, Monster and Weapon classes return already created object from resource pool but Decorator behaves differently (Based upon the Level) and attach different properties (health, attack etc.) to these objects.

- Pramod January 02, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More