Last active
February 26, 2018 19:06
-
-
Save dzaima/193b9a539269a3af63a1df7430ebba94 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; | |
//binary directions | |
const bUL = 3; const bU = 1; const bUR = 5; | |
const bL = 2; const bC = 0; const bR = 4; | |
const bDL = 10; const bD = 8; const bDR = 12; | |
const rp = 16; | |
const NOP = {cell:C}; | |
var toReturn = undefined; | |
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 -1 is ignore | |
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", "part", "side"]; | |
// spam `for (let cv of PatternKeep) pattern[cv] = opattern[cv];` everywhere | |
//entry code starts here | |
const moveSide = r; | |
const backtrackSide = r; | |
const throttleQueensSpeed = true; | |
//[[2,6,2],[7,4,7],[2,3,2],[4,6,4],[5,3,5],[1,4,1],[7,6,7]] | |
const roadmap = [[6,2,6],[7,1,7],[3,5,3],[6,2,6],[1,4,1],[7,5,7],[6,2,6]]//[[4,1,4],[6,7,6],[3,5,3],[6,2,6],[7,3,7],[1,4,1],[7,2,7]] | |
.map(l=>l.slice(0,2).map(c=>COLORS[c])); | |
const RU = roadmap.slice(0, 3); | |
const RD = roadmap.slice(4, 7); | |
const RC = [//RU[1], | |
RU[2], | |
roadmap[3], | |
RD[0], | |
/*RD[1]*/]; | |
// Alions | |
//const RU = [[C1,C2,C3,C4,C5], | |
// [C3,C4,C5,C1,C2], | |
// [C5,C1,C2,C3,C4], | |
// [C2,C3,C4,C5,C1], | |
// [C4,C5,C1,C2,C3]]; | |
//const RD = RU.slice().reverse(); | |
//const RC = [ | |
// RU[3], | |
// RU[4], | |
// [C1,C2,C3,C4,C5], | |
// RD[0], | |
// RD[1], | |
// ]; | |
console.log("----------------------------------"); | |
console.log(type,food,view); | |
RC.hp = 0; | |
RC.vp = 0; | |
RC.part = c; | |
RC.side = c; | |
RU.hp = 0; | |
RU.vp = 0; | |
RU.part = u; | |
RU.side = u; | |
RD.hp = 0; | |
RD.vp = 0; | |
RD.part = d; | |
RD.side = d; | |
const QUEEN = 5; | |
const MU = 1; | |
const MD = 2; | |
const mySide = type==MU? u : d; | |
const otherSide = type==MU? d : u; | |
const RCtR = translates(RC, R); | |
const translates2D = what => translates(what, R).map(c => translates(c, U)).reduce((a,b)=>a.concat(b)); | |
const rail = {or: | |
[ | |
//...RCtR.map(cp => {var res=cp.slice(1); for (let cv of PatternKeep) res[cv] = cp[cv]; res.side = c; return res}), // center | |
...RCtR, // up | |
//...RCtR.map(cp => {var res=cp.slice(2); for (let cv of PatternKeep) res[cv] = cp[cv]; res.side = d; return res}), // down | |
...(/*type==MD? [] : */translates2D(RU)), | |
...(/*type==MU? [] : */translates2D(RD)), | |
].map(c => setSize(c, 3, 3)) | |
}; | |
var foods; | |
var ref; | |
var refScorer; | |
{ | |
let scoreTotal = 0; | |
let ptt; | |
let correct = 0; | |
let corrstr = ""; | |
let corr = []; | |
let trustMap = [[ .6, .6,.5], | |
[1.2, 1.2, 1], | |
[ 2, 2, 1]]; | |
refScorer = { | |
new: () => {scoreTotal = 0; correct = 0; corrstr = ""; corr = [];}, | |
add: (real, wanted, where, pattern) => { | |
ptt = pattern; | |
let eqt = cellsEq(real, wanted); | |
if (eqt) correct++; | |
corrstr+= eqt?"#":" "; | |
corr.push(eqt); | |
//if (pattern.part == c) scoreTotal += (eqt? 2 : -1) * (pattern.side==c && L<=where && where<=R? 3 : 1); | |
//else scoreTotal += (eqt === 2? 0.1 : eqt? (pattern.part!=mySide? 0.25 : 1) : -.5) * trustMap[(pattern.part==u? x=>x : x=> 2-x) (Math.floor(where/3))][where%3]; | |
// else scoreTotal += (eqt? 1 : -1) * trustMap[(pattern.part==u? 0 : 3) + (pattern.part==u? 1 : -1) * Math.floor(where/3)][where%3]; | |
}, | |
finish: (currBest) => { | |
if (correct == 9) scoreTotal = 1e308; | |
if (correct > 5) correct+= 3; | |
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++; | |
}); | |
if (ptt.part==c) { | |
if (type==QUEEN) scoreTotal+= 5; | |
else if (!food) scoreTotal-= 10; | |
else scoreTotal-= 2; | |
} | |
if (ptt.side == c) { | |
if (corrstr.slice(0,3).match(/###/) && corrstr.slice(6,9).match(/###/)) scoreTotal+= 5; | |
} | |
if (cols.filter(c=>c!==WH).length < 2) scoreTotal = 1e308; | |
var fc = (what) => (["u","c","d"][(what-17)/3]) | |
//if (scoreTotal>0) console.log((scoreTotal > currBest? "!" : " ")+`P[+${fc(ptt.part)}|${fc(ptt.side)}@${ptt.vp} ${ptt.hp}] score =`,scoreTotal,"/",currBest, ptt, "["+corrstr+"]"); | |
return correct+scoreTotal/10; | |
} | |
}; | |
} | |
reference(rail, undefined, refScorer); | |
const vP = ref.pt.vp; | |
const hP = ref.pt.hp; | |
const Rpart = ref.pt.part; | |
const Rside = ref.pt.side; | |
if (isQueen) { | |
if (food < 2 && ref.correct < 6) { | |
//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 (repair([C,L,R])) { | |
if (food && food < 150 && vP == 0 && /*hP == 0 &&*/ (find({ant:{type:MU}}) || find({ant:{type:MD}})) && random4() < 2) { | |
let foundU = find({ant:{type:MU}}); | |
let foundD = find({ant:{type:MD}}); | |
if (foundU && !foundD) spawn(d, MD); | |
else if (foundD && !foundU) spawn(u, MU); | |
else if (random4() == 0) spawn(u, MU); | |
else if (random4() == 1) spawn(d, MD); | |
} | |
// console.log(Rside, "||", Rpart); | |
if (Rside === c && (!throttleQueensSpeed || random4() < 2 || find({ant:"worker"}))) move([r,u,d]); | |
else if (Rside === u) { | |
if (Rpart === c && get(dr).ant) move(r); | |
else move([d,r]); | |
} | |
else if (Rside === d) { | |
if (Rpart === c && get(ur).ant) move(r); | |
else move([u,r]); | |
} | |
} else { | |
if (food > 0 && food < 3 && ref.dist == 1) { | |
let foundU = find({ant:{type:MU}}); | |
let foundD = find({ant:{type:MD}}); | |
if (foundU && !foundD) spawn(d, MD, true); | |
else if (foundD && !foundU) spawn(u, MU, true); | |
else if (random4() < 2) spawn(u, MU, true); | |
else spawn(d, MD, true); | |
} | |
} | |
} | |
} else if (type == MU || type == MD) { | |
if (food) { | |
if (repair()) { | |
//var blocked = obstacle(backtrackSide) && obstacle(backtrackSide-3) && obstacle(backtrackSide+3); | |
if (Rside === c) move([backtrackSide, mySide]); | |
else if (Rside === u) { | |
if (obstacle(backtrackSide+3)) move([backtrackSide, u]); | |
else move([d,backtrackSide]); | |
} else if (Rside === d) { | |
if (obstacle(backtrackSide-3)) move([backtrackSide, d]); | |
else move([u,backtrackSide]); | |
} | |
} | |
} else { | |
const moveSideI = 40-moveSide; | |
const moveSideAdd = moveSide==r? 1 : -1; | |
const repairOrder = [ur,u,ul,r,c,l,dr,d,dl].filter(c=>c!=mySide + moveSideAdd/* && c!=moveSide*/).map(c => c&~rp); | |
if (find({food:1})) { | |
if (repair(repairOrder)) { | |
var place = find({food:1}); | |
if (place%2 == 1) move(place); | |
else move(rotate1CW(rawp(place))); | |
} | |
} | |
else if (find({ant:{type:QUEEN}})) { if (repair(repairOrder)) move(mySide); } | |
else if (Rside == otherSide) { if (repair(repairOrder)) move(mySide); } | |
else if (!correct(otherSide + moveSideAdd)) { // if there's a hole in front of me | |
if (clear(otherSide + moveSideAdd) && [ur,u,ul,r,c,l,dr,d,dl].every(dir => (dir === otherSide+moveSideAdd) || fix(dir))) | |
move(otherSide); | |
} | |
else if (ref.dist == 0) move(mySide); | |
// else if (!correct(C)) fix(C); | |
else if (ref.dist == 1 && (!correct(mySide + moveSideAdd) || !correct(moveSide))) { if (clear(mySide + moveSideAdd)) move(/*random4()? mySide : */moveSide); } | |
else repair(repairOrder); | |
} | |
} | |
if (!toReturn) toReturn = NOP; | |
return toReturn; | |
//---------------------------------helper functions below--------------------------------- | |
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 :p*/); | |
} | |
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)) { | |
let ccolor = defColor(shouldbe); | |
if (ccolor != ref.view[index]) { | |
if (!firstdirs) { | |
color(index|rp, 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==c).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) { // log(full, new Error().stack); | |
if (typeof required === "number") { | |
if (required === -1) return 2; | |
if (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 (!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 && required.color !== full.color) return false; | |
if (required.food !== undefined && full.food !== required.food) return false; | |
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) { | |
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