0

I have coded a game based on JS and DFS algorithm. It's similar to pacman, only both computer and the player are trying to get as many gold coins as possible.

I use DFS to calculate the computer path to the coin, then using setTimeout initialize the path. If the player has taken to coin before, it recalculates path to the next coin.

The thing is, every time the user has taken a coin, it takes too mush time for the computer to calculate the new path, especially if he is taking a few in a row. then as a result, the computer get stuck in the same position.

Kinda 80s look alike game performance...

There is much more code, but below are the main functions. how do i make this game perform better?

//Here is the DFS path generating code


checkPath = (rowS, colS, rowM, colM, matrix)=>{

        if (rowS < 0 || colS < 0 || rowS > this.row || colS > this.col) return false
        if(matrix[rowS][colS] == 'b' || matrix[rowS][colS] == '$' || matrix[rowS][colS]== '2') return false

        matrix[rowS][colS] = '$'

        this.printAnyMatrix(matrix)

        if (rowS == rowM && colS== colM){
            this.compPath.unshift({'row': rowS, 'col': colS})
            return true  
        } 

        if (this.checkPath(rowS-1, colS, rowM, colM, matrix)){
            this.compPath.unshift({'row': rowS, 'col': colS})
            return true  
        } 
        if (this.checkPath(rowS, colS+1, rowM, colM, matrix)){
            this.compPath.unshift({'row': rowS, 'col': colS})
            return true  
        }       
        if (this.checkPath(rowS+1, colS, rowM, colM, matrix)){
            this.compPath.unshift({'row': rowS, 'col': colS})
            return true  
        }      
        if (this.checkPath(rowS, colS-1, rowM, colM, matrix)) {
            this.compPath.unshift({'row': rowS, 'col': colS})
            return true  
        }

        this.printAnyMatrix(matrix)
        console.log('false')

        return false

    }

//And here is the computer function, it's being invoked every time computer has got to a coin or that the player has taken a coin.


const getClosestCoin = function (location, goldMap) {
    let closestCoin = goldMap[0]
    closestCoin.distance = Math.abs(goldMap[0].row - location.row) + Math.abs(goldMap[0].col - location.col)

    for (let i = 0; i < goldMap.length; i++) {
        goldMap[i].distance = Math.abs(goldMap[i].row - location.row) + Math.abs(goldMap[i].col - location.col)     

        if (goldMap[i].distance < closestCoin.distance){
            closestCoin = goldMap[i]
            closestCoin.goldIndex = i
        }
    }
    return closestCoin
}

const computer = function(GoldRushBoard, clearTimeoutArry){
    let rowM = GoldRushBoard.row +1
    let colM = GoldRushBoard.col +1
    let location = {row:GoldRushBoard.player1.row, col:GoldRushBoard.player1.col}
    let closestCoin = {}
    let path = GoldRushBoard.compPath = []

    GoldRushBoard.goldMap = []
    let matrixCopy = copyMatrix(GoldRushBoard.matrix, GoldRushBoard.goldMap)
    if(GoldRushBoard.goldMap.length==0) return

    closestCoin = getClosestCoin(location, GoldRushBoard.goldMap)
    GoldRushBoard.checkPath(location.row, location.col, closestCoin.row, closestCoin.col, matrixCopy)

    for (let i = 0; i < path.length-1; i++) {

        let k = i

        let setTimeoutMove = setTimeout(function(){
            console.log('count ', k);

            if(GoldRushBoard.matrix[path[k+1].row][path[k+1].col]=='c'){
                GoldRushBoard.player1.score ++
                Render.updateScore(GoldRushBoard.player1)
            }

            GoldRushBoard.alter(path[k].row, path[k].col,'.')
            GoldRushBoard.alter(path[k+1].row, path[k+1].col, 1)

            GoldRushBoard.player1.row = path[k+1].row
            GoldRushBoard.player1.col = path[k+1].col

            Render.generateMatrix(rowM, colM, GoldRushBoard.matrix)

            if(k == path.length-2){
                computer(GoldRushBoard, clearTimeoutArry)
            }

        }, 500*(k+1))

        clearTimeoutArry.push(setTimeoutMove)

        location.row = path[i+1].row
        location.col = path[i+1].col
    }
}    

Jeremy Harris
  • 24,318
  • 13
  • 79
  • 133
yoni349
  • 107
  • 1
  • 15
  • Are you actually clearing the timeouts in `clearTimeoutArry`? That would probably improve performance. – Jeremy Harris Feb 05 '20 at 14:48
  • There's too much code here for me to digest. Can you try to create a [minimal example](https://stackoverflow.com/help/mcve) of what's failing to perform adequately? – Scott Sauyet Feb 06 '20 at 16:30
  • @jeremy yes, if the computer needs to recalculate the path, i.e player have changed the game board and took a coin, all timers are cleared and a new path is calculated. – yoni349 Feb 06 '20 at 17:17
  • @scott the issue is happening when the player takes a coin and the computer needs to recalculate path. That init the checkPath function. By the time a new path has been calculated to the next coin, the player has time to get another coin, which calls the function a gain, and again... what make it look like it's stuck. Basically, you can just look on the checkPath function i think. – yoni349 Feb 06 '20 at 17:21
  • What are `rowS` and `colS` as opposed to `rowM` and `colM`? And what does `printAnyMatrix` do? It looks as though it's for some side-effect, which I would not want in a recursive calculation. So too with `this.compPath.unshift(...)`. Basically, if `checkPath` is meant to find if a path is valid, it should probably not do anything else, especially not manipulate local state. If it's meant to *find* a path, then it's possible you'd manipulate some recursion parameters for performance, but you ideally should not do anything else. Basically, I don't yet really understand the code. – Scott Sauyet Feb 06 '20 at 18:34
  • If you're looking to find shortest path through a grid with some barriers, then I would suggest you look to [Dijkstra's Algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) for a clean way to do this. That may be what you're doing; I simply can't tell. – Scott Sauyet Feb 06 '20 at 18:45
  • @scott rowS/colS is the starting point in the maze, rowM/colM is the destination i.e a gold coin. PrintAnyMatrx just console.log the matrix with the path done in the recursive (I'll take it off). this.compPath is recording the path, and only once recursive is done I'm executing the path in the actual game. So maybe I should execute each step directly in the game board? Meaning if the a step successful pass the recursive stop test (out of the board or a wall) then I'll initiate a the setTimeout with the step destination. Though that might cause more actual steps ? – yoni349 Feb 06 '20 at 21:41

0 Answers0