Skip to content

Commit

Permalink
build quickjs sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
Entkenntnis committed Oct 31, 2024
1 parent d3310d4 commit 42c91f9
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 3 deletions.
23 changes: 21 additions & 2 deletions public/worms/wormer.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ function createDemoBot() {
}

function AI(dx, dy, board, x, y, dir, oppX, oppY) {
console.time('demo bot')
// console.time('demo bot')

const availableMoves = [0, 1, 2, 3].filter(
(dir) => board[x + offsets[dir][0]][y + offsets[dir][1]] == 0
Expand Down Expand Up @@ -321,9 +321,28 @@ function createDemoBot() {
})
evals.sort((a, b) => b[0] - a[0])
console.log('eval:', evals[0][0])
console.timeEnd('demo bot')
// console.timeEnd('demo bot')
return evals[0][1]
}

return AI
}

function createSandboxedBot(QuickJS, src) {
const runtime = QuickJS.newRuntime()
const ctx = runtime.newContext()
ctx.evalCode(src)

function AI(dx, dy, board, x, y, dir, oppX, oppY) {
console.time('sandbox')

const thinkCallScript = `
think(${dx}, ${dy}, ${JSON.stringify(board)}, ${x}, ${y}, ${dir}, ${oppX}, ${oppY});
`
const id = ctx.unwrapResult(ctx.evalCode(thinkCallScript))

console.timeEnd('sandbox')
return ctx.getNumber(id)
}
return AI
}
136 changes: 135 additions & 1 deletion src/content/worms.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,131 @@
import { renderPage } from '../helper/render-page.js'

const bot = `
var offsets = [
[0, -1], // Oben
[1, 0], // Rechts
[0, 1], // Unten
[-1, 0], // Links
]
function think(dx, dy, board, x, y, dir, oppX, oppY) {
var nx = x + offsets[dir][0]
var ny = y + offsets[dir][1]
if (board[nx][ny] != 0) {
return (dir + 1) % 4
}
return dir
}
`

const bot2 = `
var offsets = [
[0, -1], // Oben
[1, 0], // Rechts
[0, 1], // Unten
[-1, 0], // Links
]
var oppDistances = []
var myDistances = []
for (var x = 0; x < 74; x++) {
var row1 = []
var row2 = []
for (var y = 0; y < 42; y++) {
row1.push(Infinity)
row2.push(Infinity)
}
oppDistances.push(row1)
myDistances.push(row2)
}
function bfs(board, startX, startY, distances) {
var queue = []
var head = 0
distances[startX][startY] = 0
queue.push({ x: startX, y: startY })
while (head < queue.length) {
var el = queue[head++]
var x = el.x
var y = el.y
var dist = distances[x][y]
for (var i = 0; i < offsets.length; i++) {
var nx = x + offsets[i][0]
var ny = y + offsets[i][1]
if (board[nx][ny] === 0 && distances[nx][ny] === Infinity) {
distances[nx][ny] = dist + 1
queue.push({ x: nx, y: ny })
}
}
}
}
function think(dx, dy, board, x, y, dir, oppX, oppY) {
// console.time('demo bot')
var availableMoves = []
for (var i = 0; i < 4; i++) {
if (board[x + offsets[i][0]][y + offsets[i][1]] == 0) {
availableMoves.push(i)
}
}
if (availableMoves.length == 0) return 0 // dead
if (availableMoves.length == 1) return availableMoves[0] // force
// Now we have 2 or 3 choices
// Start with calculating opp distances
bfs(board, oppX, oppY, oppDistances)
var evals = []
for (var i = 0; i < availableMoves.length; i++) {
var moveDir = availableMoves[i]
var nx = x + offsets[moveDir][0]
var ny = y + offsets[moveDir][1]
// Distanzen vom neuen Standpunkt nach dem Zug
bfs(board, nx, ny, myDistances)
var score = 0
for (var ix = 0; ix < dx; ix++) {
for (var iy = 0; iy < dy; iy++) {
var myDist = myDistances[ix][iy]
var oppDist = oppDistances[ix][iy]
if (myDist !== Infinity && oppDist !== Infinity) {
var diff = oppDist - myDist
score += diff > 0 ? 1 : diff < 0 ? -1 : 0
} else if (myDist !== Infinity) {
score++
} else if (oppDist !== Infinity) {
score--
}
// reset
myDistances[ix][iy] = Infinity
if (i == availableMoves.length - 1) {
oppDistances[ix][iy] = Infinity
}
}
}
evals.push([score, moveDir])
}
evals.sort(function(a, b) { return b[0] - a[0]})
return evals[0][1]
}
`

/**
* @param {import("../data/types.js").App} App
*/
Expand Down Expand Up @@ -51,14 +177,20 @@ export function setupWorms(App) {
heading: 'Worms Testbereich',
backButton: false,
content: `
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.global.js"
type="text/javascript"
></script>
<script src="/worms/wormer.js"></script>
<p>Steuerung rot: Wasd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Steuerung grün: Pfeiltasten&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start/Neustart: ENTER</p>
<div id="board"></div>
<script>
const red = createKeyboardPlayer('w', 'd', 's', 'a')
QJS.getQuickJS().then((QuickJS) => {
// createKeyboardPlayer('w', 'd', 's', 'a') //
const red = createSandboxedBot(QuickJS, \`${bot2}\`)
const green = createDemoBot()
Expand All @@ -71,6 +203,8 @@ export function setupWorms(App) {
wormer.run()
}
})
})
</script>
`,
})
Expand Down

0 comments on commit 42c91f9

Please sign in to comment.