diff --git a/index.html b/index.html
index bdfcdc0..5ac14d9 100644
--- a/index.html
+++ b/index.html
@@ -187,10 +187,14 @@
Data
Note
-
- Outer-totalistic cellular automata are supported (without B0).
+ Outer-totalistic rules and isotropic non-totalistic rules are
+ supported (without B0).
- The supplied pattern must be a phase of an oscillator.
- - The maximum period that can be analyzed is 50,000.
+ -
+ The maximum period that can be analyzed is 50,000 for outer
+ totalistic rules and 2,000 for isotropic non-totalistic rules.
+
diff --git a/package-lock.json b/package-lock.json
index ce37cef..51b71a4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"hasInstallScript": true,
"license": "MIT",
"devDependencies": {
- "@ca-ts/algo": "npm:@jsr/ca-ts__algo@^0.5.0",
+ "@ca-ts/algo": "npm:@jsr/ca-ts__algo@^0.6.0",
"@ca-ts/rle": "npm:@jsr/ca-ts__rle@^0.8.0",
"@ca-ts/rule": "npm:@jsr/ca-ts__rule@^0.4.0",
"typescript": "^5.6.3",
@@ -20,9 +20,9 @@
},
"node_modules/@ca-ts/algo": {
"name": "@jsr/ca-ts__algo",
- "version": "0.5.0",
- "resolved": "https://npm.jsr.io/~/11/@jsr/ca-ts__algo/0.5.0.tgz",
- "integrity": "sha512-KQM7g9Uc8hf/6R7LXkGgjZLsZACh1qjyHs560ruh49c/yAPFNKKllJn0dxFcZEe98KYy1oxvJ5fogH5I5JhKFw==",
+ "version": "0.6.0",
+ "resolved": "https://npm.jsr.io/~/11/@jsr/ca-ts__algo/0.6.0.tgz",
+ "integrity": "sha512-mIBtSCUeeKMLcDgPIb380gyBjM+ctWSS0JZGgb7lan5iuFlZJ3Q1dmiClKIQ4mI4pxCpVa0LKprmszv+U0Zxnw==",
"dev": true
},
"node_modules/@ca-ts/rle": {
diff --git a/package.json b/package.json
index a3656cb..759dfcf 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
"test": "vitest"
},
"devDependencies": {
- "@ca-ts/algo": "npm:@jsr/ca-ts__algo@^0.5.0",
+ "@ca-ts/algo": "npm:@jsr/ca-ts__algo@^0.6.0",
"@ca-ts/rle": "npm:@jsr/ca-ts__rle@^0.8.0",
"@ca-ts/rule": "npm:@jsr/ca-ts__rule@^0.4.0",
"typescript": "^5.6.3",
diff --git a/src/lib/WorldWithHistory.ts b/src/lib/WorldWithHistory.ts
index c81edca..e4cfe67 100644
--- a/src/lib/WorldWithHistory.ts
+++ b/src/lib/WorldWithHistory.ts
@@ -22,10 +22,16 @@ export class WorldWithHistory {
constructor({
cells,
bufferSize,
- transition,
+ rule,
}: {
cells: { x: number; y: number }[];
- transition: { birth: number[]; survive: number[] };
+ rule:
+ | {
+ transition: { birth: number[]; survive: number[] };
+ }
+ | {
+ intTransition: { birth: string[]; survive: string[] };
+ };
bufferSize?: number;
}) {
this.bufferSize = bufferSize ?? 32;
@@ -35,7 +41,12 @@ export class WorldWithHistory {
width: sizeX + this.bufferSize,
height: sizeY + this.bufferSize,
});
- this.bitWorld.setRule(transition);
+ if ("transition" in rule && rule.transition !== undefined) {
+ this.bitWorld.setRule(rule.transition);
+ } else if ("intTransition" in rule && rule.intTransition !== undefined) {
+ this.bitWorld.setINTRule(rule.intTransition);
+ }
+
setCellsToBitGrid(this.bitWorld.bitGrid, cells, { sizeX, sizeY });
this.initialBitGrid = this.bitWorld.bitGrid.clone();
diff --git a/src/lib/analyzeOscillator.test.ts b/src/lib/analyzeOscillator.test.ts
index 3250adb..e97b2c7 100644
--- a/src/lib/analyzeOscillator.test.ts
+++ b/src/lib/analyzeOscillator.test.ts
@@ -8,9 +8,11 @@ describe("analyzeOscillator", () => {
cells: parseRLE(`ooo`)
.cells.filter((x) => x.state === 1)
.map((x) => x.position),
- transition: {
- birth: [3],
- survive: [2, 3],
+ rule: {
+ transition: {
+ birth: [3],
+ survive: [2, 3],
+ },
},
maxGeneration: 1000,
});
diff --git a/src/lib/runOscillator.ts b/src/lib/runOscillator.ts
index 4922a9a..3c1ff6a 100644
--- a/src/lib/runOscillator.ts
+++ b/src/lib/runOscillator.ts
@@ -2,7 +2,13 @@ import { WorldSizeError, WorldWithHistory } from "./WorldWithHistory";
export type RunOscillatorConfig = {
cells: { x: number; y: number }[];
- transition: { birth: number[]; survive: number[] };
+ rule:
+ | {
+ transition: { birth: number[]; survive: number[] };
+ }
+ | {
+ intTransition: { birth: string[]; survive: string[] };
+ };
maxGeneration: number;
};
@@ -13,11 +19,11 @@ export type RunOscillatorResult = {
export function runOscillator(
config: RunOscillatorConfig
): RunOscillatorResult {
- const { cells, transition, maxGeneration } = config;
+ const { cells, rule, maxGeneration } = config;
let bufferSize = 32;
for (let i = 0; i < 5; i++) {
try {
- const world = new WorldWithHistory({ cells, bufferSize, transition });
+ const world = new WorldWithHistory({ cells, bufferSize, rule });
const result = world.run({
forceStop: () => world.getGen() >= maxGeneration,
});
diff --git a/src/worker.ts b/src/worker.ts
index cf61d9e..45f2ecc 100644
--- a/src/worker.ts
+++ b/src/worker.ts
@@ -37,14 +37,12 @@ function handleRequest(data: WorkerRequestMessage): WorkerResponseMessage {
};
}
- if (rule.type !== "outer-totalistic") {
+ if (rule.type === "outer-totalistic" && rule.transition.birth.includes(0)) {
return {
kind: "response-error",
- message: "Unsupported rule",
+ message: "Rules containing B0 is not supported",
};
- }
-
- if (rule.transition.birth.includes(0)) {
+ } else if (rule.type === "int" && rule.transition.birth.includes("0")) {
return {
kind: "response-error",
message: "Rules containing B0 is not supported",
@@ -62,8 +60,11 @@ function handleRequest(data: WorkerRequestMessage): WorkerResponseMessage {
try {
const result = analyzeOscillator({
cells: cells,
- transition: rule.transition,
- maxGeneration: 50_000,
+ rule:
+ rule.type === "int"
+ ? { intTransition: rule.transition }
+ : { transition: rule.transition },
+ maxGeneration: rule.type === "int" ? 2_000 : 50_000,
});
return { kind: "response-analyzed", data: result };
} catch (error) {