我目前有一个很长的脚本,可以解释每个场景。我写这篇文章是为了在棋盘上向上,向下,向左或向右移动AI。
包括所有评论,我的实际脚本长448行,非常混乱,因为大多数代码被复制到每个场景的帐户。 (如果感兴趣,可以找到here)
所以你不必查看448行代码,我写了一些伪代码:
function ai() {
var r = 0 or 1
if condition
if 0
r = 0 or 1
if 0
if canDo c
do c
else
if canDo d
do d
else
if canDo a
do a
else
if canDo b
do b
else
giveUp
else if 1
if canDo d
do d
else
if canDo c
do c
else
if canDo a
do a
else
if canDo b
do b
else
giveUp
else if 1
r = 0 or 1
if 0
if canDo a
do a
else
if canDo b
do b
else
if canDo c
do c
else
if canDo d
do d
else
giveUp
else if 1
if canDo b
do b
else
if canDo a
do a
else
if canDo c
do c
else
if canDo d
do d
else
giveUp
else
if 0
r = 0 or 1
if 0
if canDo c
do c
else
if canDo d
do d
else
if canDo a
do a
else
if canDo b
do b
else
giveUp
else if 1
if canDo d
do d
else
if canDo c
do c
else
if canDo a
do a
else
if canDo b
do b
else
giveUp
else if 1
r = 0 or 1
if 0
if canDo a
do a
else
if canDo b
do b
else
if canDo c
do c
else
if canDo d
do d
else
giveUp
else if 1
if canDo b
do b
else
if canDo a
do a
else
if canDo c
do c
else
if canDo d
do d
else
giveUp
}
是否有更简单的方法可以实现多种方案,因为您可以看到它变得非常快很长?
答案 0 :(得分:1)
最重要的是要识别出重复代码的位置(并且你有很多代码)并将其分解为可重用的函数。然后,这通常会让您注意到更多重复的代码,您可以进一步考虑这些代码。然后您可能会注意到类似的代码,并且可以将其分解为更一般的情况。这就是我在你的代码上做到这一点时想出来的:
function ai(charPos) {
var r = getRandomInt(0, 1);
if (aiPos[0] - pos[0] > (aiPos[1] - pos[1]) * 2) {
// Horizontal distance shorter than vertical distance
if (!isInLine(charPos, aiPos, 'vertical')) {
tryVerticalThenHorizontal();
} else {
tryHorizontalThenVertical();
}
} else {
// Vertical distance shorter than horizontal distance
if (!isInLine(charPos, aiPos, 'horizontal')) {
tryHorizontalThenVertical();
} else {
tryVerticalThenHorizontal();
}
}
}
function Move(name, dx, dy) {
this.name = name;
this.dx = dx;
this.dy = dy;
}
var verticalMoves = [new Move("up", 0, -1), new Move("down", 0, 1)];
var horizontalMoves = [new Move("left", -1, 0), new Move("right", 1, 0)];
function tryVerticalThenHorizontal() {
if (!(pickAndTryMoves(verticalMoves) || pickandTryMoves(horizontalMoves))) {
aiShoot();
}
}
function tryHorizontalThenVertical() {
if (!(pickAndTryMoves(horizontalMoves) || pickAndTryMoves(verticalMoves))) {
aiShoot();
}
}
// Returns true if a move succeeded, false if not
// moves should be an array with two items, each of which is a Move
function pickAndTryMoves(moves) {
var option = getRandomInt(0, 1;
// Try moves[option], and moves[otherOption] if the first one fails
return tryMove(moves[option]) || tryMove(moves[1 - option]);
}
// move is a Move object
function tryMove(move) {
var canMove = canAiMove(move.name);
if (canMove) {
moveAi(move.dx, move.dy, move.name);
}
return canMove;
}
function moveAi(dx, dy, dirName) {
var x = aiPos[0], y = aiPos[1],
nextX = x + dx, nextY = y + dy;
map[nextY] = map[nextY].replaceAt(nextX, '2');
map[y] = map[y].replaceAt(x, wallChar);
aiPos[0] = nextX;
aiPos[1] = nextY;
aiLastDir = dirName;
}
答案 1 :(得分:0)
您可以测试不可能的条件,几乎所有代码都只是复制/粘贴以前的代码。将这些转化为功能,并更好地组织它们。
你不可能的条件的例子:
if (r == 1) {
do a
} else {
if (r == 1) {
do b
} else {
do c
}
}
在这种情况下不可能做b,如果r不等于1,我们只能到else语句,为什么我们再次测试呢?
我将相同的代码格式化为40行。你将不得不经历它,但你可以看到这样的事情是多么容易维护和更新:
function ai(charPos) {
var r = getRandomInt(0, 1);
var arrUp = [0, -1, 'up'], arrDown = [0, 1, 'down'],
arrLeft = [-1, 0, 'left'], arrRight = [1, 0 'right'];
if (r == 1) {
var horizontalArray = [arrRight, arrLeft, arrDown, arrUp];
var verticalArray = [arrUp, arrDown, arrLeft, arrRight];
} else {
var horizontalArray = [arrLeft, arrRight, arrUp, arrDown];
var verticalArray = [arrDown, arrUp, arrRight, arrLeft];
}
if (aiPos[0] - pos[0] > (aiPos[1] - pos[1]) * 2) {
// Horizontal distance shorter than vertical distance
if (!isInLine(charPos, aiPos, 'vertical')) ? move(verticalArray) : move(horizontalArray);
} else {
// Vertical distance shorter than horizontal distance
if (!isInLine(charPos, aiPos, 'horizontal')) ? move(horizontalArray) : move(verticalArray);
}
}
function directionalMove(directions) {
if (canAiMove(directions[0][0])) {
mappos(directions[0][0], directions[0][1], directions[0][2]);
} else if (canAiMove(directions[1][0])) {
mappos(directions[1][0], directions[1][1], directions[1][2]);
} else if (canAiMove(directions[2][0])) {
mappos(directions[2][0], directions[2][1], directions[2][2]);
} else if (canAiMove(directions[3][0])) {
mappos(directions[3][0], directions[3][1], directions[3][2]);
} else {
aiShoot();
}
}
function mappos(x, y, name) {
map[aiPos[1] + y] = map[aiPos[1] + y].replaceAt(aiPos[0] + x, '2');
map[aiPos[1]] = map[aiPos[1]].replaceAt(aiPos[0], wallChar);
aiPos[0] = aiPos[0] + x;
aiPos[1] = aiPos[1] + y;
aiLastDir = name;
}