Unit toolsProc; Interface Uses dataUnit; Procedure doMagnet(Var g:GameState); Implementation Function inBounds(g:GameState; row, col:integer): Boolean; Begin If (row <= g.mapHeight) And (col <= g.mapWidth) And (row >= 1) And (col >= 1) Then Exit(true) Else Exit(false); End; Procedure doMagnet(Var g:GameState); Var row, col, i, s: integer; rstep: integer = 0; cstep: integer = 0; Begin For row := 1 To g.mapHeight Do For col := 1 To g.mapWidth Do Begin Case g.map[row,col] Of magnetx: cstep := 1; magnety: rstep := 1; Else continue; End; For i := 0 To 1 Do Begin s := 2*i-1; (* Follow man *) If inBounds(g,row - 2*s*rstep, col - 2*s*cstep) And (g.map[row - 2*s*rstep, col - 2*s*cstep] = man) And (g.map[row - s*rstep, col - s*cstep] = empty) Then Begin g.map[row - s*rstep, col - s*cstep] := g.map[row,col]; g.map[row,col] := empty; (* Drag pushables *) If inBounds(g, row + s*rstep, col + s*cstep) And (g.map[row + s*rstep, col + s*cstep] In pushable) Then Begin g.map[row,col] := g.map[row + s*rstep, col + s*cstep]; g.map[row + s*rstep, col + s*cstep] := empty; End; End; (* Pull pushables *) If inBounds(g, row + 2*s*rstep, col + 2*s*cstep) And (g.map[row + 2*s*rstep, col + 2*s*cstep] In pushable) And (g.map[row + s*rstep, col + s*cstep] = empty) Then Begin g.map[row + s*rstep, col + s*cstep] := g.map[row + 2*s*rstep, col + 2*s*cstep]; g.map[row + 2*s*rstep, col + 2*s*cstep] := empty; End; End; End; End; End.