Skip to content

Commit 631fd23

Browse files
committed
Predeclare tests in prepend, run_tests() in postpend
1 parent 8e2ed88 commit 631fd23

File tree

3 files changed

+79
-35
lines changed

3 files changed

+79
-35
lines changed

src/bundles/robot_minigame/functions.ts

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ interface Point {
1212
}
1313

1414
// A point (x, y) with rotation
15-
export interface PointWithRotation extends Point {
15+
interface PointWithRotation extends Point {
1616
rotation: number
1717
}
1818

19+
export interface Robot extends PointWithRotation {
20+
radius: number
21+
}
22+
1923
// A line segment between p1 and p2
2024
interface LineSegment {
2125
p1: Point
@@ -44,8 +48,14 @@ export interface Area {
4448
flags: AreaFlags
4549
}
4650

47-
export interface Robot extends PointWithRotation {
48-
radius: number
51+
interface Test {
52+
type: string
53+
test: Function
54+
}
55+
56+
interface AreaTest extends Test {
57+
type: 'area'
58+
test: (areas: Area[]) => boolean
4959
}
5060

5161
export interface RobotMinigame {
@@ -56,6 +66,7 @@ export interface RobotMinigame {
5666
areas: Area[]
5767
areaLog: Area[]
5868
actionLog: Action[]
69+
tests: Test[]
5970
message: string
6071
}
6172

@@ -68,6 +79,7 @@ const state: RobotMinigame = {
6879
areas: [],
6980
areaLog: [],
7081
actionLog: [],
82+
tests: [],
7183
message: ''
7284
};
7385

@@ -235,6 +247,27 @@ export function create_rect_obstacle(
235247
create_rect_area(x, y, width, height, true, []);
236248
}
237249

250+
/**
251+
* Check if the robot has entered different areas with the given colors in order
252+
*
253+
* @param colors in the order visited
254+
* @returns if the robot entered the given colors in order
255+
*/
256+
export function should_enter_colors(
257+
colors: string[]
258+
) {
259+
state.tests.push({
260+
type: 'area',
261+
test: (areas: Area[]) => {
262+
const coloredAreas = areas
263+
.filter((area: Area) => colors.includes(area.flags.color)) // Filter relevant colors
264+
.filter(filterAdjacentDuplicateAreas); // Filter adjacent duplicates
265+
266+
return coloredAreas.length === colors.length && coloredAreas.every(({ flags: { color } }, i) => color === colors[i]); // Check if each area has the expected color
267+
}
268+
} as AreaTest);
269+
}
270+
238271
/**
239272
* Inform the simulator that the initialisation phase is complete
240273
*/
@@ -368,32 +401,30 @@ export function turn_right() {
368401
// ======= //
369402

370403
/**
371-
* Checks if the robot's entered areas satisfy the callback
404+
* Run the stored tests in state
372405
*
373-
* @returns if the entered areas satisfy the callback
406+
* @returns if all tests pass
374407
*/
375-
export function entered_areas(
376-
callback : (areas : Area[]) => boolean
377-
) : boolean {
378-
return callback(state.areaLog);
379-
}
408+
export function run_tests() : boolean {
409+
// Run each test in order
410+
for (const test of state.tests) {
411+
// Store status in a variable
412+
let success: boolean;
413+
414+
switch(test.type) {
415+
case 'area':
416+
success = test.test(state.areaLog);
417+
break;
418+
default:
419+
success = true;
420+
}
380421

381-
/**
382-
* Check if the robot has entered different areas with the given colors in order
383-
*
384-
* @param colors in the order visited
385-
* @returns if the robot entered the given colors in order
386-
*/
387-
export function entered_colors(
388-
colors: string[]
389-
) : boolean {
390-
return entered_areas(areas => {
391-
const coloredAreas = areas
392-
.filter(area => colors.includes(area.flags.color)) // Filter relevant colors
393-
.filter(filterAdjacentDuplicateAreas); // Filter adjacent duplicates
422+
// If the test fails, return false
423+
if (!success) return false;
424+
}
394425

395-
return coloredAreas.length === colors.length && coloredAreas.every(({ flags: { color } }, i) => color === colors[i]); // Check if each area has the expected color
396-
});
426+
// If all tests pass, return true
427+
return true;
397428
}
398429

399430
// ==================

src/bundles/robot_minigame/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ export {
1010
init, create_area, create_rect_area, create_obstacle, create_rect_obstacle, complete_init,
1111
get_distance, get_color,
1212
move_forward, move_forward_to_wall, rotate, turn_left, turn_right,
13-
entered_areas, entered_colors
13+
should_enter_colors, run_tests
1414
} from './functions';

src/tabs/RobotMaze/components/RobotSimulation.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useRef, useState } from 'react';
2-
import type { Area, Action, PointWithRotation, Robot, RobotMinigame } from '../../../bundles/robot_minigame/functions';
2+
import type { Area, Action, Robot, RobotMinigame } from '../../../bundles/robot_minigame/functions';
33

44
/**
55
* Calculate the acute angle between 2 angles
@@ -8,7 +8,10 @@ import type { Area, Action, PointWithRotation, Robot, RobotMinigame } from '../.
88
* @param current rotation
99
* @returns the acute angle between
1010
*/
11-
const smallestAngle = (target, current) => {
11+
const smallestAngle = (
12+
target: number,
13+
current: number
14+
) => {
1215
const dr = (target - current) % (2 * Math.PI);
1316

1417
if (dr > 0 && dr > Math.PI) return dr - (2 * Math.PI);
@@ -24,7 +27,11 @@ const smallestAngle = (target, current) => {
2427
* @param width of the map
2528
* @param height of the map
2629
*/
27-
const drawBorders = (ctx: CanvasRenderingContext2D, width: number, height: number) => {
30+
const drawBorders = (
31+
ctx: CanvasRenderingContext2D,
32+
width: number,
33+
height: number
34+
) => {
2835
ctx.beginPath();
2936
ctx.moveTo(0, 0);
3037
ctx.lineTo(0, height);
@@ -38,7 +45,10 @@ const drawBorders = (ctx: CanvasRenderingContext2D, width: number, height: numbe
3845
};
3946

4047
// Draw the areas of the map
41-
const drawAreas = (ctx: CanvasRenderingContext2D, areas: Area[]) => {
48+
const drawAreas = (
49+
ctx: CanvasRenderingContext2D,
50+
areas: Area[]
51+
) => {
4252
for (const { vertices, isObstacle, flags } of areas) {
4353
ctx.beginPath();
4454
ctx.moveTo(vertices[0].x, vertices[0].y);
@@ -59,7 +69,10 @@ const drawAreas = (ctx: CanvasRenderingContext2D, areas: Area[]) => {
5969
};
6070

6171
// Draw the robot
62-
const drawRobot = (ctx: CanvasRenderingContext2D, { x, y, rotation } : PointWithRotation, size: number) => {
72+
const drawRobot = (
73+
ctx: CanvasRenderingContext2D,
74+
{ x, y, rotation, radius }: Robot
75+
) => {
6376
// Save the background state
6477
ctx.save();
6578

@@ -69,7 +82,7 @@ const drawRobot = (ctx: CanvasRenderingContext2D, { x, y, rotation } : PointWith
6982

7083
ctx.beginPath(); // Begin drawing robot
7184

72-
ctx.arc(0, 0, size, 0, Math.PI * 2, false); // Full circle (0 to 2π radians)
85+
ctx.arc(0, 0, radius, 0, Math.PI * 2, false); // Full circle (0 to 2π radians)
7386

7487
ctx.fillStyle = 'black'; // Set the fill color
7588
ctx.fill(); // Fill the circle
@@ -78,7 +91,7 @@ const drawRobot = (ctx: CanvasRenderingContext2D, { x, y, rotation } : PointWith
7891
ctx.strokeStyle = 'white';
7992
ctx.lineWidth = 2;
8093
ctx.beginPath();
81-
ctx.moveTo(size, 0);
94+
ctx.moveTo(radius, 0);
8295
ctx.lineTo(0, 0);
8396
ctx.stroke();
8497

@@ -94,12 +107,12 @@ const drawAll = (
94107
width : number,
95108
height : number,
96109
areas: Area[],
97-
{x, y, rotation, radius: robotSize} : Robot
110+
robot : Robot
98111
) => {
99112
ctx.reset();
100113
drawBorders(ctx, width, height);
101114
drawAreas(ctx, areas);
102-
drawRobot(ctx, {x, y, rotation}, robotSize);
115+
drawRobot(ctx, robot);
103116
};
104117

105118
// The speed to move at

0 commit comments

Comments
 (0)