/** Tests for successful placement of an offer. */
  @Test
  public void testSuccessfullOfferPlacement() {
    final SpeakerNPC npc = getNPC("Harold");
    final Engine en = npc.getEngine();
    player.addXP(1700);

    Item item = SingletonRepository.getEntityManager().getItem("axe");
    StackableItem playersMoney =
        (StackableItem) SingletonRepository.getEntityManager().getItem("money");
    Integer price = Integer.valueOf(1500);
    playersMoney.setQuantity(price);
    player.equipToInventoryOnly(item);
    player.equipToInventoryOnly(playersMoney);

    assertTrue(en.step(player, "hello"));
    assertEquals("Welcome to Semos trading center. How can I #help you?", getReply(npc));

    assertTrue(en.step(player, "sell axe 150000"));
    assertEquals(
        "Do you want to sell an axe for 150000 money? It would cost you 1500 money.",
        getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals(
        "I added your offer to the trading center and took the fee of 1500.", getReply(npc));

    assertTrue(en.step(player, "bye"));
    assertEquals(
        "Visit me again to see available offers, make a new offer or fetch your earnings!",
        getReply(npc));
  }
  /** Tests for successful placement of an offer with more than one item. */
  @Test
  public void testSellPlural() {
    final SpeakerNPC npc = getNPC("Harold");
    final Engine en = npc.getEngine();
    player.addXP(1700);

    PlayerTestHelper.equipWithStackableItem(player, "coal", 10);
    PlayerTestHelper.equipWithMoney(player, 100);

    assertTrue(en.step(player, "hello"));
    assertEquals("Welcome to Semos trading center. How can I #help you?", getReply(npc));

    assertTrue(en.step(player, "sell 2 coals for 1000"));
    assertEquals(
        "Do you want to sell 2 pieces of coal for total 1000 money? It would cost you 10 money.",
        getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("I added your offer to the trading center and took the fee of 10.", getReply(npc));

    assertTrue(en.step(player, "bye"));
    assertEquals(
        "Visit me again to see available offers, make a new offer or fetch your earnings!",
        getReply(npc));
  }
  /**
   * Check that creating offers for zero price cost. (Harold needs his provision; we need to charge
   * for those to prevent cheating the trade score)
   */
  @Test
  public void testCreateOfferForFree() {
    final SpeakerNPC npc = getNPC("Harold");
    final Engine en = npc.getEngine();
    player.addXP(1700);

    PlayerTestHelper.equipWithItem(player, "axe");
    PlayerTestHelper.equipWithStackableItem(player, "money", 42);

    assertTrue(en.step(player, "hello"));
    assertEquals("Welcome to Semos trading center. How can I #help you?", getReply(npc));

    assertTrue(en.step(player, "sell axe 0"));
    assertEquals(
        "Do you want to sell an axe for 0 money? It would cost you 1 money.", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("I added your offer to the trading center and took the fee of 1.", getReply(npc));

    assertEquals(
        "Making a free offer should cost",
        41,
        ((StackableItem) player.getFirstEquipped("money")).getQuantity());

    assertTrue(en.step(player, "bye"));
    assertEquals(
        "Visit me again to see available offers, make a new offer or fetch your earnings!",
        getReply(npc));
  }
  /** Tests for hiAndBye. */
  @Test
  public void testHiAndBye() {
    final SpeakerNPC npc = getNPC("Fleur");
    final Engine en = npc.getEngine();

    assertTrue(en.step(player, "hi Fleur"));
    assertEquals("Hi! Are you here to #trade?", getReply(npc));

    assertTrue(en.step(player, "bye"));
    assertEquals("Come back soon!", getReply(npc));
  }
  /** Tests for sellIceCream. */
  @Test
  public void testSellIceCream() {
    final SpeakerNPC npc = getNPC("Sam");
    final Engine en = npc.getEngine();

    assertTrue(en.step(player, "hi Sam"));
    assertEquals("Hi. Can I #offer you an ice cream?", getReply(npc));

    // Currently there are no response to sell sentences for Sam.
    assertFalse(en.step(player, "sell"));
  }
  /** Tests for hiAndBye. */
  @Test
  public void testHiAndBye() {
    final SpeakerNPC npc = getNPC("Sam");
    assertNotNull(npc);
    final Engine en = npc.getEngine();

    assertTrue(en.step(player, "hello"));
    assertEquals("Hi. Can I #offer you an ice cream?", getReply(npc));

    assertTrue(en.step(player, "bye"));
    assertEquals("Bye, enjoy your day!", getReply(npc));
  }
  /** Tests for trying to put multiple non stackable items in one offer. */
  @Test
  public void testSellPluralNonStackable() {
    final SpeakerNPC npc = getNPC("Harold");
    final Engine en = npc.getEngine();
    player.addXP(1700);

    PlayerTestHelper.equipWithItem(player, "dagger");
    PlayerTestHelper.equipWithMoney(player, 100);

    assertTrue(en.step(player, "hello"));
    assertEquals("Welcome to Semos trading center. How can I #help you?", getReply(npc));

    assertTrue(en.step(player, "sell 2 daggers for 1000"));
    assertEquals("Sorry, you can only put those for sale as individual items.", getReply(npc));

    assertTrue(en.step(player, "bye"));
    assertEquals(
        "Visit me again to see available offers, make a new offer or fetch your earnings!",
        getReply(npc));
  }
  @Test
  public void testOldQuest() {
    final int xp = player.getXP();
    final double karma = player.getKarma();
    LinkedList<String> questHistory = new LinkedList<String>();

    assertTrue(quest.getHistory(player).isEmpty());
    player.setQuest(questSlot, "start");
    questHistory.add("I do agree to help Morgrin.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "hi");
    assertEquals("Go down and kill the creatures, no time left.", getReply(npc));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    player.setSharedKill("spider");
    questHistory.add("I have killed a spider in the basement.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "hi");
    assertEquals("Go down and kill the creatures, no time left.", getReply(npc));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    player.setSharedKill("poisonous spider");
    questHistory.add("I have killed a poisonous spider in the basement.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "hi");
    assertEquals("Go down and kill the creatures, no time left.", getReply(npc));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    player.setSharedKill("giant spider");
    questHistory.add("I have killed a giant spider in the basement.");
    questHistory.add(
        "I have killed all 3 spiders in the basement. Now I go back to Morgrin to fetch my reward.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "hi");
    assertEquals(
        "Oh thank you my friend. Here you have something special, I got it from a Magican. Who he was I do not know. What the egg's good for, I do not know. I only know, it could be useful for you.",
        getReply(npc));
    assertTrue(player.isEquipped("mythical egg"));
    assertThat(player.getXP(), greaterThan(xp));
    assertThat(player.getKarma(), greaterThan(karma));
    assertTrue(player.getQuest(questSlot).startsWith("killed"));
    questHistory.clear();
    questHistory.add(
        "I have killed all spiders in the magic school basement and got a mythical egg.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));
  }
  /**
   * Check that creating offers without a price fails and offers for items not owned by the player
   */
  @Test
  public void testCreateInvalidOffer() {
    final SpeakerNPC npc = getNPC("Harold");
    final Engine en = npc.getEngine();
    player.addXP(1700);

    PlayerTestHelper.equipWithItem(player, "axe");
    PlayerTestHelper.equipWithStackableItem(player, "money", 42);

    assertTrue(en.step(player, "hello"));
    assertEquals("Welcome to Semos trading center. How can I #help you?", getReply(npc));

    assertTrue(en.step(player, "sell axe"));
    assertEquals("I did not understand you. Please say \"sell item price\".", getReply(npc));

    assertTrue(en.step(player, "sell vampire cloak 100"));
    assertEquals("Sorry, but I don't think you have any vampire cloaks.", getReply(npc));

    assertTrue(en.step(player, "bye"));
    assertEquals(
        "Visit me again to see available offers, make a new offer or fetch your earnings!",
        getReply(npc));
  }
  /** Test selling a container item. */
  @Test
  public void testSellContainer() {
    final SpeakerNPC npc = getNPC("Harold");
    final Engine en = npc.getEngine();
    player.addXP(1700);

    Item item = SingletonRepository.getEntityManager().getItem("keyring");
    StackableItem playersMoney =
        (StackableItem) SingletonRepository.getEntityManager().getItem("money");
    Integer price = Integer.valueOf(1500);
    playersMoney.setQuantity(price);
    player.equipToInventoryOnly(item);
    player.equipToInventoryOnly(playersMoney);

    Item key = SingletonRepository.getEntityManager().getItem("dungeon silver key");
    item.getSlot("content").add(key);

    assertTrue(en.step(player, "hello"));
    assertEquals("Welcome to Semos trading center. How can I #help you?", getReply(npc));

    // Try first selling it when it's not empty
    assertTrue(en.step(player, "sell keyring 150000"));
    assertEquals("Please empty your keyring first.", getReply(npc));
    assertTrue(player.isEquipped("keyring"));
    assertTrue(player.isEquipped("dungeon silver key"));

    // Then after emptying it
    item.getSlot("content").clear();
    assertTrue(en.step(player, "sell keyring 150000"));
    assertEquals(
        "Do you want to sell a keyring for 150000 money? It would cost you 1500 money.",
        getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals(
        "I added your offer to the trading center and took the fee of 1500.", getReply(npc));
    assertFalse(player.isEquipped("keyring"));
    assertFalse(player.isEquipped("dungeon silver key"));

    assertTrue(en.step(player, "bye"));
    assertEquals(
        "Visit me again to see available offers, make a new offer or fetch your earnings!",
        getReply(npc));
  }
  @Test
  public void quest() {

    final Player player = PlayerTestHelper.createPlayer("player");

    final Engine en = hayunn.getEngine();
    en.step(player, "hi");
    // we assume the player has already completed the meet hayunn quest
    // so that we know which of the greetings he will use
    player.setQuest("meet_hayunn", "done");
    assertTrue(player.isQuestCompleted("meet_hayunn"));
    assertTrue(hayunn.isTalking());
    assertEquals(
        "Hi. I bet you've been sent here to learn about adventuring from me. First, lets see what you're made of. Go and kill a rat outside, you should be able to find one easily. Do you want to learn how to attack it, before you go?",
        getReply(hayunn));
    en.step(player, "quest");
    assertEquals(
        "My mouth is dry, but I can't be seen to abandon this teaching room! Could you bring me some #beer from the #tavern?",
        getReply(hayunn));
    en.step(player, "yes");
    assertTrue(player.hasQuest("beer_hayunn"));
    en.step(player, "bye");
    assertFalse(hayunn.isTalking());
    assertEquals("start", player.getQuest("beer_hayunn"));
    final StackableItem beer = new StackableItem("beer", "", "", null);
    beer.setQuantity(1);
    beer.setID(new ID(2, "testzone"));
    player.getSlot("bag").add(beer);
    assertEquals(1, player.getNumberOfEquipped("beer"));
    en.step(player, "hi");
    en.step(player, "yes");
    assertEquals("done", player.getQuest("beer_hayunn"));
    en.step(player, "bye");
    // reject
    final Player player2 = PlayerTestHelper.createPlayer("player");

    en.step(player2, "hi");
    player2.setQuest("meet_hayunn", "done");
    assertTrue(player2.isQuestCompleted("meet_hayunn"));
    assertTrue(hayunn.isTalking());
    assertEquals(
        "Hi. I bet you've been sent here to learn about adventuring from me. First, lets see what you're made of. Go and kill a rat outside, you should be able to find one easily. Do you want to learn how to attack it, before you go?",
        getReply(hayunn));
    en.step(player2, "quest");
    assertEquals(
        "My mouth is dry, but I can't be seen to abandon this teaching room! Could you bring me some #beer from the #tavern?",
        getReply(hayunn));
    en.step(player2, "no");
    assertTrue(player2.hasQuest("beer_hayunn"));
    assertEquals("rejected", player2.getQuest("beer_hayunn"));
    en.step(player2, "bye");
  }
  /** Tests for buyFlower. */
  @Test
  public void testBuyFlower() {
    final SpeakerNPC npc = getNPC("Fleur");
    final Engine en = npc.getEngine();

    assertTrue(en.step(player, "hi"));
    assertEquals("Hi! Are you here to #trade?", getReply(npc));

    assertTrue(en.step(player, "job"));
    assertEquals("I sell roses in this here market.", getReply(npc));

    assertTrue(en.step(player, "trade"));
    assertEquals("I sell rose.", getReply(npc));

    // There is currently no quest response defined for Fleur.
    assertFalse(en.step(player, "quest"));

    assertTrue(en.step(player, "buy"));
    assertEquals("A rose will cost 50. Do you want to buy it?", getReply(npc));
    assertTrue(en.step(player, "no"));
    assertEquals("Ok, how else may I help you?", getReply(npc));

    assertTrue(en.step(player, "buy dog"));
    assertEquals("Sorry, I don't sell dogs.", getReply(npc));

    assertTrue(en.step(player, "buy candle"));
    assertEquals("Sorry, I don't sell candles.", getReply(npc));

    assertTrue(en.step(player, "buy a glass of wine"));
    assertEquals("Sorry, I don't sell glasses of wine.", getReply(npc));

    assertTrue(en.step(player, "buy rose"));
    assertEquals("A rose will cost 50. Do you want to buy it?", getReply(npc));

    assertTrue(en.step(player, "no"));
    assertEquals("Ok, how else may I help you?", getReply(npc));

    assertTrue(en.step(player, "buy rose"));
    assertEquals("A rose will cost 50. Do you want to buy it?", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("Sorry, you don't have enough money!", getReply(npc));

    assertTrue(en.step(player, "buy two roses"));
    assertEquals("2 roses will cost 100. Do you want to buy them?", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("Sorry, you don't have enough money!", getReply(npc));

    // equip with enough money to buy one rose
    assertTrue(equipWithMoney(player, 50));
    assertTrue(en.step(player, "buy rose"));
    assertEquals("A rose will cost 50. Do you want to buy it?", getReply(npc));

    assertFalse(player.isEquipped("rose"));

    assertTrue(en.step(player, "yes"));
    assertEquals("Congratulations! Here is your rose!", getReply(npc));

    assertTrue(player.isEquipped("rose"));

    // equip with enough money to buy five roses
    assertTrue(equipWithMoney(player, 250));
    assertTrue(en.step(player, "buy 5 roses"));
    assertEquals("5 roses will cost 250. Do you want to buy them?", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("Congratulations! Here are your roses!", getReply(npc));

    assertTrue(player.isEquipped("rose", 6));
    assertFalse(player.isEquipped("rose", 7));
  }
  /** Tests for buyIceCream. */
  @Test
  public void testBuyIceCream() {
    final SpeakerNPC npc = getNPC("Sam");
    final Engine en = npc.getEngine();

    assertTrue(en.step(player, "hi"));
    assertEquals("Hi. Can I #offer you an ice cream?", getReply(npc));

    assertTrue(en.step(player, "job"));
    assertEquals("I sell delicious ice creams.", getReply(npc));

    assertTrue(en.step(player, "offer"));
    assertEquals("I sell ice cream.", getReply(npc));

    assertTrue(en.step(player, "quest"));
    assertEquals("Mine's a simple life, I don't need a lot.", getReply(npc));

    assertTrue(en.step(player, "buy"));
    assertEquals("An ice cream will cost 30. Do you want to buy it?", getReply(npc));
    assertTrue(en.step(player, "no"));
    assertEquals("Ok, how else may I help you?", getReply(npc));

    assertTrue(en.step(player, "buy dog"));
    assertEquals("Sorry, I don't sell dogs.", getReply(npc));

    assertTrue(en.step(player, "buy house"));
    assertEquals("Sorry, I don't sell houses.", getReply(npc));

    assertTrue(en.step(player, "buy someunknownthing"));
    assertEquals("Sorry, I don't sell someunknownthings.", getReply(npc));

    assertTrue(en.step(player, "buy a bunch of socks"));
    assertEquals("Sorry, I don't sell bunches of socks.", getReply(npc));

    assertTrue(en.step(player, "buy 0 ice creams"));
    assertEquals("Sorry, how many ice creams do you want to buy?!", getReply(npc));

    assertTrue(en.step(player, "buy ice cream"));
    assertEquals("An ice cream will cost 30. Do you want to buy it?", getReply(npc));

    assertTrue(en.step(player, "no"));
    assertEquals("Ok, how else may I help you?", getReply(npc));

    assertTrue(en.step(player, "buy ice cream"));
    assertEquals("An ice cream will cost 30. Do you want to buy it?", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("Sorry, you don't have enough money!", getReply(npc));

    // equip with enough money to buy two ice creams
    assertTrue(equipWithMoney(player, 60));

    assertTrue(en.step(player, "buy three icecreams"));
    assertEquals("3 ice creams will cost 90. Do you want to buy them?", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("Sorry, you don't have enough money!", getReply(npc));

    assertTrue(en.step(player, "buy ice cream"));
    assertEquals("An ice cream will cost 30. Do you want to buy it?", getReply(npc));

    assertFalse(player.isEquipped("ice cream"));

    assertTrue(en.step(player, "yes"));
    assertEquals("Congratulations! Here is your ice cream!", getReply(npc));
    assertTrue(player.isEquipped("icecream", 1));

    assertTrue(en.step(player, "buy icecream"));
    assertEquals("An ice cream will cost 30. Do you want to buy it?", getReply(npc));

    assertTrue(en.step(player, "yes"));
    assertEquals("Congratulations! Here is your ice cream!", getReply(npc));
    assertTrue(player.isEquipped("icecream", 2));

    assertTrue(en.step(player, "buy 0 ice creams"));
    assertEquals("Sorry, how many ice creams do you want to buy?!", getReply(npc));

    // buying one ice cream by answering "yes" to npc's greeting
    assertTrue(equipWithMoney(player, 30));
    assertTrue(en.step(player, "bye"));
    assertEquals("Bye, enjoy your day!", getReply(npc));
    assertTrue(en.step(player, "hi"));
    assertEquals("Hi. Can I #offer you an ice cream?", getReply(npc));
    assertTrue(en.step(player, "yes"));
    assertEquals("An ice cream will cost 30. Do you want to buy it?", getReply(npc));
    assertTrue(en.step(player, "yes"));
    assertEquals("Congratulations! Here is your ice cream!", getReply(npc));
    assertTrue(player.isEquipped("icecream", 3));
  }
  /** Tests for quest. */
  @Test
  public void testQuest() {
    double oldkarma = player.getKarma();
    LinkedList<String> questHistory = new LinkedList<String>();

    assertTrue(quest.getHistory(player).isEmpty());
    en.step(player, "hi");
    assertEquals("Hello my friend. Nice day for walking isn't it?", getReply(npc));
    en.step(player, "yes");
    assertEquals("Fine fine, I hope you enjoy your day.", getReply(npc));

    en.step(player, "task");
    assertEquals(
        "Have you ever been to the basement of the school? The room is full of spiders and some could be dangerous, since the students do experiments! Would you like to help me with this 'little' problem?",
        getReply(npc));
    en.step(player, "no");
    assertEquals("Ok, I have to find someone else to do this 'little' job!", getReply(npc));
    assertThat(player.getKarma(), lessThan(oldkarma));
    questHistory.add("I do not agree to help Morgrin.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    questHistory.clear();
    oldkarma = player.getKarma();
    en.step(player, "hi");
    assertEquals("Hello my friend. Nice day for walking isn't it?", getReply(npc));
    en.step(player, "task");
    assertEquals(
        "Have you ever been to the basement of the school? The room is full of spiders and some could be dangerous, since the students do experiments! Would you like to help me with this 'little' problem?",
        getReply(npc));
    en.step(player, "yes");
    assertEquals("Fine. Go down to the basement and kill all the creatures there!", getReply(npc));
    questHistory.add("I do agree to help Morgrin.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    en.step(player, "hi");
    assertEquals("Go down and kill the creatures, no time left.", getReply(npc));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    killSpider("spider");
    assertEquals("spider", player.getQuest(questSlot, 1));
    questHistory.add("I have killed a spider in the basement.");
    assertEquals(questHistory, quest.getHistory(player));
    killSpider("poisonous spider");
    assertEquals("poisonous spider", player.getQuest(questSlot, 2));
    questHistory.add("I have killed a poisonous spider in the basement.");
    assertEquals(questHistory, quest.getHistory(player));
    killSpider("giant spider");
    assertEquals("giant spider", player.getQuest(questSlot, 3));
    questHistory.add("I have killed a giant spider in the basement.");
    questHistory.add(
        "I have killed all 3 spiders in the basement. Now I go back to Morgrin to fetch my reward.");
    assertEquals(questHistory, quest.getHistory(player));
    final int xp = player.getXP();
    final double karma = player.getKarma();

    questHistory.clear();
    en.step(player, "hi");
    // [15:13] kymara earns 5000 experience points.
    assertEquals(
        "Oh thank you my friend. Here you have something special, I got it from a Magican. Who he was I do not know. What the egg's good for, I do not know. I only know, it could be useful for you.",
        getReply(npc));
    assertTrue(player.isEquipped("mythical egg"));
    assertThat(player.getXP(), greaterThan(xp));
    assertThat(player.getKarma(), greaterThan(karma));
    assertTrue(player.getQuest(questSlot).startsWith("killed"));
    questHistory.add(
        "I have killed all spiders in the magic school basement and got a mythical egg.");
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    en.step(player, "hi");
    assertEquals("Hello my friend. Nice day for walking isn't it?", getReply(npc));
    en.step(player, "task");
    assertEquals(
        "Sorry there is nothing to do for you yet. But maybe you could come back later. I have to clean the school once a week.",
        getReply(npc));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    final double newKarma = player.getKarma();

    // [15:14] Changed the state of quest 'kill_all_spiders' from 'killed;1219677211115' to
    // 'killed;0'
    player.setQuest(questSlot, "killed;0");
    en.step(player, "hi");
    assertEquals("Hello my friend. Nice day for walking isn't it?", getReply(npc));
    en.step(player, "task");
    assertEquals("Would you like to help me again?", getReply(npc));
    en.step(player, "no");
    assertThat(player.getKarma(), lessThan(newKarma));
    assertEquals("Ok, I have to find someone else to do this 'little' job!", getReply(npc));
    assertThat(player.getQuest(questSlot), is("rejected"));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));

    en.step(player, "hi");
    assertEquals("Hello my friend. Nice day for walking isn't it?", getReply(npc));
    en.step(player, "task");
    assertEquals(
        "Have you ever been to the basement of the school? The room is full of spiders and some could be dangerous, since the students do experiments! Would you like to help me with this 'little' problem?",
        getReply(npc));
    en.step(player, "yes");
    assertEquals("Fine. Go down to the basement and kill all the creatures there!", getReply(npc));
    en.step(player, "bye");
    assertEquals("Bye.", getReply(npc));
  }
  @Test
  public void testQuest() {
    SpeakerNPC henry = SingletonRepository.getNPCList().get("Henry");
    Engine en1 = henry.getEngine();

    SpeakerNPC james = SingletonRepository.getNPCList().get("Sergeant James");
    Engine en2 = james.getEngine();

    // talk with Henry
    en1.step(player, "hi");
    assertEquals("Ssshh! Silence or you will attract more #dwarves.", getReply(henry));
    en1.step(player, "dwarves");
    assertEquals("They are everywhere! Their #kingdom must be close.", getReply(henry));
    en1.step(player, "kingdom");
    assertEquals("Kanmararn, the legendary city of the #dwarves.", getReply(henry));
    en1.step(player, "dwarves");
    assertEquals("They are everywhere! Their #kingdom must be close.", getReply(henry));
    en1.step(player, "kingdom");
    assertEquals("Kanmararn, the legendary city of the #dwarves.", getReply(henry));
    en1.step(player, "job");
    assertEquals("I'm a soldier in the army.", getReply(henry));
    en1.step(player, "offer");
    en1.step(player, "help");
    assertEquals(
        "I need help myself. I got separated from my #group. Now I'm all alone.", getReply(henry));
    en1.step(player, "group");
    assertEquals(
        "The General sent five of us to explore this area in search for #treasure.",
        getReply(henry));
    en1.step(player, "treasure");
    assertEquals("A big treasure is rumored to be #somewhere in this dungeon.", getReply(henry));
    en1.step(player, "somewhere");
    assertEquals("If you #help me I might give you a clue.", getReply(henry));
    en1.step(player, "help");
    assertEquals(
        "I need help myself. I got separated from my #group. Now I'm all alone.", getReply(henry));
    en1.step(player, "group");
    assertEquals(
        "The General sent five of us to explore this area in search for #treasure.",
        getReply(henry));
    en1.step(player, "task");
    assertEquals(
        "Find my #group, Peter, Tom, and Charles, prove it and I will reward you. Will you do it?",
        getReply(henry));
    en1.step(player, "group");
    assertEquals(
        "The General sent five of us to explore this area in search for #treasure. So, will you help me find them?",
        getReply(henry));
    en1.step(player, "no");
    assertEquals("OK. I understand. I'm scared of the #dwarves myself.", getReply(henry));
    en1.step(player, "task");
    assertEquals(
        "Find my #group, Peter, Tom, and Charles, prove it and I will reward you. Will you do it?",
        getReply(henry));
    en1.step(player, "group");
    assertEquals(
        "The General sent five of us to explore this area in search for #treasure. So, will you help me find them?",
        getReply(henry));
    en1.step(player, "yes");
    assertEquals("Thank you! I'll be waiting for your return.", getReply(henry));
    en1.step(player, "task");
    assertEquals(
        "Find my #group, Peter, Tom, and Charles, prove it and I will reward you. Will you do it?",
        getReply(henry));
    en1.step(player, "yes");
    assertEquals("Thank you! I'll be waiting for your return.", getReply(henry));
    en1.step(player, "map");
    assertEquals("If you find my friends, I will give you the map.", getReply(henry));
    en1.step(player, "treasure");
    assertEquals("A big treasure is rumored to be #somewhere in this dungeon.", getReply(henry));
    en1.step(player, "dwarves");
    assertEquals("They are everywhere! Their #kingdom must be close.", getReply(henry));
    en1.step(player, "kingodom");
    assertEquals("Kanmararn, the legendary city of the #dwarves.", getReply(henry));
    en1.step(player, "bye");
    assertEquals("Bye and be careful with all those dwarves around!", getReply(henry));

    en1.step(player, "hi");
    assertEquals("You didn't prove that you have found them all!", getReply(henry));
    en1.step(player, "bye");
    assertEquals("Bye and be careful with all those dwarves around!", getReply(henry));

    // You see the cold corpse of Peter. You can inspect it to see its contents.
    // You see a slightly rusty scale armor. It is heavily deformed by several strong hammer blows.
    // Stats are (DEF: 7).
    // take scale armor with me
    PlayerTestHelper.equipWithItem(player, "scale armor", "peter");

    // You see the rotten corpse of Tom. You can inspect it to see its contents.
    // take leather legs with me
    // You see torn leather legs that are heavily covered with blood. Stats are (DEF: 1).
    PlayerTestHelper.equipWithItem(player, "leather legs", "tom");

    // now talk with James
    en2.step(player, "hi");
    assertEquals("Good day, adventurer!", getReply(james));
    en2.step(player, "map");
    assertEquals(
        "The #treasure map that leads into the heart of the #dwarven #kingdom.", getReply(james));
    en2.step(player, "treasure");
    assertEquals("A big treasure is rumored to be somewhere in this dungeon.", getReply(james));
    en2.step(player, "dwarven kingdom");
    assertEquals("They are strong enemies! We're in their #kingdom.", getReply(james));
    en2.step(player, "kingdom");
    assertEquals("Kanmararn, the legendary kingdom of the #dwarves.", getReply(james));
    en2.step(player, "dwarves");
    assertEquals("They are strong enemies! We're in their #kingdom.", getReply(james));
    en2.step(player, "dwarven kingdom");
    assertEquals("They are strong enemies! We're in their #kingdom.", getReply(james));
    en2.step(player, "bye");
    assertEquals(
        "Good luck and better watch your back with all those dwarves around!", getReply(james));

    en2.step(player, "hi");
    assertEquals("Good day, adventurer!", getReply(james));
    en2.step(player, "task");
    assertEquals(
        "Find my fugitive soldier and bring him to me ... or at least the #map he's carrying.",
        getReply(james));
    en2.step(player, "bye");
    assertEquals(
        "Good luck and better watch your back with all those dwarves around!", getReply(james));
    // You see the slightly rotten corpse of Charles. You can inspect it to see its contents.
    // You read: "IOU 250 money. (signed) McPegleg"
    // take IOU with me
    PlayerTestHelper.equipWithItem(player, "note", "charles");
    en2.step(player, "hi");

    // drop leather legs for testing
    player.drop("leather legs");

    en1.step(player, "hi");
    assertEquals("You didn't prove that you have found them all!", getReply(henry));
    en1.step(player, "bye");
    assertEquals("Bye and be careful with all those dwarves around!", getReply(henry));

    // take legs up again
    PlayerTestHelper.equipWithItem(player, "leather legs", "tom");

    assertFalse(player.isEquipped("map"));
    assertEquals(0, player.getXP());

    // back to Henry
    en1.step(player, "hi");
    assertEquals(
        "Oh my! Peter, Tom, and Charles are all dead? *cries*. Anyway, here is your reward. And keep the IOU.",
        getReply(henry));
    // player earns 2500 experience points.
    assertEquals(2500, player.getXP());
    // You see a hand drawn map, but no matter how you look at it, nothing on it looks familiar.
    assertTrue(player.isEquipped("map"));
    assertEquals("map", player.getQuest(questSlot, 0));
    en1.step(player, "bye");
    assertEquals("Bye and be careful with all those dwarves around!", getReply(henry));

    // back to James
    en2.step(player, "hi");
    assertEquals("Good day, adventurer!", getReply(james));
    en2.step(player, "map");
    assertEquals("The map! Wonderful! Thank you. And here is your reward.", getReply(james));
    // player earns 5000 experience points.
    assertEquals(7500, player.getXP());
    // You see a pair of steel boots, fit for any soldier. It is a special quest reward for player,
    // and cannot be used by others. Stats are (DEF: 6).
    assertTrue(player.isEquipped("steel boots"));
    en2.step(player, "bye");
    assertEquals(
        "Good luck and better watch your back with all those dwarves around!", getReply(james));

    // back to Henry
    en1.step(player, "hi");
    assertEquals("Ssshh! Silence or you will attract more #dwarves.", getReply(henry));
    en1.step(player, "dwarves");
    assertEquals("They are everywhere! Their #kingdom must be close.", getReply(henry));
    en1.step(player, "task");
    assertEquals("I'm so sad that most of my friends are dead.", getReply(henry));

    assertEquals("done", player.getQuest(questSlot, 0));
  }
  /** Tests for quest. */
  @Test
  public void testQuest() {
    en.step(player, "hi");
    assertEquals(
        "Welcome to the bank of Semos! I am here to #help you manage your personal chest.",
        getReply(npc));
    assertTrue(quest.getHistory(player).isEmpty());

    en.step(player, "no");

    assertTrue(quest.getHistory(player).isEmpty());
    en.step(player, "task");
    assertTrue(quest.getHistory(player).isEmpty());
    assertEquals(
        "I'm so afraid of being robbed. I don't have any protection. Do you think you can help me?",
        getReply(npc));
    en.step(player, "no");
    java.util.List<String> questHistory = new LinkedList<String>();
    questHistory.add("I have met Dagobert. He is the consultant at the bank in Semos.");
    questHistory.add("He asked me to find a leather cuirass but I rejected his request.");
    assertEquals(questHistory, quest.getHistory(player));

    assertEquals("Well, then I guess I'll just duck and cover.", getReply(npc));
    en.step(player, "bye");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals("It was a pleasure to serve you.", getReply(npc));

    // -----------------------------------------------

    en.step(player, "hi");
    assertEquals(
        "Welcome to the bank of Semos! I am here to #help you manage your personal chest.",
        getReply(npc));
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "task");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals(
        "I'm so afraid of being robbed. I don't have any protection. Do you think you can help me?",
        getReply(npc));
    en.step(player, "yes");
    questHistory = new LinkedList<String>();
    questHistory.add("I have met Dagobert. He is the consultant at the bank in Semos.");
    questHistory.add("I promised to find a leather cuirass for him because he has been robbed.");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals(
        "Once I had a nice #'leather cuirass', but it was destroyed during the last robbery. If you find a new one, I'll give you a reward.",
        getReply(npc));
    en.step(player, "leather");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals(
        "A leather cuirass is the traditional cyclops armor. Some cyclopes are living in the dungeon deep under the city.",
        getReply(npc));
    en.step(player, "bye");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals("It was a pleasure to serve you.", getReply(npc));

    // -----------------------------------------------
    final Item item = ItemTestHelper.createItem("leather cuirass");
    player.getSlot("bag").add(item);
    questHistory.add("I found a leather cuirass and will take it to Dagobert.");
    assertEquals(questHistory, quest.getHistory(player));

    en.step(player, "hi");
    assertEquals(
        "Excuse me, please! I have noticed the leather cuirass you're carrying. Is it for me?",
        getReply(npc));
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "no");
    assertEquals(
        "Well then, I hope you find another one which you can give to me before I get robbed again.",
        getReply(npc));
    assertEquals(questHistory, quest.getHistory(player));
    en.step(player, "bye");
    assertEquals("It was a pleasure to serve you.", getReply(npc));
    assertEquals(questHistory, quest.getHistory(player));

    // -----------------------------------------------

    en.step(player, "hi");
    assertEquals(
        "Excuse me, please! I have noticed the leather cuirass you're carrying. Is it for me?",
        getReply(npc));
    assertEquals(questHistory, quest.getHistory(player));
    // put it out of bag onto ground, then say yes.
    player.drop("leather cuirass");
    assertFalse(player.isEquipped("leather cuirass"));
    questHistory.remove("I found a leather cuirass and will take it to Dagobert.");
    assertEquals(questHistory, quest.getHistory(player));
    npc.remove("text");
    en.step(player, "yes");
    // he doesn't do anything.
    assertEquals(questHistory, quest.getHistory(player));
    assertFalse(npc.has("text"));
    en.step(player, "bye");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals("It was a pleasure to serve you.", getReply(npc));

    // -----------------------------------------------

    player.getSlot("bag").add(item);
    en.step(player, "hi");
    questHistory.add("I found a leather cuirass and will take it to Dagobert.");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals(
        "Excuse me, please! I have noticed the leather cuirass you're carrying. Is it for me?",
        getReply(npc));
    final int xpBeforeReward = player.getXP();
    en.step(player, "yes");
    questHistory.add(
        "I took the leather cuirass to Dagobert. As a little thank you, he will allow me to use a private vault.");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals(
        "Oh, I am so thankful! Here is some gold I found ... ehm ... somewhere. Now that you have proven yourself a trusted customer, you may have access to your own private banking #vault any time you like.",
        getReply(npc));
    assertEquals(xpBeforeReward + 50, player.getXP());
    en.step(player, "task");
    assertEquals(questHistory, quest.getHistory(player));
    assertEquals(
        "Thank you very much for the armor, but I don't have any other task for you.",
        getReply(npc));
  }