Created
November 12, 2021 14:59
-
-
Save kenwebb/6e1ac29031940ddf26e977bac593f137 to your computer and use it in GitHub Desktop.
Beach Comber
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
Beach Comber | |
For use with Island Game. | |
An Avatar that stays within the current stretch of Coast. |
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
/** | |
Ken Webb | |
Learning Express. | |
October 25, 2021 | |
see Xholon workbook: Express - web framework for node | |
3ede7991936fe5281657c494f8a92caf | |
(base) ken@ken-HP-ZBook-15-G2:~/nodespace/express01$ node app.js | |
Example app listening at http://localhost:3000 | |
http://localhost:3000/add/1/99 | |
result: 1 + 99 = 100 | |
see also: ~/gwtspace/Xholon/Xholon/module/moduleAvatar2Server.xml | |
Performance | |
----------- | |
see: https://expressjs.com/en/advanced/best-practice-performance.html | |
To set NODE_ENV to “production”, enter this command in the Linux/Ubuntu terminal window, before running node: | |
export NODE_ENV=production | |
This is temporary, and is only active for that terminal window. | |
*/ | |
const express = require('express') | |
const cors = require('cors') // KSW added this | |
const {ftest, random, random4, random8, nesw, bchcmr} = require('./functions') // Procedural Memory | |
const {stest, sinsert, squery} = require('./storage') // Declarative Memory | |
const app = express() | |
const port = 3000 | |
// enable CORS for all origins | |
app.use(cors()); | |
app.use(express.json()) // for parsing application/json | |
app.get('/', (req, res) => { | |
res.send('Hello World!') | |
}) | |
// KSW test | |
app.get('/test1', (req, res) => { | |
res.send('Testing 1.') | |
}) | |
// KSW test | |
app.get('/test2', (req, res) => { | |
res.send('Testing 2.') | |
}) | |
app.get('/test2/:one', (req, res) => { | |
res.send('Testing 2: ' + req.params.one) | |
}) | |
app.get('/add/:one/:two', (req, res) => { | |
res.send(`${req.params.one} + ${req.params.two} = ` + (0 + Number(req.params.one) + Number(req.params.two))) | |
}) | |
/** | |
* Return a random direction for a Xholon agent to move to (0 1 2 3). Grid: (N S E W) or Tree: (parent first next prev). | |
*/ | |
app.get('/moveto', (req, res) => { | |
res.send("" + random4()) | |
}) | |
/** | |
* Working Memory. | |
* @param {Request} req A Perception or similar Request. | |
* @param {Response} res A Motor command or similar Response. | |
*/ | |
app.post('/nesw', (req, res) => { | |
sinsert(req.body) | |
res.send("" + nesw(req.body)) | |
}) | |
app.get("/squery", (req, res) => { | |
res.send(squery()) | |
}) | |
/** | |
* Beach Comber | |
* @param {Request} req A Perception or similar Request. | |
* @param {Response} res A Motor command or similar Response. | |
*/ | |
app.post('/bchcmr', (req, res) => { | |
res.send("" + bchcmr(req.body)) | |
}) | |
app.listen(port, () => { | |
console.log(`Example app listening at http://localhost:${port}`) | |
console.log(ftest()) | |
console.log(stest()) | |
console.log("NODE_ENV: " + process.env.NODE_ENV) | |
}) |
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
/** | |
Ken Webb | |
October 31, 2021 | |
functions.js | |
Functions for use with app.js | |
Decision Engine - Procedural Long-term Memory | |
*/ | |
const ftest = () => "Hello out there from FTest!" | |
/** | |
* Various functions that generate random integers within specified ranges. | |
*/ | |
const random = max => () => Math.floor(Math.random() * max) | |
const random4 = random(4) | |
const random8 = random(8) | |
/** | |
* Process a NESW JavaScript Object. | |
* @param {Object} obj ex: { me: 'LandCell', n: 'CoastCell', e: 'LandCell', s: 'LandCell', w: 'LandCell' } | |
* @return {Number} A direction to move to a random neighboring non-OceanCell gridCell. | |
*/ | |
const nesw = obj => { | |
const neswArr = Object.entries(obj).reduce((prev, curr) => { | |
if ((curr[0] !== "me") && (curr[1] !== "OceanCell")) { | |
prev.push(curr[0]) | |
} | |
return prev | |
}, []) | |
const moveto = neswArr[random(neswArr.length)()] | |
const movetoNum = moveto === "n" ? 0 | |
: moveto === "e" ? 1 | |
: moveto === "s" ? 2 | |
: 3 | |
//console.log(obj, neswArr, moveto, movetoNum) | |
return movetoNum | |
} | |
/** | |
* Process a Beach Comber JavaScript Object. | |
* @param {Object} obj ex: { me: 'CoastCell', n: 'CoastCell', e: 'LandCell', s: 'CoastCell', w: 'OceanCell' } | |
* @return {Number} A direction to move to a random neighboring CoastCell gridCell. | |
*/ | |
const bchcmr = obj => { | |
const arr = Object.entries(obj).reduce((prev, curr) => { | |
if ((curr[0] !== "me") && (curr[1] === "CoastCell")) { | |
prev.push(curr[0]) | |
} | |
return prev | |
}, []) | |
const moveto = arr[random(arr.length)()] | |
const movetoNum = moveto === "n" ? 0 | |
: moveto === "e" ? 1 | |
: moveto === "s" ? 2 | |
: 3 | |
//console.log(obj, arr, moveto, movetoNum) | |
return movetoNum | |
} | |
module.exports = {ftest, random, random4, random8, nesw, bchcmr}; |
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
<?xml version="1.0" encoding="UTF-8"?> | |
<!-- | |
Xholon Avatar that moves within the Island Game world, always staying within the current stretch of coast. | |
Ken Webb | |
November 12, 2021 | |
~/gwtspace/Xholon/Xholon/module/ava2srv/mBeachComber.xml | |
based on mAva2SrvPostNesw.xml | |
See Xholon workbook: Express - web framework for node | |
Copy and paste, or drag, this entire text into a running Xholon app. | |
--> | |
<XholonModule> | |
<XholonMap> | |
<Attribute_String roleName="ih"><![CDATA[ | |
<_-.XholonClass> | |
<BeachComber superClass="Avatar"/> | |
<Talk2Server superClass="Script"/> | |
</_-.XholonClass> | |
]]></Attribute_String> | |
<Attribute_String roleName="cd"><![CDATA[ | |
<xholonClassDetails> | |
<BeachComber><Color>purple</Color></BeachComber> | |
<Talk2Server><DefaultContent> | |
const REQ_REMOTE = true; | |
var me, ava, request, beh = { | |
postConfigure: function() { | |
me = this.cnode; | |
ava = me.parent().parent(); | |
if (!ava["subtrees"]) { | |
ava.action("param subtrees true"); | |
} | |
ava.action("param transcript false"); | |
const url = ["http://127.0.0.1:3000/bchcmr", "http://192.168.0.39:3000/bchcmr"]; | |
request = new Request(url[0]); | |
me.msg(101, "Sending me ..."); | |
}, | |
processReceivedMessage(msg) { | |
this.doRequest(this.prepData(ava.parent())); | |
}, | |
prepData: function(pava) { | |
return { | |
me: pava.xhc().name(), | |
n: pava.port(0).xhc().name(), | |
e: pava.port(1).xhc().name(), | |
s: pava.port(2).xhc().name(), | |
w: pava.port(3).xhc().name() | |
} | |
}, | |
doRequest: function(jso) { | |
if (REQ_REMOTE) { | |
this.doRequestRemote(jso); | |
} | |
else { | |
this.doRequestLocal(jso); | |
} | |
}, | |
doRequestRemote: function(jso) { | |
fetch(request, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify(jso) | |
}) | |
.then((res) => res.text()) | |
.then((responseText) => { | |
this.moveto(responseText); | |
me.msg(101, "Sending me againR ..."); | |
return null; | |
}); | |
}, | |
doRequestLocal: function(obj) { | |
// this is the same code used in the Server functions.js | |
const arr = Object.entries(obj).reduce((prev, curr) => { | |
if ((curr[0] !== "me") && (curr[1] === "CoastCell")) { | |
prev.push(curr[0]) | |
} | |
return prev | |
}, []) | |
const random = max => () => Math.floor(Math.random() * max) | |
const moveto = arr[random(arr.length)()] | |
const movetoNum = moveto === "n" ? 0 | |
: moveto === "e" ? 1 | |
: moveto === "s" ? 2 | |
: 3 | |
this.moveto(movetoNum); | |
me.msg(101, "Sending me againL ..."); | |
}, | |
moveto: function(direction) { | |
ava.action("go " + direction); // go 0|1|2|3 OK | |
} | |
} | |
//# sourceURL=Talk2Serverbehavior.js | |
</DefaultContent></Talk2Server> | |
</xholonClassDetails> | |
]]></Attribute_String> | |
<Attribute_String roleName="csh"><![CDATA[ | |
<_-.csh> | |
<!-- I can create additional instances of BeachComber, by dragging in just the following subtree --> | |
<BeachComber> | |
<BehaviorsST> | |
<Talk2Server/> | |
</BehaviorsST> | |
</BeachComber> | |
</_-.csh> | |
]]></Attribute_String> | |
</XholonMap> | |
</XholonModule> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment