This commit is contained in:
Olivier Gagnon 2021-10-04 12:28:57 -04:00
parent 4fc6d393e4
commit 880654c222
4 changed files with 338 additions and 280 deletions

@ -51,7 +51,7 @@ export class ActiveFragment {
fragment(): Fragment {
const fragment = FragmentById(this.id);
if (fragment === null) throw "ActiveFragment id refers to unknown Fragment.";
if (fragment === null) throw new Error("ActiveFragment id refers to unknown Fragment.");
return fragment;
}
@ -68,7 +68,7 @@ export class ActiveFragment {
copy(): ActiveFragment {
// We have to do a round trip because the constructor.
const fragment = FragmentById(this.id);
if (fragment === null) throw "ActiveFragment id refers to unknown Fragment.";
if (fragment === null) throw new Error("ActiveFragment id refers to unknown Fragment.");
const c = new ActiveFragment({ x: this.x, y: this.y, fragment: fragment });
c.charge = this.charge;
c.heat = this.heat;

@ -3,287 +3,336 @@ import { FragmentType } from "./FragmentType";
export const Fragments: Fragment[] = [];
export class Fragment {
id: number;
shape: boolean[][];
type: FragmentType;
power: number;
limit: number;
id: number;
shape: boolean[][];
type: FragmentType;
power: number;
limit: number;
constructor(id: number, shape: boolean[][], type: FragmentType, power: number, limit: number) {
this.id = id;
this.shape = shape;
this.type = type;
this.power = power;
this.limit = limit;
constructor(id: number, shape: boolean[][], type: FragmentType, power: number, limit: number) {
this.id = id;
this.shape = shape;
this.type = type;
this.power = power;
this.limit = limit;
}
fullAt(x: number, y: number): boolean {
if (y < 0) return false;
if (y >= this.shape.length) return false;
if (x < 0) return false;
if (x >= this.shape[y].length) return false;
// Yes it's ordered y first.
return this.shape[y][x];
}
width(): number {
// check every line for robustness.
return Math.max(...this.shape.map((line) => line.length));
}
height(): number {
return this.shape.length;
}
// List of direct neighboors of this fragment.
neighboors(): number[][] {
const candidates: number[][] = [];
const add = (x: number, y: number): void => {
if (this.fullAt(x, y)) return;
if (candidates.some((coord) => coord[0] === x && coord[1] === y)) return;
candidates.push([x, y]);
};
for (let y = 0; y < this.shape.length; y++) {
for (let x = 0; x < this.shape[y].length; x++) {
// This cell is full, add all it's neighboors.
if (!this.shape[y][x]) continue;
add(x - 1, y);
add(x + 1, y);
add(x, y - 1);
add(x, y + 1);
}
}
const cells: number[][] = [];
for (const candidate of candidates) {
if (cells.some((cell) => cell[0] === candidate[0] && cell[1] === candidate[1])) continue;
cells.push(candidate);
}
fullAt(x: number, y: number): boolean {
if(y < 0) return false;
if(y >= this.shape.length) return false;
if(x < 0) return false;
if(x >= this.shape[y].length) return false;
// Yes it's ordered y first.
return this.shape[y][x];
}
return cells;
}
width() {
// check every line for robustness.
return Math.max(...this.shape.map(line => line.length));
}
height() {
return this.shape.length;
}
// List of direct neighboors of this fragment.
neighboors(): number[][] {
let candidates: number[][] = [];
const add = (x: number, y: number): void => {
if(this.fullAt(x, y)) return;
if(candidates.some(coord => coord[0] === x && coord[1] === y)) return;
candidates.push([x, y]);
};
for(let y = 0; y < this.shape.length; y++) {
for(let x = 0; x < this.shape[y].length; x++) {
// This cell is full, add all it's neighboors.
if(!this.shape[y][x]) continue;
add(x-1, y);
add(x+1, y);
add(x, y-1);
add(x, y+1);
}
}
const cells: number[][] = [];
for(const candidate of candidates) {
if(cells.some(cell => cell[0] === candidate[0] && cell[1] === candidate[1])) continue;
cells.push(candidate);
}
return cells;
}
copy(): Fragment {
return new Fragment(this.id, this.shape.map(a => a.slice()), this.type, this.power, this.limit);
}
copy(): Fragment {
return new Fragment(
this.id,
this.shape.map((a) => a.slice()),
this.type,
this.power,
this.limit,
);
}
}
export function FragmentById(id: number): Fragment | null {
for(const fragment of Fragments) {
if(fragment.id === id) return fragment;
}
return null;
for (const fragment of Fragments) {
if (fragment.id === id) return fragment;
}
return null;
}
(function () {
const _ = false;
const X = true;
Fragments.push(
new Fragment(
0, // id
[
// shape
[X, X, X],
[_, _, X],
[_, _, X],
],
FragmentType.Hacking, // type
10,
1, // limit
),
);
Fragments.push(
new Fragment(
1, // id
[
// shape
[_, X, _],
[X, X, X],
[_, X, _],
],
FragmentType.Hacking, // type
10,
1, // limit
),
);
Fragments.push(
new Fragment(
2, // id
[
// shape
[X, X, X],
[X, _, X],
[X, X, X],
],
FragmentType.Booster, // type
500,
3, // limit
),
);
Fragments.push(
new Fragment(
3, // id
[
// shape
[X, X],
[X, X],
],
FragmentType.Cooling, // type
200,
Infinity, // limit
),
);
Fragments.push(
new Fragment(
4, // id
[
// shape
[X],
],
FragmentType.Cooling, // type
50,
1, // limit
),
);
Fragments.push(
new Fragment(
5, // id
[
// shape
[X, X],
],
FragmentType.HackingSpeed, // type
50,
1, // limit
),
);
(function() {
const _ = false;
const X = true;
Fragments.push(new Fragment(
0, // id
[ // shape
[X,X,X],
[_,_,X],
[_,_,X],
],
FragmentType.Hacking, // type
10,
1, // limit
));
Fragments.push(new Fragment(
1, // id
[ // shape
[_,X,_],
[X,X,X],
[_,X,_],
],
FragmentType.Hacking, // type
10,
1, // limit
));
Fragments.push(new Fragment(
2, // id
[ // shape
[X,X,X],
[X,_,X],
[X,X,X],
],
FragmentType.Booster, // type
500,
3, // limit
));
Fragments.push(new Fragment(
3, // id
[ // shape
[X,X],
[X,X],
],
FragmentType.Cooling, // type
200,
Infinity, // limit
));
Fragments.push(new Fragment(
4, // id
[ // shape
[X],
],
FragmentType.Cooling, // type
50,
1, // limit
));
Fragments.push(new Fragment(
5, // id
[ // shape
[X, X],
],
FragmentType.HackingSpeed, // type
50,
1, // limit
));
Fragments.push(new Fragment(
6, // id
[
[X, _],
[X, X],
], // shape
FragmentType.HackingMoney, // type
10, // power
1, // limit
));
Fragments.push(new Fragment(
7, // id
[
[X, X],
[X, X],
], // shape
FragmentType.HackingGrow, // type
30, // power
1, // limit
));
Fragments.push(new Fragment(
8, // id
[
[X, X, X],
[_, X, _],
[X, X, X],
], // shape
FragmentType.Hacking, // type
50, // power
1, // limit
));
Fragments.push(new Fragment(
10, // id
[
[X, X],
[_, X],
], // shape
FragmentType.Strength, // type
50, // power
1, // limit
));
Fragments.push(new Fragment(
12, // id
[
[_, X],
[X, X],
], // shape
FragmentType.Defense, // type
50, // power
1, // limit
));
Fragments.push(new Fragment(
14, // id
[
[X, X],
[X, _],
], // shape
FragmentType.Dexterity, // type
50, // power
1, // limit
));
Fragments.push(new Fragment(
16, // id
[
[X, _],
[X, X],
], // shape
FragmentType.Agility, // type
50, // power
1, // limit
));
Fragments.push(new Fragment(
18, // id
[
[X, X],
[X, _],
], // shape
FragmentType.Charisma, // type
50, // power
1, // limit
));
Fragments.push(new Fragment(
20, // id
[
[X, _, _],
[X, X, _],
[X, X, X],
], // shape
FragmentType.HacknetMoney, // type
30, // power
1, // limit
));
Fragments.push(new Fragment(
21, // id
[
[X, X],
[_, X],
[_, X],
], // shape
FragmentType.HacknetCost, // type
-10, // power
1, // limit
));
Fragments.push(new Fragment(
25, // id
[
[X, X, X],
[_, X, _],
], // shape
FragmentType.Rep, // type
100, // power
1, // limit
));
Fragments.push(new Fragment(
27, // id
[
[X, _],
[_, X],
], // shape
FragmentType.WorkMoney, // type
20, // power
1, // limit
));
Fragments.push(new Fragment(
28, // id
[
[X, X],
], // shape
FragmentType.Crime, // type
20, // power
1, // limit
));
Fragments.push(new Fragment(
30, // id
[
[X, X, X],
[X, X, X],
[X, X, X],
], // shape
FragmentType.Bladeburner, // type
50, // power
1, // limit
));
Fragments.push(
new Fragment(
6, // id
[
[X, _],
[X, X],
], // shape
FragmentType.HackingMoney, // type
10, // power
1, // limit
),
);
Fragments.push(
new Fragment(
7, // id
[
[X, X],
[X, X],
], // shape
FragmentType.HackingGrow, // type
30, // power
1, // limit
),
);
Fragments.push(
new Fragment(
8, // id
[
[X, X, X],
[_, X, _],
[X, X, X],
], // shape
FragmentType.Hacking, // type
50, // power
1, // limit
),
);
Fragments.push(
new Fragment(
10, // id
[
[X, X],
[_, X],
], // shape
FragmentType.Strength, // type
50, // power
1, // limit
),
);
Fragments.push(
new Fragment(
12, // id
[
[_, X],
[X, X],
], // shape
FragmentType.Defense, // type
50, // power
1, // limit
),
);
Fragments.push(
new Fragment(
14, // id
[
[X, X],
[X, _],
], // shape
FragmentType.Dexterity, // type
50, // power
1, // limit
),
);
Fragments.push(
new Fragment(
16, // id
[
[X, _],
[X, X],
], // shape
FragmentType.Agility, // type
50, // power
1, // limit
),
);
Fragments.push(
new Fragment(
18, // id
[
[X, X],
[X, _],
], // shape
FragmentType.Charisma, // type
50, // power
1, // limit
),
);
Fragments.push(
new Fragment(
20, // id
[
[X, _, _],
[X, X, _],
[X, X, X],
], // shape
FragmentType.HacknetMoney, // type
30, // power
1, // limit
),
);
Fragments.push(
new Fragment(
21, // id
[
[X, X],
[_, X],
[_, X],
], // shape
FragmentType.HacknetCost, // type
-10, // power
1, // limit
),
);
Fragments.push(
new Fragment(
25, // id
[
[X, X, X],
[_, X, _],
], // shape
FragmentType.Rep, // type
100, // power
1, // limit
),
);
Fragments.push(
new Fragment(
27, // id
[
[X, _],
[_, X],
], // shape
FragmentType.WorkMoney, // type
20, // power
1, // limit
),
);
Fragments.push(
new Fragment(
28, // id
[[X, X]], // shape
FragmentType.Crime, // type
20, // power
1, // limit
),
);
Fragments.push(
new Fragment(
30, // id
[
[X, X, X],
[X, X, X],
[X, X, X],
], // shape
FragmentType.Bladeburner, // type
50, // power
1, // limit
),
);
})();
export const NoneFragment = new Fragment(-2, [], FragmentType.None, 0, Infinity);

@ -9,9 +9,11 @@ import Typography from "@mui/material/Typography";
type IProps = {
fragment: ActiveFragment | null;
x: number;
y: number;
};
export function FragmentInspector(props: IProps) {
export function FragmentInspector(props: IProps): React.ReactElement {
const [, setC] = useState(new Date());
useEffect(() => {
@ -38,6 +40,7 @@ export function FragmentInspector(props: IProps) {
<br />
[X, Y] N/A
<br />
[X, Y] {props.x}, {props.y}
</Typography>
</Paper>
);
@ -68,8 +71,9 @@ export function FragmentInspector(props: IProps) {
<br />
Effect: {effect}
<br />
[X, Y] {props.fragment.x}, {props.fragment.y}
root [X, Y] {props.fragment.x}, {props.fragment.y}
<br />
[X, Y] {props.x}, {props.y}
</Typography>
</Paper>
);

@ -1,5 +1,5 @@
import * as React from "react";
import { Fragment, Fragments, NoneFragment } from "../Fragment";
import { Fragment, NoneFragment } from "../Fragment";
import { ActiveFragment } from "../ActiveFragment";
import { FragmentType } from "../FragmentType";
import { IStaneksGift } from "../IStaneksGift";
@ -7,6 +7,9 @@ import { Cell } from "./Cell";
import { FragmentInspector } from "./FragmentInspector";
import { FragmentSelector } from "./FragmentSelector";
import Button from "@mui/material/Button";
import TableRow from "@mui/material/TableRow";
import TableBody from "@mui/material/TableBody";
import { Table } from "../../ui/React/Table";
function zeros(dimensions: number[]): any {
const array = [];
@ -116,9 +119,9 @@ export function Grid(props: GridProps): React.ReactElement {
);
}
elems.push(
<div key={j} className="staneksgift_row">
<TableRow key={j} className="staneksgift_row">
{cells}
</div>,
</TableRow>,
);
}
@ -130,10 +133,12 @@ export function Grid(props: GridProps): React.ReactElement {
return (
<>
{elems}
<Table>
<TableBody>{elems}</TableBody>
</Table>
<FragmentSelector gift={props.gift} selectFragment={updateSelectedFragment} />
<Button onClick={clear}>Clear</Button>
<FragmentInspector fragment={props.gift.fragmentAt(pos[0], pos[1])} />
<FragmentInspector x={pos[0]} y={pos[1]} fragment={props.gift.fragmentAt(pos[0], pos[1])} />
</>
);
}