- Welcome!
- Abstraction Programming and Education
- Four Questions about Math Education
- The Future of Education
- A New Curriculum
- Writing with Less Writing
- The Goals of Learneroo - How I Hope to Improve Online Education
- The Java Job Market
- Kickstarter Success, Thank you Backers!
- Comments and Chat
- Path to Learning Java
- Aristotle on Learning
- Programming Bootcamps as an Alternative to Lectures
- The Education Dialog
- The Mean, the Median and Startup Equity
- Membership on Learneroo
- Discounts - Satisfaction Guaranteed!
- Lecture Videos and Learning
- Learn Programming by Example and with Challenges
- Java Coding Contest Results
- Coding the Java Explorer
- New - Java Budget Bootcamp
- Java Jobs II
- The Web for All - Kickstarter
- Finding a Web Host and Creating a Site
- Web Development for Entrepreneurs, Marketers and Biz-devs
- Web Development for Non-Developers
- Lessons from my Unsuccessful Kickstarter Project
- Changes on Learneroo
- Learneroo on Reddit and the Powers of 10
- Free Membership for Teachers
- New Algorithms Tutorials
- Free Membership on Learneroo
- Algorithms for Interviews and Jobs
- Interactive Cartoon Guide to Ruby on Rails
- Kickstarter Launched
- Learn Web Development Kickstarter - Q & A
- Ruby on Rails for Web Designers
- Web App Framework vs. CMS vs. Website Builder
- Real Web Development for Entrepreneurs
- What Programming Language Should You Learn?
- Lessons from my Successful Kickstarter Project
- Ruby Coding Contest Live!
- Understanding Recursion
- Ruby Coding Contest Recap
A blog about education. On Learneroo Itself. Blog Home
Coding the Java Explorer
You could see the whole board in all the challenges in the Advanced Java Explorer except the last. This means you could hand-code the Explorer to defeat the enemies and one contestant actually used this approach to beat the challenges. You look at the board and figure out the plan of attack and then encode it in a long String / Array of moves where the explorer looks at the next character to determine each turn.
A more general solution would be to create an AI for the explorer to analyze the board each turn and decide what to do. You can build up the AI from level to level, until it easily beats the final level. This was the approach mostly followed by the winner of the contest, Egor Kulikov. This post will look at solving the first two challenges.
In this level, the explorer needs to get by a Pawn and then reach the Goal.
▥▥▥▥▥▥▥▥▥▥ ▥♖...▥...▥ ▥....▥...▥ ▥...♟....▥ ▥..♟.....▥ ▥▥▥.....↢▥ ▥........▥ ▥......↢.▥ ▥.....▥.☆▥ ▥▥▥▥▥▥▥▥▥▥
A direct move-or-fight method would die when facing the Archers, so you need to recharge at some point. If you just recharge when you're energy is low, you'll get stuck in a loop when facing the Archer's attack. Instead, you should recharge when low on energy unless you're under attack. One way to solve it is to keep track of your health, and only recharge if it's low but not decreasing. This is similar to the Archer and Archers! levels from Java Explorer 1D and 2D:
class Player{
int health = 100;
public void play(Explorer explorer){
if(explorer.getHealth() < 90 && health == explorer.getHealth()){
explorer.recharge();
}
else if(explorer.getSpace(Direction.DOWN).isEnemy()){
explorer.poke(Direction.DOWN);
}
else if(explorer.getSpace(Direction.RIGHT).isWall()){
explorer.walk(Direction.DOWN);
}
else{
explorer.walk(Direction.RIGHT);
}
health = explorer.getHealth();
}
}
Knights are much more dangerous than other enemies, since one you come into their line of sight, there's almost no escaping them. To defeat them you need to carefully encounter one at a time, bring it away from its friends and fight it there. Then you can recharge and face another Knight, until you've cleared a path forward.
Although you can use lookAround
in this level to detect Knights, you can also use your previous code to detect when you're under attack and then follow the 'flight then fight' pattern. You'll just need to make sure you don't get to close to more than one Knight. In the code below, the Explorer pauses when moving down to see if anything attacks.
class Player {
int y = 1;
int moves = 0;
int health = 100;
boolean flee = false;
public void play(Explorer explorer){
if(explorer.getHealth() < 80 && !underAttack(explorer)){
explorer.recharge();
}
else if(attackEnemy(explorer)){
}
else if(flee){
if(y>2){
explorer.walk(Direction.UP);
}
else{
explorer.walk(Direction.DOWN); //meet your enemy
flee=false;
}
}
else if(underAttack(explorer) && y>2){ //retreat
flee = true;
y--;
explorer.walk(Direction.UP);
}
else if(explorer.getSpace(Direction.RIGHT).isWall()){
if(moves%2==0){ //wait a move to see if attacked
explorer.walk(Direction.DOWN);
y++;
}
}
else{
explorer.walk(Direction.RIGHT);
}
health = explorer.getHealth();
moves++;
}
boolean attackEnemy(Explorer explorer){
for(Direction d: Direction.values()){
if(explorer.getSpace(d).isEnemy()){
explorer.poke(d);
return true;
}
}
return false;
}
boolean underAttack(Explorer explorer){
return health != explorer.getHealth();
}
}
The alternative would be to just hand-code a solution, as mentioned above. For example, this solution reaches the goal in only 51 moves:
class Player{
int move = 0;
char[] ar = "rrr>>>>>>>hhhhhhhrrrrddulvvvvvvvvhhhhhhhhhrlddddddr".toCharArray();
public void play(Explorer explorer){
switch(ar[move]){
case 'r':
explorer.walk(Direction.RIGHT);
break;
case 'l':
explorer.walk(Direction.LEFT);
break;
case 'd':
explorer.walk(Direction.DOWN);
break;
case 'u':
explorer.walk(Direction.UP);
break;
case '>':
explorer.poke(Direction.RIGHT);
break;
case '<':
explorer.poke(Direction.LEFT);
break;
case '^':
explorer.poke(Direction.UP);
break;
case 'v':
explorer.poke(Direction.DOWN);
break;
case 'h':
explorer.recharge();
break;
}
move++;
}
}