Last active
February 24, 2022 08:11
-
-
Save gaplo917/b5beaa8d830f6093cc31d13bc8a49b18 to your computer and use it in GitHub Desktop.
GCP X GT Water fight
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/GoogleCloudPlatform/cloudbowl-microservice-game.git | |
const express = require('express'); | |
const app = express(); | |
const bodyParser = require('body-parser'); | |
app.use(bodyParser.json()); | |
app.get('/', function (req, res) { | |
res.send('Let the battle begin!'); | |
}); | |
function detectEnemy({enemyInfo, myInfo}) { | |
const isTopHasEnemy = enemyInfo.x === myInfo.x && myInfo.y - enemyInfo.y >= 1 && myInfo.y - enemyInfo.y <= 3 | |
const isBottomHasEnemy = enemyInfo.x === myInfo.x && enemyInfo.y - myInfo.y >= 1 && enemyInfo.y - myInfo.y <= 3 | |
const isWestHasEnemy = myInfo.x - enemyInfo.x >= 1 && myInfo.x - enemyInfo.x <= 3 && myInfo.y === enemyInfo.y | |
const isEastHasEnemy = enemyInfo.x - myInfo.x >= 1 && enemyInfo.x - myInfo.x <= 3 && myInfo.y === enemyInfo.y | |
return {isTopHasEnemy, isBottomHasEnemy, isWestHasEnemy, isEastHasEnemy} | |
} | |
function bestEscapeMove({dims, myInfo, enemyPosList}) { | |
switch (myInfo.direction) { | |
case "S": | |
if(myInfo.y < dims[1] && !enemyPosList[`${myInfo.x},${myInfo.y + 1}`]) { | |
return 'F' | |
} | |
break | |
case "N": | |
if(myInfo.y > 0 && !enemyPosList[`${myInfo.x},${myInfo.y - 1}`]) { | |
return 'F' | |
} | |
break | |
case "W": | |
if(myInfo.x > 0 && !enemyPosList[`${myInfo.x - 1},${myInfo.y}`]) { | |
return 'F' | |
} | |
break | |
case "E": | |
if(myInfo.x < dims[0] && !enemyPosList[`${myInfo.x + 1},${myInfo.y}`]) { | |
return 'F' | |
} | |
break | |
} | |
return 'R' | |
} | |
app.post('/', function (req, res) { | |
console.log(req.body); | |
const selfUrl = req.body._links.self.href | |
const {dims, state} = req.body.arena | |
const myInfo = state[selfUrl] | |
// sort by highest score | |
const enemyInfosSortWithScore = Object.entries(state) | |
.filter(([k,v]) => k !== selfUrl) | |
.sort(([k1, v1], [k2, v2]) => v2.score - v1.score) | |
const enemyPosList = Object.entries(state).reduce((acc, [k,v]) => { | |
return { | |
[`${v.x},${v.y}`]: true, | |
...acc | |
} | |
}, {}) | |
const enemyUrls = enemyInfosSortWithScore.map(([k,v]) => k) | |
// being hit, escape first | |
if (myInfo.wasHit) { | |
res.send(bestEscapeMove({dims, myInfo, enemyPosList})); | |
return | |
} else { | |
// not being hit try to hit the highest one | |
for (const enemyUrlsKey of enemyUrls) { | |
const enemyInfo = state[enemyUrlsKey] | |
const {isTopHasEnemy, isBottomHasEnemy, isWestHasEnemy, isEastHasEnemy} = detectEnemy({enemyInfo, myInfo}) | |
console.log({isTopHasEnemy, isBottomHasEnemy, isWestHasEnemy, isEastHasEnemy, myInfo, enemyInfo}) | |
// no matter what, hit enemy first | |
switch (myInfo.direction) { | |
case "N": | |
if (isTopHasEnemy) { | |
res.send("T"); | |
return | |
} | |
break | |
case "S": | |
if (isBottomHasEnemy) { | |
res.send("T"); | |
return | |
} | |
break | |
case "W": | |
if (isWestHasEnemy) { | |
res.send("T"); | |
return | |
} | |
break | |
case "E": | |
if (isEastHasEnemy) { | |
res.send("T"); | |
return | |
} | |
break | |
} | |
} | |
// rotate if enemy is nearby, only consider best move | |
for (const enemyUrlsKey of enemyUrls) { | |
const enemyInfo = state[enemyUrlsKey] | |
const {isTopHasEnemy, isBottomHasEnemy, isWestHasEnemy, isEastHasEnemy} = detectEnemy({enemyInfo, myInfo}) | |
if (isTopHasEnemy) { | |
switch (myInfo.direction) { | |
case "E": | |
res.send("L"); | |
return | |
case "W": | |
res.send("R"); | |
return | |
} | |
} | |
if (isBottomHasEnemy) { | |
switch (myInfo.direction) { | |
case "W": | |
res.send("L"); | |
return | |
case "E": | |
res.send("R"); | |
return | |
} | |
} | |
if (isWestHasEnemy) { | |
switch (myInfo.direction) { | |
case "N": | |
res.send("L"); | |
return | |
case "S": | |
res.send("R"); | |
return | |
} | |
} | |
if (isEastHasEnemy) { | |
switch (myInfo.direction) { | |
case "S": | |
res.send("L"); | |
return | |
case "N": | |
res.send("R"); | |
return | |
} | |
} | |
} | |
// otherwise, just walk around to the highest target | |
const target = enemyInfosSortWithScore[0] | |
if(target) { | |
const targetEnemy = target[1] | |
if(targetEnemy) { | |
const diffX = targetEnemy.x - myInfo.x | |
const diffY = targetEnemy.y - myInfo.y | |
if(diffY > 0) { | |
switch (myInfo.direction) { | |
case "S": | |
res.send('F'); | |
return | |
} | |
} | |
if(diffY < 0) { | |
switch (myInfo.direction) { | |
case "N": | |
res.send('F'); | |
return | |
} | |
} | |
if(diffX > 0) { | |
switch (myInfo.direction) { | |
case "E": | |
res.send('F'); | |
return | |
} | |
} | |
if(diffX < 0) { | |
switch (myInfo.direction) { | |
case "W": | |
res.send('F'); | |
return | |
} | |
} | |
} | |
} | |
res.send('R'); | |
return | |
} | |
}); | |
app.listen(process.env.PORT || 8080); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment