doesn't detect portal if there is air in it, add test to check that

This commit is contained in:
Romain Beaumont 2015-12-14 02:58:00 +01:00
parent 703b42abea
commit 3d6dd9faec
2 changed files with 90 additions and 28 deletions

View file

@ -72,20 +72,37 @@ async function findBorder(world,{line,direction},directionV)
if(bottom.length<2 || top.length<2 || left.length<3 || right.length<3) if(bottom.length<2 || top.length<2 || left.length<3 || right.length<3)
return null; return null;
return [bottom,left,right,top]; return {bottom,left,right,top};
} }
async function detectFrame(world,startingPoint,directionV) async function detectFrame(world,startingPoint,directionV)
{ {
let potentialLines=await findPotentialLines(world,startingPoint,directionV); let potentialLines=await findPotentialLines(world,startingPoint,directionV);
return (await Promise.all(potentialLines return asyncFilter((await Promise.all(potentialLines
.map(line => findBorder(world,line,directionV)))) .map(line => findBorder(world,line,directionV))))
.filter(border => border!=null); .filter(border => border!=null)
.map(({bottom,left,right,top}) => ({bottom,left,right,top,air:getAir({bottom,left,right,top})})),
async ({air}) => await isAllAir(world,air));
}
async function asyncEvery(array,pred) {
return Promise.all(array.map(x => pred(x).then(y => y ? true : Promise.reject(false))))
.then(results => true)
.catch(x => false);
}
function asyncFilter(array,pred) {
return Promise.all(array.map(e => pred(e).then(a => a ? e : null))).then(r => r.filter(a => a!=null));
}
async function isAllAir(world,blocks)
{
return asyncEvery(blocks,async block => (await world.getBlockType(block))==0);
} }
function getAir(border) function getAir(border)
{ {
var [bottom,,,top]=border; var {bottom,top}=border;
return flatMap(bottom,pos => range(1,top[0].y-bottom[0].y).map(i => pos.offset(0,i,0))); return flatMap(bottom,pos => range(1,top[0].y-bottom[0].y).map(i => pos.offset(0,i,0)));
} }

View file

@ -22,6 +22,24 @@ function generatePortal(bottomLeft,direction,width,height){
} }
} }
async function makeWorldWithPortal(portal,additionalAir,additionalObsidian)
{
var {bottom,left,right,top,air}=portal;
var world=new World();
var chunk=new Chunk();
[bottom,left,right,top].forEach(border => border.forEach(pos => chunk.setBlockType(pos,49)));
air.forEach(pos => chunk.setBlockType(pos,0));
additionalAir.forEach(pos => chunk.setBlockType(pos,0));
additionalObsidian.forEach(pos => chunk.setBlockType(pos,49));
await world.setColumn(0,0,chunk);
return world;
}
describe("Generate portal",function(){ describe("Generate portal",function(){
it("generate a line",() => { it("generate a line",() => {
assert.deepEqual(generateLine(new Vec3(3,1,1),new Vec3(1,0,0),2),[new Vec3(3, 1, 1), new Vec3(4, 1, 1)]) assert.deepEqual(generateLine(new Vec3(3,1,1),new Vec3(1,0,0),2),[new Vec3(3, 1, 1), new Vec3(4, 1, 1)])
@ -38,8 +56,6 @@ describe("Generate portal",function(){
}); });
describe("Detect portal", function() { describe("Detect portal", function() {
var portalData=[]; var portalData=[];
portalData.push({ portalData.push({
name:"simple portal frame x", name:"simple portal frame x",
@ -89,29 +105,16 @@ describe("Detect portal", function() {
additionalObsidian:[].concat.apply([], [bottom, left, right,top]) additionalObsidian:[].concat.apply([], [bottom, left, right,top])
}); });
portalData.forEach(({name,bottomLeft,direction,width,height,additionalAir,additionalObsidian}) => { portalData.forEach(({name,bottomLeft,direction,width,height,additionalAir,additionalObsidian}) => {
var {bottom,left,right,top,air}=generatePortal(bottomLeft,direction,width,height); var portal=generatePortal(bottomLeft,direction,width,height);
var {bottom,left,right,top,air}=portal;
describe("Detect "+name,() => { describe("Detect "+name,() => {
var expectedBorder=[ var expectedBorder={bottom,left,right,top};
bottom,
left,
right,
top
];
var world; var world;
before(function(){ before(async function(){
world=new World(); world=await makeWorldWithPortal(portal,additionalAir,additionalObsidian);
var chunk=new Chunk();
expectedBorder.forEach(border => border.forEach(pos => chunk.setBlockType(pos,49)));
air.forEach(pos => chunk.setBlockType(pos,0));
additionalAir.forEach(pos => chunk.setBlockType(pos,0));
additionalObsidian.forEach(pos => chunk.setBlockType(pos,49));
return world.setColumn(0,0,chunk);
}); });
@ -203,15 +206,15 @@ describe("Detect portal", function() {
describe("detect portals",function(){ describe("detect portals",function(){
it("detect portals from bottom left",async function() { it("detect portals from bottom left",async function() {
var portals=await detectFrame(world,bottom[0],new Vec3(0,1,0)); var portals=await detectFrame(world,bottom[0],new Vec3(0,1,0));
assert.deepEqual(portals,[expectedBorder]) assert.deepEqual(portals,[portal])
}); });
it("detect portals from top left",async function() { it("detect portals from top left",async function() {
var portals=await detectFrame(world,top[0],new Vec3(0,-1,0)); var portals=await detectFrame(world,top[0],new Vec3(0,-1,0));
assert.deepEqual(portals,[expectedBorder]) assert.deepEqual(portals,[portal])
}); });
it("detect portals from right top",async function() { it("detect portals from right top",async function() {
var portals=await detectFrame(world,right[right.length-1],direction.scaled(-1)); var portals=await detectFrame(world,right[right.length-1],direction.scaled(-1));
assert.deepEqual(portals,[expectedBorder]) assert.deepEqual(portals,[portal])
}) })
}); });
@ -224,3 +227,45 @@ describe("Detect portal", function() {
}); });
describe("Doesn't detect non-portal",function() {
var portalData=[];
portalData.push({
name:"simple portal frame x with one obsidian in the middle",
bottomLeft:new Vec3(2,1,1),
direction:new Vec3(1,0,0),
width:5,
height:5,
additionalAir:[],
additionalObsidian:[new Vec3(4,3,1)]
});
portalData.forEach(({name,bottomLeft,direction,width,height,additionalAir,additionalObsidian}) => {
var portal = generatePortal(bottomLeft, direction, width, height);
var {bottom,left,right,top,air}=portal;
describe("Doesn't detect detect " + name, () => {
var world;
before(async function () {
world=await makeWorldWithPortal(portal, additionalAir, additionalObsidian);
});
describe("doesn't detect portals",function(){
it("doesn't detect portals from bottom left",async function() {
var portals=await detectFrame(world,bottom[0],new Vec3(0,1,0));
assert.deepEqual(portals,[])
});
it("doesn't detect portals from top left",async function() {
var portals=await detectFrame(world,top[0],new Vec3(0,-1,0));
assert.deepEqual(portals,[])
});
it("doesn't detect portals from right top",async function() {
var portals=await detectFrame(world,right[right.length-1],direction.scaled(-1));
assert.deepEqual(portals,[])
})
});
});
});
});