@@ -8,83 +8,54 @@ namespace tilesExt {
88 import TL = tiles . Location ;
99
1010 /**
11- * Iterates over a line between two locations. If the handler returns truthy, then the iteration is stopped,
12- * and the handlers return value is returned, otherwise the iteration runs to completion and returns undefined.
11+ * Calculates the locations between two given locations.
1312 * @param lineType width of maze
1413 * @param l1 start
1514 * @param l2 end
16- * @param handler a handler which is invoked for each location
1715 * @param exclusive exclude the endpoints
18- * @returns undefined if the whole line was iterated
16+ * @returns The locations intersected by the line
1917 */
2018 //% blickId="tilesExt_line"
21- //% block="for each $loc on $lineType line from $l1 to $l2 exclusive $exclusive"
19+ //% block="array of locations on $lineType line from $l1 to $l2 || exclusive $exclusive"
2220 //% exclusive.defl=false
2321 //% inlineInputMode=inline
2422 //% l1.shadow=mapgettile
2523 //% l2.shadow=mapgettile
26- //% loc.shadow=loc
27- //% draggableParameters="reporter"
28- export function line < T > ( lineType : LineType , l1 : TL , l2 : TL , exclusive : boolean , handler : ( loc : TL ) => T ) : T {
29- return lineType === LineType . Diagonal ? diagonalLine ( l1 , l2 , exclusive , handler ) :
30- lineType === LineType . Covering ? coveringLine ( l1 , l2 , exclusive , handler ) :
24+ export function line ( lineType : LineType , l1 : TL , l2 : TL , exclusive : boolean ) : TL [ ] {
25+ return lineType === LineType . Diagonal ? diagonalLine ( l1 , l2 , exclusive ) :
26+ lineType === LineType . Covering ? coveringLine ( l1 , l2 , exclusive ) :
3127 undefined ;
3228 }
3329
34- /**
35- * Iterates over a line between two locations. If the handler returns truthy, then the iteration is stopped,
36- * and the handlers return value is returned, otherwise the iteration runs to completion and returns undefined.
37- * @param lineType width of maze
38- * @param l1 start
39- * @param l2 end
40- * @param handler a handler which is invoked for each location
41- * @param exclusive exclude the endpoints
42- * @returns undefined if the whole line was iterated
43- */
44- //% block="for each $loc on $lineType line from $l1 to $l2 exclusive $exclusive"
45- //% blockId="tilesExt_line_statement"
46- //% blockAliasFor="tilesExt.line"
47- //% exclusive.defl=false
48- //% inlineInputMode=inline
49- //% l1.shadow=mapgettile
50- //% l2.shadow=mapgettile
51- //% draggableParameters="reporter"
52- //% topblock=false
53- //% handlerStatement=true
54- export function _line ( lineType : LineType , l1 : TL , l2 : TL , exclusive : boolean , handler : ( loc : TL ) => boolean | void ) : void {
55- line ( lineType , l1 , l2 , exclusive , handler ) ;
56- }
5730
5831 function lerp ( start : number , end : number , t : number ) {
5932 return start * ( 1.0 - t ) + t * end ;
6033 }
6134
62- function diagonalLine < T > ( l1 : TL , l2 : TL , exclusive : boolean , handler : ( loc : TL ) => T ) : T {
35+ function diagonalLine ( l1 : TL , l2 : TL , exclusive : boolean ) : TL [ ] {
6336 const dx = l2 . col - l1 . col , dy = l2 . row - l1 . row ;
6437 const N = Math . max ( Math . abs ( dx ) , Math . abs ( dy ) ) ;
6538 if ( N <= 0 ) {
66- return exclusive ? undefined : handler ( l1 ) ;
67- } else {
68- const lastN = N - ( exclusive ? 1 : 0 ) ;
69- for ( let step = ( exclusive ? 1 : 0 ) ; step <= lastN ; step ++ ) {
70- let t = step / N ;
71- const res = handler (
72- new TL (
73- Math . round ( lerp ( l1 . col , l2 . col , t ) ) ,
74- Math . round ( lerp ( l1 . row , l2 . row , t ) ) ,
75- l1 . tileMap
76- ) ) ;
77- if ( res ) return res ;
78- }
39+ return exclusive ? [ ] : [ l1 ] ;
7940 }
8041
81- return undefined ;
42+ const res = [ ] ;
43+ const lastN = N - ( exclusive ? 1 : 0 ) ;
44+ for ( let step = ( exclusive ? 1 : 0 ) ; step <= lastN ; step ++ ) {
45+ let t = step / N ;
46+ res . push (
47+ new TL (
48+ Math . round ( lerp ( l1 . col , l2 . col , t ) ) ,
49+ Math . round ( lerp ( l1 . row , l2 . row , t ) ) ,
50+ l1 . tileMap
51+ ) ) ;
52+ }
53+
54+ return res ;
8255 }
8356
84-
85-
8657
87- export function coveringLine < T > ( l1 : TL , l2 : TL , exclusive : boolean , handler : ( loc : TL ) => T ) : T {
58+ export function coveringLine ( l1 : TL , l2 : TL , exclusive : boolean ) : TL [ ] {
8859 // https://www.redblobgames.com/grids/line-drawing/#stepping
8960 const dx = l2 . col - l1 . col , dy = l2 . row - l1 . row ;
9061 const absx = Math . abs ( dx ) , absy = Math . abs ( dy ) ;
@@ -102,8 +73,9 @@ namespace tilesExt {
10273 }
10374 }
10475
76+ const res = [ ] ;
10577 for ( ; ix < absx || iy < absy ; ) {
106- const res = handler ( new TL ( x , y , l1 . tileMap ) ) ;
78+ res . push ( new TL ( x , y , l1 . tileMap ) ) ;
10779 if ( res ) return res ;
10880 if ( ( 1 + ix << 1 ) * absy < ( 1 + iy << 1 ) * absx ) {
10981 x += stepx ;
@@ -114,23 +86,10 @@ namespace tilesExt {
11486 }
11587 }
11688 if ( ! exclusive ) {
117- const res = handler ( new TL ( x , y , l1 . tileMap ) ) ;
118- if ( res ) return res ;
89+ res . push ( new TL ( x , y , l1 . tileMap ) ) ;
11990 }
12091
121- return undefined ;
122- }
123-
124- export function isWallBetweenLocations ( l1 : TL , l2 : TL , tileMap ?: tiles . TileMap ) : TL | void {
125- tileMap = tileMap || game . currentScene ( ) . tileMap ;
126- return coveringLine ( l1 , l2 , true , loc => tileMap . isObstacle ( loc . col , loc . row ) ? loc : undefined ) ;
127- }
128-
129-
130- export function setTileBetweenLocations ( l1 : TL , l2 : TL , im : Image , tileMap ?: tiles . TileMap ) : void {
131- tileMap = tileMap || game . currentScene ( ) . tileMap ;
132- const index = tileMap . getImageType ( im ) ;
133- coveringLine ( l1 , l2 , false , loc => tileMap . setTileAt ( loc . col , loc . row , index ) ) ;
92+ return res ;
13493 }
13594
13695
0 commit comments