+fast_checks() {
+ asteroid=$1
+ start_x=${asteroid%,*}
+ start_y=${asteroid#*,}
+
+ max_x=$width
+ max_y=$ln
+
+ # directions:
+ # -1, 0 - left
+ # 1, 0 - right
+ # 0, 1 - up
+ # 0,-1 - down
+ # -1, 1 - diagonal left down
+ # -1,-1 - diagonal left up
+ # 1, 1 - diagonal right down
+ # 1,-1 - diagonal right up
+ for direction in -1,0 1,0 0,1 0,-1 -1,1 -1,-1 1,1 1,-1; do
+ #for direction in "-1,0" "1,0" "0,1" "0,-1"; do
+ stepx=${direction%,*}
+ stepy=${direction#*,}
+ do_blocker_check $start_x $start_y $stepx $stepy
+ done
+}
+
+do_blocker_check() {
+ startx=$1
+ starty=$2
+ stepx=$3
+ stepy=$4
+
+ hitblocker=0
+
+ if [ $stepx -eq 0 -a $stepy -eq 0 ]; then
+ echo "Somehow got 0 and 0 as steps"
+ return
+ fi
+
+ local x=$startx
+ local y=$starty
+
+ # add the steps before we start the loop to not be
+ # on ourselves
+ x=$((x+$stepx))
+ y=$((y+$stepy))
+
+ while [ $x -le $width -a $x -ge 0 -a $y -le $ln -a $y -ge 0 ]; do
+ if [ ${asteroids[$x,$y]+a} ]; then
+ if [ $hitblocker -eq 0 ]; then
+ cansee[$asteroid,$x,$y]=1
+ cansee[$x,$y,$startx,$starty]=1
+ hitblocker=1
+ else
+ cantsee[$startx,$starty,$x,$y]=1
+ cantsee[$x,$y,$startx,$starty]=1
+ fi
+ fi
+ x=$((x+$stepx))
+ y=$((y+$stepy))
+ done
+}
+
+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
+}
+