Bug with `feel()` at the very first turn
lipsumar opened this issue · 1 comments
There seems to be bug when using feel at the very first turn. For some reason it thinks there is an enemy where there is none.
Environment
System:
- OS: macOS Sierra 10.12.3
- CPU: x64 Intel(R) Core(TM) i7-4750HQ CPU @ 2.00GHz
- Memory: 1.21 GB / 8.00 GB
- Shell: 3.2.57 - /bin/bash
Binaries:
- Node: 8.7.0 - /usr/local/bin/node
- Yarn: 1.2.1 - /usr/local/bin/yarn
- npm: 6.1.0 - /usr/local/bin/npm
npmGlobalPackages:
- @warriorjs/cli: 0.8.0
Steps to reproduce
At level 2, use this code:
class Player {
playTurn(warrior) {
const space = warrior.feel()
if (space.isUnit()) {
const unit = space.getUnit()
if (unit.isEnemy()) {
throw new Error('Unexpected enemy')
}
}
warrior.walk()
}
}Result:
╔════════╗
║@ s >║
╚════════╝
Invalid Player code: Unexpected enemy
Throwing an error is the only way i found to get feedback, warrior.think doesn't output anything at that point (very first turn).
Expected Behavior
space.isUnit() should return false
Actual Behavior
space.isUnit() returns true at the very first turn, even if the space in front of the warrior is clearly empty.
Hello @lipsumar. Thanks for opening the issue, but this isn't a bug. Let me explain:
The playTurn method execution and the output you see in the screen are completely disconnected. First, the playTurn method of each unit in the level (including your warrior) is executed (here and here). This sets the action to be performed on the unit's turn. Then, the performTurn method of each unit is executed, which finally performs the action selected for that turn (here and here). This is where play log entries like "Starbolt walks forward" are added, but they are not printed to the screen at this point. At the end of the entire play, the play log is returned and printed to the screen by the CLI. If you manually throw an error during that process, you're basically preventing the play log from being returned and then printed to the screen.
If you change your code to this, you'll see it behaves correctly:
class Player {
playTurn(warrior) {
const space = warrior.feel()
if (space.isUnit()) {
const unit = space.getUnit()
if (unit.isEnemy()) {
warrior.think('there is an enemy in front')
warrior.attack()
}
} else {
warrior.walk()
}
}
}