Skip to content

Instantly share code, notes, and snippets.

@gaplo917
Last active February 24, 2022 08:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaplo917/b5beaa8d830f6093cc31d13bc8a49b18 to your computer and use it in GitHub Desktop.
Save gaplo917/b5beaa8d830f6093cc31d13bc8a49b18 to your computer and use it in GitHub Desktop.
GCP X GT Water fight
// 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