pinewood-derby-scheduler 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -5
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/sbma44/pinewood-derby-scheduler/actions/workflows/node.js.yml)
|
|
4
4
|
|
|
5
|
-
A lane assignment scheduler for pinewood derby races. Generates fair race schedules that
|
|
5
|
+
A lane assignment scheduler for pinewood derby races. Generates fair race schedules that optimize for lane diversity, opponent variety, and fast race setup.
|
|
6
|
+
|
|
7
|
+
Live demo: [https://pinewood.tomlee.space](https://pinewood.tomlee.space/)
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -36,18 +38,63 @@ raceSchedule.forEach((heat, i) => {
|
|
|
36
38
|
});
|
|
37
39
|
```
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
## Scheduling Criteria
|
|
42
|
+
|
|
43
|
+
The scheduler optimizes for three criteria, which you can prioritize in any order:
|
|
44
|
+
|
|
45
|
+
| Criterion | Description |
|
|
46
|
+
|-----------|-------------|
|
|
47
|
+
| `'lanes'` | **Lane diversity** — Each racer uses different lanes across their heats |
|
|
48
|
+
| `'opponents'` | **Opponent diversity** — Each racer faces different opponents |
|
|
49
|
+
| `'turnover'` | **Turnover** — Minimize cars appearing in consecutive heats (faster race setup) |
|
|
50
|
+
|
|
51
|
+
### Setting Priorities
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
Pass an array to `prioritize` to control the relative importance of each criterion. The first item has highest priority:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// Prioritize fast race setup, then opponent variety, then lane diversity
|
|
57
|
+
const raceSchedule = schedule(racers, {
|
|
58
|
+
numLanes: 4,
|
|
59
|
+
heatsPerRacer: 4,
|
|
60
|
+
prioritize: ['turnover', 'opponents', 'lanes'],
|
|
61
|
+
});
|
|
62
|
+
```
|
|
42
63
|
|
|
43
64
|
```ts
|
|
65
|
+
// Prioritize lane diversity (default behavior)
|
|
44
66
|
const raceSchedule = schedule(racers, {
|
|
45
67
|
numLanes: 4,
|
|
46
68
|
heatsPerRacer: 4,
|
|
47
|
-
prioritize: 'opponents',
|
|
69
|
+
prioritize: ['lanes', 'opponents', 'turnover'],
|
|
48
70
|
});
|
|
49
71
|
```
|
|
50
72
|
|
|
73
|
+
```ts
|
|
74
|
+
// Prioritize opponent variety above all else
|
|
75
|
+
const raceSchedule = schedule(racers, {
|
|
76
|
+
numLanes: 4,
|
|
77
|
+
heatsPerRacer: 4,
|
|
78
|
+
prioritize: ['opponents', 'lanes', 'turnover'],
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
All three criteria are always considered; the priority order controls their relative weights (first = 1000, second = 100, third = 10).
|
|
83
|
+
|
|
84
|
+
### Backward Compatibility
|
|
85
|
+
|
|
86
|
+
The old single-string format still works:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// These are equivalent:
|
|
90
|
+
prioritize: 'lanes'
|
|
91
|
+
prioritize: ['lanes', 'opponents', 'turnover']
|
|
92
|
+
|
|
93
|
+
// These are equivalent:
|
|
94
|
+
prioritize: 'opponents'
|
|
95
|
+
prioritize: ['opponents', 'lanes', 'turnover']
|
|
96
|
+
```
|
|
97
|
+
|
|
51
98
|
## API
|
|
52
99
|
|
|
53
100
|
### `schedule<T>(racers: T[], options: ScheduleOptions): Schedule<T>`
|
|
@@ -58,10 +105,28 @@ Generates a race schedule.
|
|
|
58
105
|
- `racers` — Array of racer objects (any shape)
|
|
59
106
|
- `options.numLanes` — Number of lanes on the track
|
|
60
107
|
- `options.heatsPerRacer` — How many heats each racer participates in
|
|
61
|
-
- `options.prioritize` —
|
|
108
|
+
- `options.prioritize` — Priority order for scheduling criteria
|
|
109
|
+
- Single criterion: `'lanes'` | `'opponents'` (backward compatible)
|
|
110
|
+
- Array of criteria: `['lanes', 'opponents', 'turnover']` (any order)
|
|
111
|
+
- Default: `['lanes', 'opponents', 'turnover']`
|
|
62
112
|
|
|
63
113
|
**Returns:** A 2D array where `result[heatIndex][laneIndex]` is a racer or `null` (empty lane).
|
|
64
114
|
|
|
115
|
+
### Types
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
type ScheduleCriterion = 'lanes' | 'opponents' | 'turnover';
|
|
119
|
+
|
|
120
|
+
interface ScheduleOptions {
|
|
121
|
+
numLanes: number;
|
|
122
|
+
heatsPerRacer: number;
|
|
123
|
+
prioritize?: ScheduleCriterion | ScheduleCriterion[];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type Heat<T> = (T | null)[];
|
|
127
|
+
type Schedule<T> = Heat<T>[];
|
|
128
|
+
```
|
|
129
|
+
|
|
65
130
|
## License
|
|
66
131
|
|
|
67
132
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinewood-derby-scheduler",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Lane assignment scheduler for pinewood derby races",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
-
"dist",
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
23
25
|
],
|
|
24
26
|
"scripts": {
|
|
25
27
|
"build": "tsup src/index.ts --format esm --dts",
|
|
@@ -45,4 +47,3 @@
|
|
|
45
47
|
"vitest": "^1.1.3"
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
|
-
|