-
-
Save dzaima/eb36fd6ca55b4968277f33a210a8ab3f to your computer and use it in GitHub Desktop.
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
const DEBUG = false; | |
//raw directions | |
const UL = 0; const U = 1; const UR = 2; | |
const L = 3; const C = 4; const R = 5; | |
const DL = 6; const D = 7; const DR = 8; | |
//directions from the reference point | |
const ul = 16; const u = 17; const ur = 18; | |
const l = 19; const c = 20; const r = 21; | |
const dl = 22; const d = 23; const dr = 24; | |
const rp = 16; | |
const NOP = {cell:C}; | |
var toReturn = undefined; | |
var foods; | |
var ref; | |
const me = view[C].ant; | |
const type = me.type; | |
const food = me.food; | |
const isQueen = type == 5; | |
const allvs = allRots(view); | |
const ixs = [0,1,2,3,4,5,6,7,8]; | |
const cols = ixs.map(a=>view[a].color); | |
const allcs = allRots(cols); | |
// color 0 is ignore | |
// negative colors are always matched as correct but need to be repaired | |
const COLORS = [1, 6, 2, 3, 4, 5, 8, 7]; | |
const WH = COLORS[0]; // 1 | |
const C1 = COLORS[1]; // 6/should stay green (or whatever is trail-eraser most ignorant of :p) | |
const C2 = COLORS[2]; // 2/yellow | |
const C3 = COLORS[3]; // 3/purple | |
const C4 = COLORS[4]; // 4/cyan | |
const C5 = COLORS[5]; // 5/red | |
const C6 = COLORS[6]; // 8/black | |
const C7 = COLORS[7]; // 7/blue | |
const TRAIL = C1; | |
const PatternKeep = ["vp", "hp", "p"]; | |
// spam `for (let cv of PatternKeep) pattern[cv] = opattern[cv];` everywhere | |
const QUEEN = {ant:{friend:true,type:5}}; | |
const MU = 1; | |
const MD = 2; | |
const mydir = type==MU? u : d; | |
const notmydir = type==MU? d : u; | |
var refScorer; | |
{ | |
let scoreTotal = 0; | |
let totalBiggestScore = 0; | |
let ptt; | |
let correct = 0; | |
let incorrect = 0; | |
let corrstr = ""; | |
let corr = []; | |
refScorer = { | |
new: () => {scoreTotal = 0; correct = 0; corrstr = ""; corr = []; incorrect = 0}, | |
add: (real, wanted, where, pattern) => { | |
ptt = pattern; | |
let eqt = cellsEq(real, wanted); | |
if (eqt && eqt!==2) correct++; | |
if (!eqt) incorrect++; | |
corrstr+= eqt?"#":" "; | |
corr.push(eqt); | |
}, | |
finish: (currBest) => { | |
if (incorrect == 0) scoreTotal+= 1e4; | |
if (ptt.p == 0 && ptt.vp ==-2 && !/......###/.test(corrstr)) scoreTotal-= 1e300; | |
if (ptt.p == 0 && ptt.vp == 2 && !/###....../.test(corrstr)) scoreTotal-= 1e300; | |
if (correct > 5) correct+= 3; | |
if (ptt.p==1) { | |
var good = false; | |
if (mydir==u || food) good|= /...######/.test(corrstr); | |
if (mydir==d || food) good|= /######.../.test(corrstr); | |
if (good) correct*=1.5; | |
else scoreTotal-= 20; | |
} | |
if (corr[4]) [[0,1,3],[1,2,5],[3,6,7],[5,7,8]].forEach(c=> { | |
if (c.every(i=>corr[i])) scoreTotal+= 3;// correct++; | |
}); | |
var fc = (what) => (["u","c","d"][(what-17)/3]) | |
console.log(`P[${ptt.p}@${ptt.hp} ${ptt.vp}] score = ${correct+scoreTotal/10}/${totalBiggestScore} [${corrstr}]`, ptt); | |
if (totalBiggestScore < correct+scoreTotal/10) totalBiggestScore = correct+scoreTotal/10; | |
return correct+scoreTotal/10; | |
} | |
}; | |
} | |
const rail = [[-1,-1,C5,-1], | |
[C4,-1,-1,-1], | |
[C1,C1,C2,C3], | |
[C4,C5,C1,C6], | |
[C2,C7,C3,C1], | |
[C4,-1,-1,-1], | |
[-1,-1,C5,-1]]; | |
rail.vp = -2; | |
rail.hp = 0; | |
rail.p = 0; | |
const shaft = [[WH,-1,C5], | |
[C4,-1,WH]]; | |
const foodExt = [C7,C3,C6]; | |
shaft.p = 1; | |
shaft.vp = 0; | |
shaft.hp = 0; | |
const pattern = {or:[]}; | |
const shifts = translates(rail, R); | |
function addPart(part) { | |
pattern.or.push(setSize(part, 3, 3)); | |
} | |
function section(line, forMe) { | |
if (!forMe) return []; | |
shifts.forEach(c=>{ | |
let res = c.slice(line+2); | |
for (let cv of PatternKeep) res[cv] = c[cv]; | |
res.vp = line; | |
addPart(res); | |
}); | |
} | |
section(-2, !isQueen); | |
section(-1, !isQueen); | |
section( 0, true); | |
section( 1, !isQueen); | |
section( 2, !isQueen); | |
if (!isQueen) { | |
var shafts = translates(shaft,U).map(c => setSize(c, 3, 3)); | |
var backFromFood = [foodExt,[0,0,0],[0,0,0]]; | |
backFromFood.p = 2; | |
if (food) addPart(backFromFood); | |
// if (mydir==u || food) shafts.forEach(c=>addPart(mapP(c,(ln,i)=>i==0? ln.map(col=>-Math.abs(col)) : ln))); | |
// if (mydir==d || food) shafts.forEach(c=>addPart(mapP(c,(ln,i)=>i==2? ln.map(col=>-Math.abs(col)) : ln))); | |
shafts.forEach(c=>addPart(c)); | |
} | |
console.log("new ant"); | |
reference(pattern, undefined, refScorer); | |
const vp = ref.pt.vp; | |
const hp = ref.pt.hp; | |
const p = ref.pt.p; | |
//log("ant",type,"on rail at ", ref); | |
//log("vp", vp, "hp", hp); | |
//-----------------------------------------------------QUEEN------------------------------------------------------- | |
if (isQueen) { | |
if (food < 2 && ref.dist > 5) { | |
//initial food scramble | |
generateFoods(); | |
var sidevar = -1; | |
if ([0,2,6,8].some((i) => { | |
if (cols[i] === TRAIL) { | |
if (sidevar === -1) | |
sidevar = i; | |
else return true; | |
} | |
})) move(0); | |
else if (foods.includes(1)) { | |
move(foods.indexOf(1)); | |
} else if (cols[C] == TRAIL) { | |
if (sidevar == -1) { | |
move(0); | |
} else { | |
move(8-sidevar); | |
} | |
} else { | |
color(C, TRAIL); | |
} | |
//end food scramble | |
} else { | |
//on the rail | |
if ((food > 100 || ref.dist != 1 || !spawnMiners()) && | |
(p == 0 && repair())) { | |
if (hp != 3 || get(ur).ant || get(dr).ant) { | |
move(r); | |
} /*else if (food < 50) { | |
if (hp == 1 && !random4()) spawnMiners(); | |
}*/ | |
} | |
} | |
} else { | |
const movedir = food? notmydir : mydir; | |
const unmovedir = food? mydir : notmydir; | |
if (p == 0) { | |
if ((hp==0 && (vp == (mydir==u?-1:1)) && find(QUEEN) == notmydir) || repair()) { | |
var fQ = find(QUEEN); | |
var queenvp = fQ? (((fQ-1)%3) + hp + 16)%4: -1; | |
if (food && vp == 0) move([r,ur,dr]); | |
//else if (!food && vp == 2 && mydir==u) move([ur,r]); | |
//else if (!food && vp ==-1 && mydir==u && cellsEq(get(dr),{ant:"queen"})) move(r); | |
//else if (!food && vp == 1 && mydir==d && cellsEq(get(ur),{ant:"queen"})) move(r); | |
//else if (!food && vp ==-2 && mydir==d) move([dr,r]); | |
else if (queenvp == 0) move(r); // move into place for shafting | |
else if (hp==0 && (vp == (mydir==u?-1:1)) && fQ == notmydir) {if (ref.dist == 0) move(mydir)} // go out to shaft! | |
else if (queenvp !=-1) move(c); // else don't move around queen | |
else if ((food || fQ != u) && vp == 1) move(mydir==d? [r, ur] : [ur, u]); // move forwards | |
else if ((food || fQ != d) && vp ==-1) move(mydir==u? [r, dr] : [dr, d]); | |
else if ((hp==0 && Math.abs(vp) > 1) || vp == 0) move([movedir, unmovedir]); // move more away from rail into the shaft | |
else if (vp==0) move([r,mydir+1,notmydir+1]); // move forwards | |
else move(r); // TODO: I don't remember ¯\_(ツ)_/¯ | |
} | |
} else if (p == 1) { | |
if (get([l,r]).some(c=>c.food)) { | |
var foodL = get(l).food; | |
var shaftsn = shafts.map(c=>c.map((ln,i)=>[ln[0], foodL? foodExt[i] : foodExt[2-i], ln[2]])); | |
for (let cv of PatternKeep) shaftsn[cv] = shafts[cv]; | |
reference({or:shaftsn}, undefined, refScorer); | |
if (repair([c, mydir, notmydir])) { | |
move(foodL? l : r); | |
} | |
} | |
if ( | |
!( | |
(cellsEq(get(mydir), {ant:{type:type,friend:true,food:0}}) && get([mydir+1,mydir-1]).some(c=>c.food)) // someone's preparing to get food | |
|| | |
get([mydir+1,mydir-1]).some(c=>cellsEq(c,{ant:{type:type,friend:true,food:1}})) // someone got food! | |
|| | |
cellsEq(get(mydir), {ant:{type:type,friend:true,food:0}, color:[foodExt[0],foodExt[2]]}) //someone way above is getting food | |
) && repair()) { | |
move([movedir,unmovedir]); | |
} | |
} else if (p == 2) { | |
move(u); | |
} else { | |
ohno("no p for me.."); | |
} | |
} | |
function spawnMiners() { | |
if (view.filter(c=>c.ant).length>3) return false; // we have enough | |
var du = find({ant:{type:MU,friend:true}}); // do up / down | |
var dd = find({ant:{type:MD,friend:true}}); | |
if (du&&!dd) return spawn(d,MD) || spawn(u,MU); | |
if (dd&&!du) return spawn(u,MU) || spawn(d,MD); | |
if (random4()<2) return spawn(u,MU) || spawn(d,MD); | |
else return spawn(d,MD) || spawn(u,MU); | |
} | |
if (!toReturn) toReturn = NOP; | |
return toReturn; | |
//---------------------------------helper functions below--------------------------------- | |
function mapP(pt,fn) { | |
var res = pt.slice().map(c=>c.slice()).map(fn); | |
for (let cv of PatternKeep) res[cv] = pt[cv]; | |
return res; | |
} | |
function diagonalSearch (cl) { | |
var colors = view.map(c=>c.color === cl); | |
if (!colors.includes(true)) return color(UL, cl); | |
const nc = [WH,C1,C2,C3,C4,C5,C6,C7].filter(c => c !== cl); | |
if (exactReference([[cl,nc,nc], | |
[nc,cl,nc], | |
[nc,nc,nc]])) return move(dr); | |
if (exactReference([[cl,nc,nc], | |
[nc,nc,nc], | |
[nc,nc,nc]])) return color(C, cl); | |
move(random4()? U : UL); | |
} | |
function generateFoods (useRef) { | |
if (!foods || useRef) | |
foods = ixs.map(a=>view[a].food); | |
if (useRef) { | |
foods = allRots(foods)[ref.rot]; | |
} | |
} | |
/* | |
false - ?? | |
true - gonna draw the color | |
1 - already colored | |
*/ | |
function obstacle (where) { | |
var got = get(where); | |
return got.ant || (type !== QUEEN && got.food); | |
} | |
/* | |
false - coloring in this move | |
0 - incorrect params?!?!!??! | |
true - already colored | |
*/ | |
function color (where, color) { | |
if (where&rp) where = rawp(where); | |
if (get(where).color === color) return true; | |
return result({cell:where, color:color})? false : 0; | |
} | |
function move (where) { | |
if (Array.isArray(where)) { | |
return where.some(move /*is possible*/); | |
} | |
if (where&rp) where = rawp(where); | |
return result({cell:where}); | |
} | |
function spawn (where, what, force) { | |
if (Array.isArray(where)) { | |
return where.some(c => spawn(c, what, force)); | |
} | |
if (where&rp) where = rawp(where); | |
return result({cell:where, type:what}, force); | |
} | |
/* | |
either colors the cell white or leaves it correctly colored. | |
Meant for making it as an okay thing to stay like that when moving around | |
false - coloring... | |
true - ready for moving to related! | |
*/ | |
function clear (cell) { | |
if (correct(cell)) return true; | |
else return color(cell, WH); | |
} | |
function correct (cell) { | |
cell = cell&~rp; | |
return cellsEq(ref.view[cell], ref.pt[cell]); | |
} | |
function fix (cell) { | |
cell&= ~rp; | |
let ccolor = defColor(ref.pt[cell]); | |
if (ccolor != ref.view[cell].color) { | |
color(cell|rp, ccolor); | |
return false; | |
} else return true; | |
} | |
function repair (firstdirs) {// firstdirs is lowercase | |
//if (ref.dist == 0) return true; | |
var possibilities = []; | |
var repaired = ref.pt.every((shouldbe, index) => {//return if every cell is correct | |
if (!cellsEq(ref.view[index], shouldbe, true)) { | |
let ccolor = defColor(shouldbe); | |
if (ccolor != ref.view[index]) { | |
if (!firstdirs) { | |
color(index|rp, Math.abs(ccolor)); | |
return false; | |
} else possibilities.push({i:index|rp, c:ccolor}); | |
} | |
} | |
return true; | |
}); | |
if (repaired && possibilities.length > 0) { | |
repaired = false; | |
var first = firstdirs.find(c=>possibilities.find(pc=>pc.i==c)); | |
if (first) color(first, possibilities.find(pc=>pc.i==first).c); | |
else color(possibilities[0].i, possibilities[0].c); | |
} | |
return repaired; | |
} | |
function defColor (cell) { | |
if (typeof cell === "number") return cell; | |
if (Array.isArray(cell)) return cell[0]; | |
ohno("defColor recieved bad param type ", cell); | |
} | |
function get (pos) { | |
if (Array.isArray(pos)) return pos.map(get); | |
if (pos&rp) return ref.view[pos^rp]; | |
else return view[pos]; | |
} | |
function gc (pos) { | |
return get(pos).color; | |
} | |
function exactReference (...args) { | |
var pt = match(...args); | |
if (pt.dist === 0) { | |
return ref = pt; | |
} | |
return false; | |
} | |
function reference (...args) { | |
return ref = match(...args); | |
} | |
/* | |
this function makes a pseudo-reference out of a value of a direction | |
For example, if you want a type-2 worker orthogonally to you to be able to be referenced as `r` (and of course the other directions are relative), do | |
define(r, find({ant:{type:2,friend:true}})) | |
*/ | |
function define (whichDir, whatCellItIs) { | |
var rot = [0,1,2,3].find(rot => rotate(whatCellItIs, -rot) === (whichDir&~rp)); | |
ref = {rot:rot, view:allvs[rot]}; | |
} | |
function match (pattern, givendir, scoreResults) { | |
if (Array.isArray(pattern.or)) { | |
var bestPattern = {dist:999, correct: -1, score: -1e308}; | |
pattern.or.forEach((cOr) => { | |
let cres = match(cOr, givendir, scoreResults); | |
if (scoreResults? cres.score > bestPattern.score : compareScores(cres.dist, cres.correct, bestPattern.dist, bestPattern.correct) > 0) { | |
bestPattern = cres; | |
} | |
}); | |
//console.log(bestPattern); | |
return bestPattern; | |
} | |
var bestRotation = 0; | |
var bestDist = 999; | |
var bestCorrect = -1; | |
var bestScore = -1e308; | |
if (Array.isArray(pattern)) { | |
let opattern = pattern; | |
pattern = [...pattern[0],...pattern[1],...pattern[2]]; | |
for (let cv of PatternKeep) pattern[cv] = opattern[cv]; | |
((givendir != undefined)? [allvs[givendir]] : allvs).forEach((cVRot, cRot) => { | |
if (givendir != undefined) cRot = givendir; | |
let dist = 0; | |
let correct = 0; | |
let fatalFail = false; | |
if (scoreResults) scoreResults.new(); | |
// log("match going trough", cVRot.map(c=>c.color), "at", pattern, pattern.hp); | |
cVRot.some((cVCell, cCell) => {//log(cCell, pattern) | |
let eqt = cellsEq(cVCell, pattern[cCell]); | |
if (scoreResults) scoreResults.add(cVCell, pattern[cCell], cCell, pattern); | |
else { | |
if (eqt === 3) correct+=2; | |
if (eqt === 0) fatalFail = true; | |
} | |
if (eqt === true) correct++; | |
if (eqt === false) dist++; | |
return fatalFail; | |
}); | |
//log("distance",dist, "correct",correct); | |
let score; | |
if (scoreResults? (score = scoreResults.finish(bestScore)) > bestScore : !fatalFail && compareScores(dist, correct, bestDist, bestCorrect)>0) { | |
bestDist = dist; | |
bestCorrect = correct; | |
bestRotation = cRot; | |
if (scoreResults) bestScore = score; | |
} | |
}); | |
return {dist:bestDist, correct:bestCorrect, rot:bestRotation, pt:pattern, view:allvs[bestRotation], opt:opattern, score:bestScore}; | |
} | |
ohno("match failed to do anything", pattern); | |
} | |
function compareScores (ad, ac, bd, bc) { | |
//scoring by percentage correct | |
let a = ac / (ad+ac+1); | |
let b = bc / (bd+bc+1); | |
//scoring by correct overhead | |
///let a = ac - ad | |
///let b = bc - bd | |
return a==b? 0 : ((a>b)? 1 : -1); | |
} | |
function bitify (num) { | |
num&=~rp; | |
if (num === U) return bU; | |
if (num === D) return bD; | |
if (num === L) return bL; | |
if (num === R) return bR; | |
if (num === UL) return bUL; | |
if (num === DL) return bDL; | |
if (num === UR) return bUR; | |
if (num === DR) return bDR; | |
} | |
function rawp (dir) { | |
dir &= ~rp; // remove rp 'flag' | |
return rotate(dir, ref.rot); | |
} | |
function refp (dir) { | |
return rp | rotate(dir, -ref.rot); | |
} | |
function rotate (torot, am) { | |
am = am%4; | |
if (am < 0) am+= 4; | |
for (let i = 0; i < am; i++) torot = [2,5,8, 1,4,7, 0,3,6][torot]; | |
return torot; | |
} | |
function find (obj) { | |
var res = ref.view.findIndex(c => cellsEq(c, obj)); | |
if (res === -1) return false; | |
return res | rp; | |
} | |
/* | |
0 - ant isn't how it should be | |
false - colors don't match | |
true - match | |
2 - match, but very easy to match, so shouldn't count | |
3 - matched ants | |
1st param - full object, aka anything that comes from view[x] | |
2nd param - the partical object you want it to equal (e.g. {ant:{friend:true}}; 6 ) | |
*/ | |
function cellsEq (full, required, negativeIncorrect) { // log(full, new Error().stack); | |
if (typeof required === "number") { | |
if (required === 0) return 2; | |
if (!negativeIncorrect && required < 0) return 2; | |
if (Math.abs(required) === full.color) return true; | |
return false; | |
} else if (Array.isArray(required)) { | |
let best = 0; | |
required.some((c) => { | |
let res = cellsEq(full, c); | |
if (res === false && best === 0) best = false; | |
if (res === true && best !== 3) best = true; | |
if (res === 3) best = 3; | |
}); | |
//log("cellsEq array",required,full,best); | |
return best; | |
} else if (typeof required === "object") { | |
if (required.ant==false && full.ant) return 0; | |
if (required.ant) { | |
if (required.ant==="notQueen") { | |
if (full.ant) { | |
if (full.ant.type==5 && full.ant.friend) return 0; | |
} | |
} else if (required.ant==="worker") { | |
if (full.ant) { | |
if (full.ant.type==5 && full.ant.friend) return 0; | |
} else return 0; | |
} else if (required.ant==="queen") { | |
if (full.ant) { | |
if (full.ant.type!=5 && full.ant.friend) return 0; | |
} else return 0; | |
} else { | |
if (!full.ant) return 0; | |
else { | |
// ಠ_ಠ | |
if (required.ant.type && required.ant.type != full.ant.type) return 0; | |
if (required.ant.friend && required.ant.friend != full.ant.friend) return 0; | |
} | |
} | |
} | |
if (required.color) { | |
if (Array.isArray(required.color)) { | |
if (!required.color.some(c=>c===full.color)) return false; | |
} else if (required.color !== full.color) return false; | |
} | |
if (required.food !== undefined && full.food != required.food) return false; // intentional `!=` | |
if (required.ant) return 3; | |
return true; | |
} | |
ohno("cellsEq failed to do anything", arguments); | |
} | |
function limitSize (pattern, xs, ys) { | |
var out = pattern.slice(0, ys).map(c => c.slice(0,xs)); | |
for (let cv of PatternKeep) out[cv] = pattern[cv]; | |
return out; | |
} | |
function setSize (pattern, xs, ys) { | |
//var out = pattern.slice(0, ys).map(c => c.slice(0,xs)); | |
//while (out[0].length < xs) out.map(c => c.push()); | |
var out = []; | |
for (let y = 0; y < ys; y++) { | |
var ca = []; | |
for (let x = 0; x < xs; x++) { | |
ca.push(pattern[y % pattern.length][x % pattern[0].length]); | |
} | |
out.push(ca); | |
} | |
for (let cv of PatternKeep) out[cv] = pattern[cv]; | |
return out; | |
} | |
function translates (pattern, direction) { | |
var out = [pattern.slice()]; | |
for (let cv of PatternKeep) out[0][cv] = pattern[cv]; | |
for (let i = 0; i < lengthIn(pattern, direction)-1; i++) { | |
pattern = rotatePt(pattern, direction); | |
out.push(pattern); | |
} | |
return out; | |
} | |
function rotatePt (pattern, direction) { | |
if (direction == DR) { | |
return rotatePt(rotatePt(pattern, D), R); | |
} | |
if (direction == R) { | |
let np = pattern.map((c, ln) => c.slice(1).concat([c[0]])); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.hp++; | |
return np; | |
} | |
if (direction == D) { | |
let np = pattern.slice(1).concat([pattern[0]]); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.v++; | |
return np; | |
} | |
if (direction == U) { | |
let np = pattern.slice(); | |
np.splice(0,0,...np.splice(np.length-1)); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.vp--; | |
return np; | |
} | |
ohno("rotatePt failed to do anything", arguments); | |
} | |
function translatePt (pattern, direction) { | |
direction&=~rp; | |
if (direction == R) { | |
let np = pattern.map((ln) => ln.slice(1).concat(-1)); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.hp++; | |
return np; | |
} | |
if (direction == L) { | |
let np = pattern.map((ln) => [-1].concat(ln.slice(0,-1))); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.hp--; | |
return np; | |
} | |
if (direction == U) { | |
let np = [new Array(pattern[0].length).fill(-1)].concat(pattern.slice(0,-1)); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.vp--; | |
return np; | |
} | |
if (direction == D) { | |
let np = pattern.slice(1).concat([new Array(pattern[0].length).fill(-1)]); | |
for (let cv of PatternKeep) np[cv] = pattern[cv]; | |
np.vp++; | |
return np; | |
} | |
ohno("translatePt failed to do anything", arguments); | |
} | |
function lengthIn (pattern, direction) { | |
if (direction == U || direction == D) return pattern.length; | |
if (direction == L || direction == R) return pattern[0].length; | |
ohno("lengthIn failed to do anything", arguments); | |
} | |
function ohno (msg) { | |
log(new Error()); | |
log("FAILURE"); | |
log(...arguments); | |
if (DEBUG) throw msg; | |
else toReturn = NOP; | |
} | |
function log() { | |
if (DEBUG) console.log(...arguments); | |
} | |
//---------------------------------functions from Rail Miners--------------------------------- | |
function result (action, force) { | |
if (force) return resultForce(action); | |
if (toReturn !== undefined) return 0; | |
var color = action.color; | |
var type = action.type; | |
var cell = action.cell; | |
if (!(cell >= 0 && cell <= 8)) return false; | |
if (!color && ((view[cell].ant && cell != 4) || (isQueen? (view[cell].food && type) : (food && view[cell].food)))) return false; | |
if (!isQueen && type) return false; | |
if (!isQueen && !color && food && view[cell].food) return false; | |
if (isQueen && !food && type) return false; | |
if (type && cell==C) return false; | |
if (color && type) return false; | |
toReturn = action; | |
return true; | |
} | |
function resultForce(action) { | |
var temptoReturn = toReturn; | |
toReturn = undefined; | |
if (result(action)) { | |
return true; | |
} else { | |
toReturn = temptoReturn; | |
return false; | |
} | |
} | |
function random4 () { | |
var scores = allcs.map((cs) => { | |
let cscore = 0; | |
cs.forEach((c) => { | |
cscore*= 8; | |
cscore+= c-1; | |
}) | |
return cscore; | |
}) | |
var bestscore = -1, bestindex = 1; | |
scores.forEach((score, index) => { | |
if (score > bestscore) { | |
bestscore = score; | |
bestindex = index; | |
} | |
}) | |
return bestindex; | |
} | |
function allRots (arr) { | |
return [arr, | |
[arr[2], arr[5], arr[8], | |
arr[1], arr[4], arr[7], | |
arr[0], arr[3], arr[6]], | |
[arr[8], arr[7], arr[6], | |
arr[5], arr[4], arr[3], | |
arr[2], arr[1], arr[0]], | |
[arr[6], arr[3], arr[0], | |
arr[7], arr[4], arr[1], | |
arr[8], arr[5], arr[2]]]; | |
} | |
function rotate1CW (c) { | |
return [1, 2, 5, 0, undefined, 8, 3, 6, 7][c]; | |
} | |
function rotate1CCW (c) { | |
return [3, 0, 1, 6, undefined, 2, 7, 8, 5][c]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment