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

View File

@ -51,7 +51,7 @@ export class ActiveFragment {
fragment(): Fragment { fragment(): Fragment {
const fragment = FragmentById(this.id); 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; return fragment;
} }
@ -68,7 +68,7 @@ export class ActiveFragment {
copy(): ActiveFragment { copy(): ActiveFragment {
// We have to do a round trip because the constructor. // We have to do a round trip because the constructor.
const fragment = FragmentById(this.id); 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 }); const c = new ActiveFragment({ x: this.x, y: this.y, fragment: fragment });
c.charge = this.charge; c.charge = this.charge;
c.heat = this.heat; c.heat = this.heat;

View File

@ -3,287 +3,336 @@ import { FragmentType } from "./FragmentType";
export const Fragments: Fragment[] = []; export const Fragments: Fragment[] = [];
export class Fragment { export class Fragment {
id: number; id: number;
shape: boolean[][]; shape: boolean[][];
type: FragmentType; type: FragmentType;
power: number; power: number;
limit: number; limit: number;
constructor(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.id = id;
this.shape = shape; this.shape = shape;
this.type = type; this.type = type;
this.power = power; this.power = power;
this.limit = limit; 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 { return cells;
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() { copy(): Fragment {
// check every line for robustness. return new Fragment(
return Math.max(...this.shape.map(line => line.length)); this.id,
} this.shape.map((a) => a.slice()),
this.type,
height() { this.power,
return this.shape.length; this.limit,
} );
}
// 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);
}
} }
export function FragmentById(id: number): Fragment | null { export function FragmentById(id: number): Fragment | null {
for(const fragment of Fragments) { for (const fragment of Fragments) {
if(fragment.id === id) return fragment; if (fragment.id === id) return fragment;
} }
return null; 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() { Fragments.push(
const _ = false; new Fragment(
const X = true; 6, // id
Fragments.push(new Fragment( [
0, // id [X, _],
[ // shape [X, X],
[X,X,X], ], // shape
[_,_,X], FragmentType.HackingMoney, // type
[_,_,X], 10, // power
], 1, // limit
FragmentType.Hacking, // type ),
10, );
1, // limit Fragments.push(
)); new Fragment(
Fragments.push(new Fragment( 7, // id
1, // id [
[ // shape [X, X],
[_,X,_], [X, X],
[X,X,X], ], // shape
[_,X,_], FragmentType.HackingGrow, // type
], 30, // power
FragmentType.Hacking, // type 1, // limit
10, ),
1, // limit );
)); Fragments.push(
Fragments.push(new Fragment( new Fragment(
2, // id 8, // id
[ // shape [
[X,X,X], [X, X, X],
[X,_,X], [_, X, _],
[X,X,X], [X, X, X],
], ], // shape
FragmentType.Booster, // type FragmentType.Hacking, // type
500, 50, // power
3, // limit 1, // limit
)); ),
Fragments.push(new Fragment( );
3, // id Fragments.push(
[ // shape new Fragment(
[X,X], 10, // id
[X,X], [
], [X, X],
FragmentType.Cooling, // type [_, X],
200, ], // shape
Infinity, // limit FragmentType.Strength, // type
)); 50, // power
Fragments.push(new Fragment( 1, // limit
4, // id ),
[ // shape );
[X], Fragments.push(
], new Fragment(
FragmentType.Cooling, // type 12, // id
50, [
1, // limit [_, X],
)); [X, X],
Fragments.push(new Fragment( ], // shape
5, // id FragmentType.Defense, // type
[ // shape 50, // power
[X, X], 1, // limit
], ),
FragmentType.HackingSpeed, // type );
50, Fragments.push(
1, // limit new Fragment(
)); 14, // id
[
Fragments.push(new Fragment( [X, X],
6, // id [X, _],
[ ], // shape
[X, _], FragmentType.Dexterity, // type
[X, X], 50, // power
], // shape 1, // limit
FragmentType.HackingMoney, // type ),
10, // power );
1, // limit Fragments.push(
)); new Fragment(
Fragments.push(new Fragment( 16, // id
7, // id [
[ [X, _],
[X, X], [X, X],
[X, X], ], // shape
], // shape FragmentType.Agility, // type
FragmentType.HackingGrow, // type 50, // power
30, // power 1, // limit
1, // limit ),
)); );
Fragments.push(new Fragment( Fragments.push(
8, // id new Fragment(
[ 18, // id
[X, X, X], [
[_, X, _], [X, X],
[X, X, X], [X, _],
], // shape ], // shape
FragmentType.Hacking, // type FragmentType.Charisma, // type
50, // power 50, // power
1, // limit 1, // limit
)); ),
Fragments.push(new Fragment( );
10, // id Fragments.push(
[ new Fragment(
[X, X], 20, // id
[_, X], [
], // shape [X, _, _],
FragmentType.Strength, // type [X, X, _],
50, // power [X, X, X],
1, // limit ], // shape
)); FragmentType.HacknetMoney, // type
Fragments.push(new Fragment( 30, // power
12, // id 1, // limit
[ ),
[_, X], );
[X, X], Fragments.push(
], // shape new Fragment(
FragmentType.Defense, // type 21, // id
50, // power [
1, // limit [X, X],
)); [_, X],
Fragments.push(new Fragment( [_, X],
14, // id ], // shape
[ FragmentType.HacknetCost, // type
[X, X], -10, // power
[X, _], 1, // limit
], // shape ),
FragmentType.Dexterity, // type );
50, // power Fragments.push(
1, // limit new Fragment(
)); 25, // id
Fragments.push(new Fragment( [
16, // id [X, X, X],
[ [_, X, _],
[X, _], ], // shape
[X, X], FragmentType.Rep, // type
], // shape 100, // power
FragmentType.Agility, // type 1, // limit
50, // power ),
1, // limit );
)); Fragments.push(
Fragments.push(new Fragment( new Fragment(
18, // id 27, // id
[ [
[X, X], [X, _],
[X, _], [_, X],
], // shape ], // shape
FragmentType.Charisma, // type FragmentType.WorkMoney, // type
50, // power 20, // power
1, // limit 1, // limit
)); ),
Fragments.push(new Fragment( );
20, // id Fragments.push(
[ new Fragment(
[X, _, _], 28, // id
[X, X, _], [[X, X]], // shape
[X, X, X], FragmentType.Crime, // type
], // shape 20, // power
FragmentType.HacknetMoney, // type 1, // limit
30, // power ),
1, // limit );
)); Fragments.push(
Fragments.push(new Fragment( new Fragment(
21, // id 30, // id
[ [
[X, X], [X, X, X],
[_, X], [X, X, X],
[_, X], [X, X, X],
], // shape ], // shape
FragmentType.HacknetCost, // type FragmentType.Bladeburner, // type
-10, // power 50, // power
1, // limit 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); export const NoneFragment = new Fragment(-2, [], FragmentType.None, 0, Infinity);

View File

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

View File

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