Skip to content

Commit a7630f3

Browse files
committed
commented and cleaned up code
1 parent fd5321d commit a7630f3

File tree

2 files changed

+83
-38
lines changed

2 files changed

+83
-38
lines changed

src/bundles/robot_minigame/functions.ts

Lines changed: 81 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
/*
2-
* Currently uses a grid based system, will upgrade to more fancy stuff later
3-
* The movement is simulated, then a series of movement points is passed to the module context, which the frontend then uses to render
4-
*/
5-
61
import context from 'js-slang/context';
72
import {
8-
accumulate,
93
head,
104
tail,
115
type List
126
} from 'js-slang/dist/stdlib/list';
137

148
type Point = {x: number, y: number};
15-
type Intersection = {x: number, y: number, dist: number}
9+
type PointWithRotation = {x: number, y: number, angle: number}
10+
11+
type CommandData = {
12+
type: String,
13+
location: PointWithRotation
14+
}
1615

1716
type Polygon = Point[];
1817

@@ -24,8 +23,7 @@ type StateData = {
2423
movePoints: Point[],
2524
message: string,
2625
success: boolean,
27-
messages: string[],
28-
rotations: Point[]
26+
messages: string[]
2927
};
3028

3129
type Robot = {
@@ -44,8 +42,7 @@ const stateData: StateData = {
4442
movePoints: [],
4543
message: 'moved successfully',
4644
success: true,
47-
messages: [],
48-
rotations: []
45+
messages: []
4946
};
5047

5148
const robot: Robot = {
@@ -58,6 +55,7 @@ const robot: Robot = {
5855

5956
let bounds: Point[] = [];
6057

58+
// sets the context to the statedata obj, mostly for convenience so i dont have to type context.... everytime
6159
context.moduleContexts.robot_minigame.state = stateData;
6260

6361
export function set_pos(x: number, y: number): void {
@@ -73,11 +71,15 @@ export function set_height(height: number) {
7371
stateData.height = height;
7472
}
7573

74+
// condenses setting the width and height of map, and the initial position of robot in one call
7675
export function init(width: number, height: number, posX: number, posY: number) {
76+
if (stateData.isInit) return; // dont allow init more than once
77+
7778
set_width(width);
7879
set_height(height);
7980
set_pos(posX, posY);
80-
stateData.movePoints.push({x: posX, y: posY});
81+
82+
stateData.movePoints.push({x: posX, y: posY}); // push starting point to movepoints data
8183
stateData.isInit = true;
8284

8385
bounds = [
@@ -86,7 +88,6 @@ export function init(width: number, height: number, posX: number, posY: number)
8688
{x: width, y: height},
8789
{x: 0, y: height}
8890
];
89-
9091
}
9192

9293
export function turn_left() {
@@ -97,9 +98,11 @@ export function turn_left() {
9798
robot.dx = Math.cos(currentAngle);
9899
robot.dy = -Math.sin(currentAngle);
99100

101+
// prevent floating point issues
100102
if (robot.dx < 0.00001 && robot.dx > -0.00001) robot.dx = 0;
101103
if (robot.dy < 0.00001 && robot.dy > -0.00001) robot.dy = 0;
102104

105+
// debug log
103106
logCoordinates();
104107
}
105108

@@ -114,6 +117,7 @@ export function turn_right() {
114117
if (robot.dx < 0.00001 && robot.dx > -0.00001) robot.dx = 0;
115118
if (robot.dy < 0.00001 && robot.dy > -0.00001) robot.dy = 0;
116119

120+
// debug log
117121
logCoordinates();
118122
}
119123

@@ -124,10 +128,11 @@ export function rotate_right(angle: number) {
124128

125129
robot.dx = Math.cos(currentAngle);
126130
robot.dy = -Math.sin(currentAngle);
127-
131+
128132
if (robot.dx < 0.00001 && robot.dx > -0.00001) robot.dx = 0;
129133
if (robot.dy < 0.00001 && robot.dy > -0.00001) robot.dy = 0;
130134

135+
// debug log
131136
logCoordinates();
132137
}
133138

@@ -145,6 +150,7 @@ export function rotate_left(angle: number) {
145150
logCoordinates();
146151
}
147152

153+
// easily set up a rectangular wall using the x and y of the top left corner, and width/height
148154
export function set_rect_wall(x: number, y: number, width: number, height: number) {
149155
const polygon: Polygon = [
150156
{x: x, y: y},
@@ -156,8 +162,11 @@ export function set_rect_wall(x: number, y: number, width: number, height: numbe
156162
stateData.walls.push(polygon);
157163
}
158164

165+
// creates irregularly shaped wall
166+
// takes in a list of vertices as its argument
159167
export function set_polygon_wall(vertices: List) {
160168
const polygon: Polygon = []
169+
161170
while (vertices != null) {
162171
const p = head(vertices);
163172
polygon.push({x: head(p), y: tail(p)});
@@ -175,80 +184,114 @@ export function getY():number {
175184
return robot.y;
176185
}
177186

178-
export function move_forward(): void {
187+
// moves robot to the nearest wall
188+
export function move_forward_to_wall(): void {
179189
if (alrCollided()) return;
180190

181-
let distance = findCollision();
191+
let distance = findMoveDistance(); // do the raycast, figure out how far the robot is from the nearest wall
192+
193+
// a lil extra offset from wall
182194
distance = Math.max(distance - robot.radius - 5, 0)
183195

184196
const nextPoint: Point = {
185197
x: robot.x + distance * robot.dx,
186198
y: robot.y + distance * robot.dy
187199
}
188200

189-
190201
robot.x = nextPoint.x;
191202
robot.y = nextPoint.y;
192203
stateData.movePoints.push(nextPoint);
204+
205+
// for debug
193206
stateData.messages.push(`Distance is ${distance} Collision point at x: ${nextPoint.x}, y: ${nextPoint.y}`);
194207
}
195208

196-
function findCollision(): number {
197-
let nearest: Point | null = null;
209+
// Moves forward by a small amount
210+
export function move_forward(moveDist: number): void {
211+
const nextPoint: Point = {
212+
x: robot.x + moveDist * robot.dx,
213+
y: robot.y + moveDist + robot.dy
214+
}
215+
216+
// need to check for collision with wall
217+
218+
robot.x = nextPoint.x;
219+
robot.y = nextPoint.y;
220+
stateData.movePoints.push(nextPoint);
221+
222+
logCoordinates();
223+
}
224+
225+
export function sensor(): boolean {
226+
return false;
227+
}
228+
229+
// returns the distance from the nearest wall
230+
function findMoveDistance(): number {
198231
let minDist: number = Infinity;
199232

233+
// loop through all the walls
200234
for (const wall of stateData.walls) {
201-
const intersection: Intersection | null = raycast(wall);
202-
if (intersection !== null && intersection.dist < minDist) {
203-
minDist = intersection.dist;
204-
nearest = {x: intersection.x, y: intersection.y};
235+
const intersectionDist = raycast(wall); // do the raycast
236+
237+
// if intersection is closer, update minDist
238+
if (intersectionDist !== null && intersectionDist < minDist) {
239+
minDist = intersectionDist;
205240
}
206241
}
207242

208243
// check outer bounds as well
209-
const intersection: Intersection | null = raycast(bounds);
210-
if (intersection !== null && intersection.dist < minDist) {
211-
minDist = intersection.dist;
212-
nearest = {x: intersection.x, y: intersection.y};
244+
const intersectionDist = raycast(bounds);
245+
if (intersectionDist !== null && intersectionDist < minDist) {
246+
minDist = intersectionDist;
213247
}
214248

215-
return minDist === Infinity ? 0 : minDist; // Closest intersection point
249+
// Closest intersection point
250+
// By all rights, there should always be an intersection point since the robot is always within the bounds
251+
// and the bounds should be a collision
252+
// but something goes wrong, will just return 0
253+
return minDist === Infinity ? 0 : minDist;
216254
}
217255

218-
function raycast(polygon: Polygon): Intersection | null {
256+
// does the raycast logic for one particular wall
257+
// three rays are cast: one from the center, one from the top and one from the bottom. the minimum dist is returned
258+
// return null if no collision
259+
function raycast(polygon: Polygon): number | null {
219260
let minDist = Infinity;
220-
let nearest: Intersection | null = null;
221261

222262
for (let i = 0; i < polygon.length; i++) {
263+
// wall line segment
223264
const x1 = polygon[i].x, y1 = polygon[i].y;
224265
const x2 = polygon[(i + 1) % polygon.length].x, y2 = polygon[(i + 1) % polygon.length].y;
225266

267+
// calculate the top and bottom coordinates of the robot
226268
const topX = robot.x - robot.radius * robot.dy;
227269
const topY = robot.y - robot.radius * robot.dx;
228270

229271
const bottomX = robot.x + robot.radius * robot.dy;
230272
const bottomY = robot.y + robot.radius * robot.dx;
231273

274+
// raycast from 3 sources: top, middle, bottom
232275
const raycast_sources: Point[] = [
233276
{x: robot.x, y: robot.y},
234277
{x: topX, y: topY},
235278
{x: bottomX, y: bottomY}
236279
]
237280

238281
for (const source of raycast_sources) {
239-
const intersection = getIntersection(source.x, source.y, robot.dx + source.x, robot.dy + source.y, x1, y1, x2, y2);
240-
if (intersection !== null && intersection.dist < minDist) {
241-
minDist = intersection.dist;
242-
nearest = intersection;
282+
const intersectionDist = getIntersection(source.x, source.y, robot.dx + source.x, robot.dy + source.y, x1, y1, x2, y2);
283+
if (intersectionDist !== null && intersectionDist < minDist) {
284+
minDist = intersectionDist;
243285
}
244286
}
245287
}
246288

247-
return nearest;
289+
return minDist === Infinity ? null : minDist;
248290
}
249291

250292
// Determine if a ray and a line segment intersect, and if so, determine the collision point
251-
function getIntersection(x1, y1, x2, y2, x3, y3, x4, y4): Intersection | null {
293+
// returns null if there's no collision, or the distance to the line segment if collides
294+
function getIntersection(x1, y1, x2, y2, x3, y3, x4, y4): number | null {
252295
const denom = ((x2 - x1)*(y4 - y3)-(y2 - y1)*(x4 - x3));
253296
let r;
254297
let s;
@@ -276,9 +319,9 @@ function getIntersection(x1, y1, x2, y2, x3, y3, x4, y4): Intersection | null {
276319
}
277320
}
278321

279-
if (!b) return null
322+
if (!b) return null;
280323

281-
return {x: x, y: y, dist: r}
324+
return r;
282325
}
283326

284327
function alrCollided() {

src/bundles/robot_minigame/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export {
1414
set_rect_wall,
1515
set_polygon_wall,
1616
move_forward,
17+
sensor,
18+
move_forward_to_wall,
1719
turn_left,
1820
turn_right,
1921
rotate_right,

0 commit comments

Comments
 (0)