+fast_checks() {
+ asteroid=$1
+ start_x=${asteroid%,*}
+ start_y=${asteroid#*,}
+
+ hitblocker=0
+
+ max_x=$width
+ max_y=$ln
+
+ # first, head left of the asteroid
+ for (( x=$((start_x-1)); x>=0; x-- )); do
+ do_blocker_check $asteroid $x $start_y
+ done
+ hitblocker=0 # this gets updated in do_blocker_check, reset it
+
+ # now head right of the asteroid
+ for (( x=$(($start_x+1)); x<= $width; x++ )); do
+ do_blocker_check $asteroid $x $start_y
+ done
+ hitblocker=0 # this gets updated in do_blocker_check, reset it
+
+ # head upwards
+ for (( y=$((start_y-1)); y>=0; y-- )); do
+ do_blocker_check $asteroid $start_x $y
+ done
+ hitblocker=0 # this gets updated in do_blocker_check, reset it
+
+ # head down
+ for (( y=$((start_y+1)); y<=$ln; y++ )); do
+ do_blocker_check $asteroid $start_x $y
+ done
+}
+
+do_blocker_check() {
+ asteroid=$1
+ x=$2
+ y=$3
+
+ if [ ${asteroids[$x,$y]+a} ]; then
+ if [ $hitblocker -eq 0 ]; then
+ cansee[$asteroid,$x,$y]=1
+ cansee[$x,$y,$asteroid]=1
+ hitblocker=1
+ else
+ cantsee[$asteroid,$x,$y]=1
+ cantsee[$x,$y,$asteroid]=1
+ fi
+ fi
+}
+
+possibly_in_way() {
+ source_x=$1
+ source_y=$2
+ sink_x=$3
+ sink_y=$4
+ blocker_x=$5
+ blocker_y=$6
+
+ # first check the horizontal and vertical planes
+ if [[ ( $source_x -eq $sink_x && $sink_x -eq $blocker_x ) && ( $sink_y -gt $blocker_y && $blocker_y -gt $source_y ) || ( $sink_y -lt $blocker_y && $blocker_y -lt $source_y ) ]] ||
+ [[ ( $source_y -eq $sink_y && $sink_y -eq $blocker_y ) && ( $sink_x -gt $blocker_x && $blocker_x -gt $source_x ) || ( $sink_x -lt $blocker_x && $blocker_x -lt $source_x ) ]]; then
+ return 0
+ fi
+
+ # if our source asteroid is further to the right thank our sink, then to stand half a chance
+ # of being in the way, the blocker has to be x > $sink_x and x < source_x
+ # apply the same rule for y
+ # reverse the direction and do the same checks.
+ # So if source_x < sink_x then blocker_x has to be < sink_x > source_x
+ if [ $source_x -gt $sink_x -a $blocker_x -gt $sink_x -a $blocker_x -lt $source_x ] ||
+ [ $source_y -gt $sink_y -a $blocker_y -gt $sink_y -a $blocker_y -lt $source_y ] ||
+ [ $source_x -lt $sink_x -a $blocker_x -lt $sink_x -a $blocker_x -gt $source_x ] ||
+ [ $source_y -lt $sink_y -a $blocker_y -lt $sink_y -a $blocker_y -gt $source_y ]; then
+ return 0
+ fi
+
+ return 1
+}
+