-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ex3.java
97 lines (82 loc) · 3 KB
/
Ex3.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
Ex3
My headingController uses a hierarchical design.
The direction of the wall is not selectable.
The direction opposite to the target is the second choice.
The target direction is the first choice.
The robot moves closer to the target with each step.
Because of this, if it needs to move in a direction away from the target, it will get stuck.
Based on my design, I will set the previously traveled path as the second choice.
*/
import uk.ac.warwick.dcs.maze.logic.IRobot;
public class Ex3 {
/**
* Determine if the target is north of the robot
*
* @param robot Robot object
* @return 1 = North / -1 = South / 0 = same latitudee
*/
private byte isTargetNorth(IRobot robot) {
if (robot.getLocation().y == robot.getTargetLocation().y) return 0;
else return (byte)(robot.getLocation().y > robot.getTargetLocation().y?1:-1);
}
/**
* Determine if the target is East of the robot
*
* @param robot Robot object
* @return 1 = East / -1 = West / 0 = same latitudee
*/
private byte isTargetEast(IRobot robot) {
if (robot.getLocation().x == robot.getTargetLocation().x) return 0;
else return (byte)(robot.getLocation().x > robot.getTargetLocation().x?-1:1);
}
/**
* Determine the status of the specified direction
*
* @param robot Robot object
* @param direction Absolute direction
* @return Status
*/
private int lookHeading(IRobot robot, int direction) {
return robot.look(switch (direction - robot.getHeading()) {
case -3,1 -> IRobot.RIGHT;
case -2,2 -> IRobot.BEHIND;
case -1,3 -> IRobot.LEFT;
default -> IRobot.AHEAD;
});
}
/**
* Determine which direction to move to get closer to the target without hitting a wall
*
* @param robot Robot object
* @return Direction
*/
private int headingController(IRobot robot) {
/*
* When the value of direction equal to 0 means it's a wall
* When the value of direction less than 0 means it's not the first choice
*/
int direction[] = new int[]{IRobot.NORTH, IRobot.EAST, IRobot.SOUTH, IRobot.WEST};
int result = 0;
for (int i = 0; i < 4; i++) {
direction[i] *= (lookHeading(robot, direction[i]) == IRobot.WALL)?0:1;
}
direction[0] *= isTargetNorth(robot)*1;
direction[1] *= isTargetEast(robot)*1;
direction[2] *= isTargetNorth(robot)*-1;
direction[3] *= isTargetEast(robot)*-1;
for (int i = 0; i < 4; i++) if (direction[i] > 0) result++;
if (result == 0) for (int i = 0; i < 4; i++) direction[i] *= -1;//If all directions are either walls or second choices, make all second choices first choices
result = (int)(Math.random()*4);
while (direction[result] <= 0) result = (int)(Math.random()*4);//If the result not the first choise, re-randomize direction
return direction[result];
}
public void reset() {
ControlTest.printResults();
}
public void controlRobot(IRobot robot) {
int heading = headingController(robot);
ControlTest.test(heading, robot);
robot.setHeading(heading);
}
}