我开始制作一个创建随机新地下城的地下城游戏。因为我有seededRandom
功能。从我的测试来看,这个功能是正确的。
function seededRandom (seed, min = 0, max = 1) {
const random = ((seed * 9301 + 49297) % 233280) / 233280
return min + random * (max - min)
}
它将在createDungeon
函数内调用Date.now()
作为seed
的参数
function createDungeon(numberOfRooms, rooms = []) {
...
const randomWidth = Math.floor(Generator.seededRandom(Date.now(), 10, 20))
const randomHeight = Math.floor(Generator.seededRandom(Date.now(), 10, 20))
const randomTopLeftCoordinate = Coordinate.create(
Math.floor(Generator.seededRandom(Date.now(), 10, previousRoom.width)), // x position
Math.floor(Generator.seededRandom(Date.now(), 10, previousRoom.height)) // y position
)
...
}
在我的测试中,我记录了start timestemp
,createDungeon return value
和end timestemp
,显然Date.now()
还不够。
1502301604075 // start timestemp
[
{ width: 19, height: 19, topLeftCoordinate: { x: 18, y: 18 } },
...
{ width: 19, height: 19, topLeftCoordinate: { x: 18, y: 18 } },
{ width: 19, height: 19, topLeftCoordinate: { x: 18, y: 18 } }
]
1502301604075 // end timestemp
我可以使用什么作为种子在每个对象中根据种子获得不同的值?
答案 0 :(得分:1)
与上述评论一样:有几个种子随机数库,应该非常适合您的应用程序。我在我的例子中使用了this one。
关键是在获取地牢的属性之前创建一个种子随机数生成器:
const DungeonCreator = seed => {
const rnd = new Math.seedrandom(seed);
return nrOfRooms => ({
width: inRange(rnd(), 0, 20),
height: inRange(rnd(), 0, 20),
topLeft: {
x: inRange(rnd(), 0, 10),
y: inRange(rnd(), 0, 10)
},
nrOfRooms
})
}
此方法返回一个地牢生成器,每次调用它时都会为您提供一个新的地牢。 然而,使用相同种子创建的生成器将为您提供相同的地下城。
虽然不是“纯粹”,但它使代码可以测试。
const DungeonCreator = seed => {
const rnd = new Math.seedrandom(seed);
return nrOfRooms => ({
width: inRange(rnd(), 0, 20),
height: inRange(rnd(), 0, 20),
topLeft: {
x: inRange(rnd(), 0, 10),
y: inRange(rnd(), 0, 10)
},
nrOfRooms
})
}
const myDungeonCreator1 = DungeonCreator("seedOne");
const myDungeonCreator2 = DungeonCreator("seedTwo");
const myDungeonCreator3 = DungeonCreator("seedOne");
const roomSizes = [1, 3, 6, 3, 2, 6];
const dungeons1 = roomSizes.map(myDungeonCreator1);
const dungeons2 = roomSizes.map(myDungeonCreator2);
const dungeons3 = roomSizes.map(myDungeonCreator3);
console.log("Creator 1 & 3 created the same dungeons:",
dungeonsEqual(dungeons1, dungeons3)
);
console.log("Creator 1 & 2 created the same dungeons:",
dungeonsEqual(dungeons1, dungeons2)
);
console.log("Creator 2 & 3 created the same dungeons:",
dungeonsEqual(dungeons2, dungeons3)
);
// Util
function inRange(value, min, max) {
return min + Math.floor(value * (max - min));
};
function dungeonEqual(d1, d2) {
return (
d1.nrOfRooms === d2.nrOfRooms &&
d1.width === d2.width &&
d1.height === d2.height &&
d1.topLeft.x === d2.topLeft.x &&
d1.topLeft.y === d2.topLeft.y
);
}
function dungeonsEqual(ds1, ds2) {
return ds1.every((d, i) => dungeonEqual(d, ds2[i]));
};
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js">
</script>