我的字符串不会在循环中重新声明

问题描述 投票:0回答:1

我一直在编写Battlesnake(https://play.battlesnake.com/)并且我需要重新声明我的移动命令(例如

move="left"
move="right"
)命令,但每次它结束时该代码使用一次移动命令,不会再次使用它。它还只使用它可以使用的第一个,而不会使用它上面的任何其他。循环不起作用,因为据我了解,Battlesnake 服务器每回合都会调用
handleMove
函数,如果 Battlesnake 服务器在 500 毫秒内没有得到响应,游戏就会为您移动。代码从
handleMove
的顶部开始,到
response.status
的东西结束。我知道代码会遍历这些函数,因为我用
console.log
跟踪了它。代码按预期遍历所有内容,因为我在所有函数和所有 if 命令内设置了
console.log
,并且它遍历 if 命令内的移动字符串,但忽略代码到达后到达的所有移动命令
response.status
。 这就是我感到困惑的地方。许多数据托管在 Battlesnake 服务器上,因此如果我的代码中未声明某些内容,它可能来自 Battlesnake 服务器。 我该如何解决这个问题?

const express = require('express')

const PORT = process.env.PORT || 3000

const app = express()
app.use(bodyParser.json())

app.get('/', handleIndex)
app.post('/start', handleStart)
app.post('/move', handleMove)
app.post('/end', handleEnd)

app.listen(PORT, () => console.log(`Battlesnake Server listening at http://127.0.0.1:${PORT}`))


function handleIndex(request, response) {
  var battlesnakeInfo = {
    apiversion: '1',
    author: '',
    color: '#1c607d',
    head: 'caffeine',
    tail: 'leaf'
  }
  response.status(200).json(battlesnakeInfo)
}

function handleStart(request, response) {
  var gameData = request.body

  console.log('START')
  response.status(200).send('ok')
}

function handleMove(request, response) {
  var gameData = request.body
  var head = gameData.you.head
  var boardWidth = gameData.board.width
  var boardHeight = gameData.board.height
  var food = gameData.board.food[0]

  // code i wrote

  function moveUpB() {

    if (head.x < 1) {

      move = "up"
      //refuses to execute at all??
    }


  }


  function moveRightB() {

    if (head.y > (boardHeight - 2)) {

      move = "right"
      //only used once
    }

  }

  function moveDownB() {

    if (head.x > (boardWidth - 2)) {

      move = "down"
      //only used once
    }

  }

  function moveLeftB() {

    if (head.y < 1) {

      move = "left"
      //only used once
    }

  }


  moveUpB()

  moveRightB()

  moveDownB()

  moveLeftB()
  //aafter here it should go back to moveUpB but it doesent?



  //rest of the code needed for the snake to move
  console.log('MOVE: ' + move)



  response.status(200).send({
    move: move




  })

}





function handleEnd(request, response) {
  var gameData = request.body

  console.log('END')
  response.status(200).send('ok')
}
javascript
1个回答
0
投票

您的代码编写方式,看起来好像您期望调用

move = "up"
将立即在游戏中为您的蛇应用该移动,并且通过在同一
handleMove
函数中调用具有不同方向的类似代码行在发送 HTTP 响应之前多次将按游戏中的顺序应用它们。然而,Battlesnake 的 API 并不是这样设计的。

Battlesnake 的工作方式是游戏在 Battlesnake 的服务器(“Battlesnake 引擎”)上运行。在每一回合,对于游戏中的每条蛇,Battlesnake 引擎都会向您的服务器发送一个 HTTP 请求,为您提供该回合位置的游戏板的完整状态,并允许您对该回合准确地做出一个动作响应,在限定时间内。如果战蛇引擎在该时间限制之前收到您的一个动作作为响应,那么当引擎应用这些动作来构建下一回合的状态时,该动作将包含在所有蛇的动作中。如果引擎认为游戏尚未结束,并且您的蛇尚未被消灭,那么在下一个回合,新游戏位置的状态将再次作为新请求发送到您的蛇的 HTTP 服务器,请求下一个并且只为下一个回合做出决定,这将重复。

代码中实际发生的情况是,当您调用

move = "up"
时,它所做的就是将名为
move
的变量的值设置为字符串
"up"
。然后,当调用
move = "right"
时,该变量的值将替换为字符串
"right"
。该变量是在您的服务器上的代码中设置的,Battlesnake 无法访问它。通过在发送响应之前将其设置为新的移动,在您的蛇的决定实际发送回战蛇之前,先前的移动决定将丢失/覆盖。当这段代码被调用时...

response.status(200).send({
  move: move
})

...正是在这一点上,你的蛇将移动发送回Battlesnake,同样仅针对所请求的单回合。

在一场 Battlesnake 游戏中,引擎发出一次移动请求时,您无法进行多次移动。当请求第 0 回合时,您必须为第 0 回合移动,然后在请求第 1 回合时为第 1 回合移动,依此类推。

那么如何解决呢?好吧,这完全取决于您玩游戏的算法/策略是如何设计的。在不了解具体情况的情况下,这些一般提示可以提供帮助:

  1. 您决定采取的行动可能取决于请求该回合时的游戏状态。例如,也许您的策略是始终选择随机方向移动,不包括“禁止移动”。 (禁止的动作是当你的蛇向后移动并与自身相撞时)。在这种情况下,你在每个回合的决定不依赖于任何先前的回合,它是“无状态的”。无论该 HTTP 请求请求哪一轮,您都可以根据请求中给出的棋盘状态决定要做什么。

  2. 在某些情况下,您决定采取的行动可能需要取决于之前的行动或游戏状态的先前属性。如果无法从该回合的请求中获取该信息,一种选择是让您的 Snake HTTP 服务器存储信息以供以后在 HTTP 请求之间使用。这是“有状态的”。这可能是在内存中使用全局范围,向数据库服务器发出外部请求等。您选择“记住”哪些信息以及在后续回合中如何使用它完全取决于您和您的策略。

© www.soinside.com 2019 - 2024. All rights reserved.