1
\$\begingroup\$

Shown below is a function I wrote for pawn move generation, I find it difficult to understand what the code does in a glance due to the cumbersome if statements, so any changes I make are done unnecessarily slowly. Is there a way to avoid these complex if statements so that the code is more maintainable?

  if(standardPawn.indexOf(this.board[position.y][position.x]) != -1){
          if(position.x + 1 < 8){
            if(board[position.y][position.x + 1].canEnpas === true && standardPawn.indexOf(board[position.y][position.x + 1]) == -1){
              moves.push({x: position.x + 1, y: position.y - 1});
            }
          }
          if(position.y == 6){
            if(board[position.y - 1][position.x] == "vacant"){
              moves.push({x: position.x, y: position.y - 1});
            }
            if(board[position.y - 2][position.x] == "vacant" && board[position.y - 1][position.x] == "vacant"){
              moves.push({x: position.x, y: position.y - 2});
            }
          } else if(position.y - 1 >= 0){
            if(board[position.y - 1][position.x] == "vacant"){
              moves.push({x: position.x, y: position.y - 1});
            }
          }
          if(position.x + 1 < 8 && position.y - 1 >= 0){
            if(getPieceType({x: position.x + 1, y: position.y - 1}, this.board) != pieceType && board[position.y - 1][position.x + 1] != "vacant"){
              moves.push({x: position.x + 1, y: position.y - 1});
            }
          }
          if(position.x - 1 >= 0 && position.y - 1 >= 0){
            if(getPieceType({x: position.x - 1, y: position.y - 1}, this.board) != pieceType && board[position.y - 1][position.x - 1] != "vacant"){
              moves.push({x: position.x - 1, y: position.y - 1});
            }
          }
        } else {
          if(position.x + 1 < 8){
            if(board[position.y][position.x + 1].canEnpas === true && standardPawn.indexOf(board[position.y][position.x + 1]) != -1){
              moves.push({x: position.x + 1, y: position.y + 1});
            }
          }
          if(position.y == 1){
            if(board[position.y + 1][position.x] == "vacant"){
              moves.push({x: position.x, y: position.y + 1});
            }
            if(board[position.y + 2][position.x] == "vacant" && board[position.y + 1][position.x] == "vacant"){
              moves.push({x: position.x, y: position.y + 2});
            }
          } else if(position.y + 1 < 8){
            if(board[position.y + 1][position.x] == "vacant"){
              moves.push({x: position.x, y: position.y + 1});
            }
          }
          if(position.x + 1 < 8 && position.y + 1 < 8){
            if(getPieceType({x: position.x + 1, y: position.y + 1}, this.board) != pieceType && board[position.y + 1][position.x + 1] != "vacant"){
              moves.push({x: position.x + 1, y: position.y + 1});
            }
          }
          if(position.x - 1 >= 0 && position.y + 1 < 8){
            if(getPieceType({x: position.x - 1, y: position.y + 1}, this.board) != pieceType && board[position.y + 1][position.x - 1] != "vacant"){
              moves.push({x: position.x - 1, y: position.y + 1});
            }
          }
        }
\$\endgroup\$
1
\$\begingroup\$

You can predefine some of the conditions. E.g.

let blocked = (board[position.y - 1][position.x] !== "vacant")
let unmoved = (y === 6)
…

You can also define some short functions. E.g. isEnemy(x,y) would return true if there is an enemy piece at that position.

Then using those variables in the tests will make them look tidier, and be easier to read and understand.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

You can enhance the readability by extracting the conditons of your ifs to functions without chanceing the performance. Plus you can remove your duplicate code like positon.x +1 < 8

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.