Skip to content

Commit 1d7372e

Browse files
committed
new module for source academy minigame
1 parent d2b843c commit 1d7372e

File tree

5 files changed

+468
-1
lines changed

5 files changed

+468
-1
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,6 @@
137137
"resolutions": {
138138
"esbuild": "^0.18.20",
139139
"**/gl": "^6.0.2"
140-
}
140+
},
141+
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
141142
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Internally, the robot uses a grid based movement and collision system
3+
*/
4+
5+
import context from 'js-slang/context';
6+
7+
let robotPos: Point = {x: 0, y: 0};
8+
9+
let movePoints: Point[];
10+
11+
const DIRECTIONS = {
12+
UP: 0,
13+
RIGHT: 1,
14+
DOWN: 2,
15+
LEFT: 3
16+
};
17+
18+
let robotRotation = 1;
19+
20+
// default grid width and height is 25
21+
context.moduleContexts.robot_minigame.state = {
22+
isInit: false,
23+
width: 25,
24+
height: 25,
25+
walls: [],
26+
movePoints: [],
27+
message: "moved successfully",
28+
success: true
29+
}
30+
31+
type Point = {x: number, y: number}
32+
type Wall = {p1: Point, p2: Point}
33+
34+
export function set_pos(x: number, y: number): void {
35+
robotPos.x = x;
36+
robotPos.y = y;
37+
}
38+
39+
export function set_grid_width(width: number) {
40+
context.moduleContexts.robot_minigame.state.width = width;
41+
}
42+
43+
export function set_grid_height(height: number) {
44+
context.moduleContexts.robot_minigame.state.height = height;
45+
}
46+
47+
export function init(gridWidth: number, gridHeight: number, posX: number, posY: number) {
48+
set_grid_width(gridWidth);
49+
set_grid_height(gridHeight);
50+
set_pos(posX, posY);
51+
context.moduleContexts.robot_minigame.state.movePoints.push({x: posX, y: posY});
52+
context.moduleContexts.robot_minigame.state.isInit = true;
53+
}
54+
55+
export function turn_left() {
56+
if (alrCollided()) return;
57+
58+
robotRotation -= 1;
59+
if (robotRotation < 0) {
60+
robotRotation = 3;
61+
}
62+
}
63+
64+
export function turn_right() {
65+
if (alrCollided()) return;
66+
67+
robotRotation = (robotRotation + 1) % 4;
68+
}
69+
70+
// takes the top left and bottom right corners of walls
71+
// in terms of grid boxes
72+
// grid starts from (0, 0) at the top left corner btw
73+
export function set_wall(x1: number, y1: number, x2: number, y2: number) {
74+
let wall: Wall = {p1: {x: x1, y: y1}, p2: {x: x2, y: y2}};
75+
context.moduleContexts.robot_minigame.state.walls.push(wall);
76+
}
77+
78+
export function move_forward(dist: number): void {
79+
if (alrCollided()) return;
80+
81+
simulate(dist);
82+
}
83+
84+
export function getX():number {
85+
return robotPos.x;
86+
}
87+
88+
export function getY():number {
89+
return robotPos.y;
90+
}
91+
92+
function simulate(moveDist: number) {
93+
let dx: number = 0;
94+
let dy: number = 0;
95+
switch (robotRotation) {
96+
case DIRECTIONS.UP:
97+
dy = -1;
98+
break;
99+
case DIRECTIONS.RIGHT:
100+
dx = 1;
101+
break;
102+
case DIRECTIONS.DOWN:
103+
dy = 1;
104+
break;
105+
case DIRECTIONS.LEFT:
106+
dx = -1;
107+
break;
108+
}
109+
110+
// moves robot by one grid box and checks collision
111+
for (var i = 0; i < moveDist; i++) {
112+
robotPos.x += dx;
113+
robotPos.y += dy;
114+
115+
var walls = context.moduleContexts.robot_minigame.state.walls;
116+
for (let j = 0; j < walls.length; j++) {
117+
if (checkWallCollision(walls[j], robotPos)) {
118+
context.moduleContexts.robot_minigame.state.success = false;
119+
context.moduleContexts.robot_minigame.state.message = "collided";
120+
context.moduleContexts.robot_minigame.state.movePoints.push({x: robotPos.x, y: robotPos.y});
121+
return;
122+
}
123+
}
124+
}
125+
126+
context.moduleContexts.robot_minigame.state.movePoints.push({x: robotPos.x, y: robotPos.y});
127+
128+
// OLD CODE
129+
// let destX = robotPos.x + moveDist * Math.cos(robotAngle);
130+
// let destY = robotPos.y + moveDist * Math.sin(robotAngle);
131+
// let destPoint: Point = {x: destX, y: destY}
132+
133+
// for (let i = 0; i < steps; i++) {
134+
// let distX: number = moveSpeed * Math.cos(robotAngle);
135+
// let distY: number = moveSpeed * Math.sin(robotAngle);
136+
137+
// robotPos.x += distX;
138+
// robotPos.y += distY;
139+
140+
// for (let j = 0; j < walls.length; j++) {
141+
// if(checkWallCollision(walls[j], robotPos)) {
142+
// addMessage("Collided with wall!!");
143+
// addMessage(`Position: (${robotPos.x.toFixed(3)}, ${robotPos.y.toFixed(3)}), Rotation: ${robotAngle}\n`);
144+
// return;
145+
// }
146+
// }
147+
148+
// if (distanceBetween(destPoint, robotPos) < robotRadius) {
149+
// robotPos = destPoint;
150+
// addMessage(`Robot moved forward by ${moveDist} at angle ${robotAngle} radians\n`);
151+
// addMessage(`Position: (${robotPos.x.toFixed(3)}, ${robotPos.y.toFixed(3)}), Rotation: ${robotAngle}\n`);
152+
// return;
153+
// }
154+
// }
155+
156+
157+
}
158+
159+
160+
function checkWallCollision(wall: Wall, pos: Point): boolean {
161+
// // Apply the distance formula
162+
// const p1 = wall.p1;
163+
// const p2 = wall.p2;
164+
165+
// const numerator = Math.abs((p2.y - p1.y) * pos.x - (p2.x - p1.x) * pos.y + p2.x * p1.y - p2.y * p1.x);
166+
// const denominator = Math.sqrt((p2.y - p1.y) ** 2 + (p2.x - p1.x) ** 2);
167+
168+
// return numerator / denominator < robotRadius;
169+
170+
const p1 = wall.p1;
171+
const p2 = wall.p2;
172+
173+
const minX = Math.min(p1.x, p2.x);
174+
const maxX = Math.max(p1.x, p2.x);
175+
const minY = Math.min(p1.y, p2.y);
176+
const maxY = Math.max(p1.y, p2.y);
177+
178+
return pos.x >= minX && pos.x <= maxX && pos.y >= minY && pos.y <= maxY;
179+
}
180+
181+
function alrCollided() {
182+
return !context.moduleContexts.robot_minigame.state.success;
183+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* A single sentence summarising the module (this sentence is displayed larger).
3+
*
4+
* Sentences describing the module. More sentences about the module.
5+
*
6+
* @module robot_minigame
7+
* @author Koh Wai Kei
8+
* @author Author Name
9+
*/
10+
11+
export {
12+
init,
13+
set_pos,
14+
set_wall,
15+
move_forward,
16+
turn_left,
17+
turn_right,
18+
getX,
19+
getY
20+
} from "./functions";
21+
22+
23+

0 commit comments

Comments
 (0)