user9122229
user9122229

Reputation:

Bash script getting slower and slower

So I created this account only to ask this question, I'm desperate, lol.

I'm currently working on a tiny game in Bash and got a nice base - I thought. The problem is every time I move, the script gets slower and slower until it reaches a certain point at which the game's movement 'lags' like half a second behind the input.

Here is my script:

#!/bin/bash
source $(dirname $0)/gui.sh

# Position coordinates of character
charx=0
chary=0

# OUTPUT THE MAP AND WAIT FOR KEY STROKE
function output {

  clear
  echo -e "$charx $chary\n"
  j=0
  while [ "$j" -le "$i" ]
  do

    outputLevel="level$j"
    echo "${!outputLevel}"
    ((j++))

  done
  read -s -n1 control
  movement

}

# THIS MANAGES MOVEMENT AND ALSO BORDERS
function movement {

  if [ "$control" = "$moveLeftKey" ]
  then
    let moveToX="$charx-1"
    moveToY="$chary"
  elif [ "$control" = "$moveRightKey" ]
  then
    let moveToX="$charx+1"
    moveToY="$chary"
  elif [ "$control" = "$moveUpKey" ]
  then
    let moveToY="$chary+1"
    moveToX="$charx"
  elif [ "$control" = "$moveDownKey" ]
  then
    let moveToY="$chary-1"
    moveToX="$charx"
  else
    output
  fi

  #PlayerPosition="array$chary[$charx]"
  nextPosition="array$moveToY[$moveToX]"
  if [ "${!nextPosition}" = " " ]
  then

    IFS= read "array$chary[$charx]" <<< " "
    IFS= read "array$moveToY[$moveToX]" <<< "$charLetter"
    charx="$moveToX"
    chary="$moveToY"
    render_map

  else
    output
  fi

}

# SET THE OUTPUT VARS FOR FUNCTION OUTPUT() FROM THE READ MAP FILE
function render_map {

  j=0

  while [ "$j" -le "$i" ]
  do

    arr="array$j[@]"
    for lvl in "${!arr}"
    do

      tmp+="$lvl"

    done
    declare level$j="$tmp"
    tmp=
    ((j++))

  done
  output

}

# LOCATE THE PLAYER ASCII CHARACTER DEFINED IN $charLetter
function locate_player {

  j=0

  while [ "$j" -le "$i" ]
  do

    arr="array$j[@]"
    a=0
    for searchPos in "${!arr}"
    do

      if [ "$searchPos" = "$charLetter" ]
      then
        charx="$a"
        chary="$j"
      else
        ((a++))
      fi

    done
    ((j++))
  done
  render_map

}

# READ FROM THE VAR $MAPFILE
function read_map {

  i=0

  while IFS= read -r "var"
  do
    IFS=',' read -r -a "array$i" <<< "$var"
    ((i++))
  done < "$mapfile"
  locate_player

}

# START TRIGGER
function start {
  gui
  # After GUI finished start the game by reading the map file
  read_map
}

start

Notice: the imported script will take care of the gui at some further point, but for now it only imports the following variables: $charLetter, $moveRightKey, $moveLeftKey, $moveDownKey, $moveUpKey and $mapfile.

I'm happy to hear any ideas, suggestions or any other thought-provoking impulse!

Upvotes: 2

Views: 182

Answers (1)

Toby Speight
Toby Speight

Reputation: 30960

You seem to be recursing very deeply, and never actually returning from any of your functions. Bash doesn't do tail-call elimination, so you're steadily eating memory in the form of the function call stack.

You'll want to replace the deep nesting with some sort of while input; do action loop.

Upvotes: 1

Related Questions