|
|
|
|
|
|
|
|
public class SnakeBot extends Bot{ |
|
|
public class SnakeBot extends Bot{ |
|
|
String moves = ""; |
|
|
String moves = ""; |
|
|
private int spiralNumber = 0; |
|
|
private int spiralNumber = 0; |
|
|
|
|
|
private boolean goesForward = true; |
|
|
private boolean ignoreStones = false; |
|
|
private boolean ignoreStones = false; |
|
|
public static void main(String[] args) { |
|
|
public static void main(String[] args) { |
|
|
Bot snakeBot = new SnakeBot(args); |
|
|
Bot snakeBot = new SnakeBot(args); |
|
|
|
|
|
|
|
|
protected SnakeBot(String[] args) { |
|
|
protected SnakeBot(String[] args) { |
|
|
super(args); |
|
|
super(args); |
|
|
} |
|
|
} |
|
|
//@TODO: find a better way to avoid collectedStones |
|
|
|
|
|
|
|
|
//@TODO: find a better way to avoid collected stones |
|
|
|
|
|
//@TODO: find a better way to collect stones |
|
|
protected char nextMove(View view) { |
|
|
protected char nextMove(View view) { |
|
|
boolean stoneDetected = view.data.contains("@"); |
|
|
boolean stoneDetected = view.data.contains("@"); |
|
|
char nextMove; |
|
|
char nextMove; |
|
|
|
|
|
|
|
|
nextMove = (countCollectedStonesLeft(view) <= countCollectedStonesRight(view)) ? '<' : '>'; |
|
|
nextMove = (countCollectedStonesLeft(view) <= countCollectedStonesRight(view)) ? '<' : '>'; |
|
|
ignoreStones = true; |
|
|
ignoreStones = true; |
|
|
} |
|
|
} |
|
|
/* |
|
|
|
|
|
* @TODO: |
|
|
|
|
|
* Avoiding endless loops due to trying to collect two stones at once. |
|
|
|
|
|
* Problem: stones located near to each other are ignored. |
|
|
|
|
|
* Tested: 20 tries; avgScore = 25.45/32; minScore = 19; maxScore = 29; trapped 1/20. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if(countUncollectedStones(view) > 1) ignoreStones = true; |
|
|
if(countUncollectedStones(view) > 1) ignoreStones = true; |
|
|
if(countCollectedStones(view) <= 2 && countUncollectedStones(view) <= 1) ignoreStones = false; |
|
|
if(countCollectedStones(view) <= 2 && countUncollectedStones(view) <= 1) ignoreStones = false; |
|
|
|
|
|
|
|
|
|
|
|
if(isStoneNearby(view)){ |
|
|
|
|
|
nextMove = goToNearbyStone(view); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return nextMove; |
|
|
return nextMove; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean isStoneNearby(View view){ |
|
|
|
|
|
int centerCoordinateOfView = view.width / 2; |
|
|
|
|
|
int frontCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView, centerCoordinateOfView - 1); |
|
|
|
|
|
int leftCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView - 1, centerCoordinateOfView); |
|
|
|
|
|
int rightCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView + 1, centerCoordinateOfView); |
|
|
|
|
|
|
|
|
|
|
|
boolean stoneIsInFront = view.data.charAt(frontCellIndex) == '@'; |
|
|
|
|
|
boolean stoneIsOnTheLeft = view.data.charAt(leftCellIndex) == '@'; |
|
|
|
|
|
boolean stoneIsOneTheRight = view.data.charAt(rightCellIndex) == '@'; |
|
|
|
|
|
|
|
|
|
|
|
return stoneIsInFront || stoneIsOnTheLeft || stoneIsOneTheRight; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private char goToNearbyStone(View view){ |
|
|
|
|
|
int centerCoordinateOfView = view.width / 2; |
|
|
|
|
|
int frontCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView, centerCoordinateOfView - 1); |
|
|
|
|
|
int leftCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView - 1, centerCoordinateOfView); |
|
|
|
|
|
int rightCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView + 1, centerCoordinateOfView); |
|
|
|
|
|
|
|
|
|
|
|
if(view.data.charAt(frontCellIndex) == '@') return '^'; |
|
|
|
|
|
if(view.data.charAt(leftCellIndex) == '@') return '<'; |
|
|
|
|
|
if(view.data.charAt(rightCellIndex) == '@') return '>'; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void resetMoves() { |
|
|
|
|
|
moves = ""; |
|
|
|
|
|
spiralNumber = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private int countUncollectedStones(View view) { |
|
|
private int countUncollectedStones(View view) { |
|
|
int count = 0; |
|
|
int count = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return rightStones; |
|
|
return rightStones; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private char walkByColumns(View view) { |
|
|
|
|
|
if(moves.isEmpty()){ |
|
|
|
|
|
moves = "^".repeat(28); |
|
|
|
|
|
moves += (goesForward ? ">" + "^".repeat(view.width) + ">" : "<" + "^".repeat(view.width) + "<"); |
|
|
|
|
|
goesForward = !goesForward; |
|
|
|
|
|
} |
|
|
|
|
|
char nextMove = moves.charAt(0); |
|
|
|
|
|
moves = moves.substring(1); |
|
|
|
|
|
return nextMove; |
|
|
|
|
|
} |
|
|
} |
|
|
} |