我正在编写一个样本游戏,其中一个块永远落下,你需要从一侧到另一侧操纵它。如果你撞到墙壁,你会输。我正在尝试随机并不断地生成关卡,因此总会有一条路,所以路径逐渐变窄。
# #
# #
# ##
# ###
# ####
# #####
## #####
## #####
## ####
### ####
### ###
#### ###
#### ###
### ###
### ###
## ####
## ####
## #####
## #####
## ######
## ######
## ######
## ######
我目前的方法是拥有一系列可能的路径,然后我随机选择一行。问题是路径不平滑,有时候变得不可能:
# #
# ####
# #####
### ###
## #####
### ####
# ###
## #####
#### ### <--- can't get through here
## ####
#### ###
### ###
# ##
## ######
## #####
## ######
## #####
## #####
## ####
## ####
# #
### ###
## ###### <--- or here
# #
## ######
## ######
哪种算法可以帮助我开始使用它?
答案 0 :(得分:2)
这里是一个简单算法的基础,可以通过改进来获得更具挑战性和趣味性的游戏。这里没有IA 它只是生成路径,由于路径较旧,所以总是可以实现。
基本思想是坚持使用将成为路径中间的索引 在那里你随机停留或向右或向左移动这个中间索引。 我已经在我的实现中选择随机获得更窄的路径。一种可能的改进是通过考虑到这种具有连贯路径的方式的广泛性来做出更深入和更聪明的动作(如果需要,可以做到这一点)。
// path is a vector of booleans
// wideness tells how narrow the path is
// middle represents the middle of the path
while wideness > 0
{
thicken wideness sometimes
move middle to the right, left, or do not move it
print the path
}
你可以看一下 的 Live C++ code and algorithm here 强>
结果可能如下所示:
|# #########|
|## ########|
|## ########|
|### #######|
|#### ######|
|### #######|
|### #######|
|#### ######|
|##### #####|
|##### #####|
|##### #####|
|#### ######|
|##### #####|
|###### ####|
|####### ###|
|####### #####|
|######## ####|
|######### ###|
|######## ####|
|######### ###|
|######## ####|
|######### ###|
|######### ###|
|######## ####|
|######### ###|
|######### ###|
|########## ##|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########## ##|
|########## ##|
|########## ##|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########## ##|
|######### ###|
|######### ###|
|######### ###|
|########## ##|
|########## ##|
|########## ##|
|######### ###|
|######## ####|
|####### #####|
|###### ######|
|####### #####|
|######## ####|
|######### ###|
|######## ####|
|######### ###|
|######### ###|
|########## ##|
|########### #|
|########## ##|
|########## ##|
|########### #|
|########## ##|
|######### ###|
|########## ##|
|########## ##|
|########## ##|
|########## ##|
|######### ###|
|########## ##|
|########### #|
|########## ##|
|########### #|
|########### #|
|########### #|
|########## ##|
|########### #|
|########## ##|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########### #|
|########## ##|
|########### #|
|########### #|
|########## ##|
|######### ###|
|######### ###|
|########## ##|
|######### ###|
|########## ##|
|########## ####|
|########## ####|
|######### #####|
|######## ######|
|######### #####|
|######### #####|
|######## ######|
|######### #####|
|########## ####|
|######### #####|
|######## ######|
|######## ######|
|######## ######|
|######### #####|
|######### #####|
|########## ####|
|######### #####|
|########## ####|
|########## ####|
答案 1 :(得分:2)
我不确定课程,但可能适用以下原则。
你可以跟踪一个“洞中心指数”,i,它将跟踪任何给定水平的洞的中心,以及“当前洞口宽度”(将逐渐变小的东西),w
At each level:
i <- i +/- (w / 2)
w <- widthModify(w) //decreases width sometimes
for all "tokens" n on level
if [n < i - (w / 2)] or [n > i + (w / 2)] print("#")
else print(" ")
这意味着后续孔之间必须有一些重叠,因为下面的中心位于前一级的“孔的范围”。
答案 2 :(得分:1)
算法本身非常简单,正如其他人所建议的那样,要注意的要点是路径的连续性,这可以通过首先计算每行路径的宽度然后定位它来保证它。重叠前一行的间隙。
我们定义:
接下来,要生成 W i ,我们定义:
最后,要生成 X i ,我们定义:
将所有这些放在一起,这是一个实时的JavaScript实现:
function PathRow(fullWidth, progress, prevRow) {
var Rw = Math.random();
var Rx = Math.random();
this.width = Math.ceil(fullWidth * (1 - Math.pow(progress * (1 - Rw), 0.65)));
if(prevRow) {
this.x = Math.round(Rx * Math.min(fullWidth - this.width, prevRow.x + prevRow.width - 1) +
(1 - Rx) * Math.max(0, prevRow.x - this.width + 1));
}
else {
this.x = Math.round(Rx * (fullWidth - this.width));
}
}
function Game(width, height, target) {
this.progress = 0;
this.width = width;
this.height = height;
this.target = target;
this.path = [];
}
Game.prototype.next = function(progress) {
this.progress = progress;
this.path.push(new PathRow(this.width, this.progress, this.path[this.path.length - 1]));
this.draw();
}
Game.prototype.draw = function() {
var pathString = '';
for(var i = Math.max(0, this.path.length - this.height + 1); i < this.path.length; i++) {
pathString += '|' + new Array(this.path[i].x + 1).join('#') + new Array(this.path[i].width + 1).join(' ') + new Array(this.width - this.path[i].x - this.path[i].width + 1).join('#') + '|\r\n';
}
this.target.innerHTML = pathString;
}
var path = document.getElementById('path');
var go = document.getElementById('go');
go.onclick = function() {
go.disabled = true;
var game = new Game(20, 20, path);
var progress = 0;
var totalSteps = 480;
var interval = setInterval(function() {
game.next(progress++ / totalSteps);
if(progress == totalSteps) {
clearInterval(interval);
go.disabled = false;
}
}, 125);
}
#path {
white-space: pre;
font-family: monospace;
}
<div id="path"></div>
<br/><br/>
<button id="go">Go!</button>