A world-class math input for the web
at main 59 lines 1.6 kB view raw
1import { TokenFlow } from "../flow"; 2 3export class GridFlow extends TokenFlow { 4 rows: number; 5 columns: number; 6 7 constructor(rows: number, columns: number) { 8 super(); 9 this.rows = rows; 10 this.columns = columns; 11 } 12 13 get requiredLength(): number | null { 14 return this.rows * this.columns; 15 } 16 17 isWithin( 18 anchorIndex: number, 19 headIndex: number, 20 otherIndex: number 21 ): boolean { 22 const anchorRow = Math.floor(anchorIndex / this.columns); 23 const anchorCol = anchorIndex % this.columns; 24 const headRow = Math.floor(headIndex / this.columns); 25 const headCol = headIndex % this.columns; 26 const otherRow = Math.floor(otherIndex / this.columns); 27 const otherCol = otherIndex % this.columns; 28 29 const minRow = Math.min(anchorRow, headRow); 30 const maxRow = Math.max(anchorRow, headRow); 31 const minCol = Math.min(anchorCol, headCol); 32 const maxCol = Math.max(anchorCol, headCol); 33 34 return ( 35 otherRow >= minRow && 36 otherRow <= maxRow && 37 otherCol >= minCol && 38 otherCol <= maxCol 39 ); 40 } 41 42 verticalCandidates( 43 direction: "up" | "down", 44 fromIndex: number, 45 length: number 46 ): number[] { 47 const row = Math.floor(fromIndex / this.columns); 48 const col = fromIndex % this.columns; 49 const candidates: number[] = []; 50 51 if (direction === "up" && row > 0) { 52 candidates.push((row - 1) * this.columns + col); 53 } else if (direction === "down" && row < this.rows - 1) { 54 candidates.push((row + 1) * this.columns + col); 55 } 56 57 return candidates.filter((index) => index < length); 58 } 59}