project0实现一个2048游戏,大部分逻辑其实已经写好了,只需要把目光放在Model.java
中主要的任务实现以下几个函数
emptySpaceExists
maxTileExists
atLeastOneMoveExists
tilt
前三个较为简单这里就不多赘述,重点实现tile方法
Tile method实现
在写tile函数之前务必阅读文档,了解一下函数的用法以及作用
- Border的tile
- move
- setViewingPerspective
完成以下检验是否真正的理解需求
实现
根据Tips的提示,我们可以先从只考虑向上移动来进行分析。Border.tile(c, r)的行为是一列一列进行遍历的。
for (int c = 0; c < border.size(); c++) {
for (int r = 0; r < border.size(); r++) {
// 具体实现逻辑,针对该列进行操作
}
}
判断是否合并其实就是寻找该列中是否满足某个性质,如果满足则移动到X
行。需要维护每一列的数据。因为文档提供了setViewingPerspective
,因此只需要专注实现向上移动的逻辑,如果我们的循环是从顶行开始,会方便许多,因为向上移动是最简单的情况,如果某一列上的顶行没有元素,则直接移动到顶行即可。
for (int c = board.size() - 1; c >= 0; c--) {
int[] x = new int[4];
for (int r = board.size() - 2; r >= 0; r--) {
// 具体实现逻辑,针对该列进行操作
}
}
维护了一个数组x
用于记录当前行中有什么元素,用于判断是否合并,所以大体的框架就可以写出来了
for (int c = board.size() - 1; c >= 0; c--) {
int[] x = new int[4];
// 将顶行元素添加到辅助数组中
if (board.tile(c, 3) != null) x[3] = board.tile(c, 3).value();
for (int r = board.size() - 2; r >= 0; r--) {
if (board.tile(c, r) != null) {
int currentValue = board.tile(c, r).value();
Tile t = board.tile(c, r);
x[r] = currentValue;
// 获取更新到某行
// int moveStep = TODO
// TODO Score实现
board.move(c, moveStep, t);
// TODO 更新辅助数组值
changed = true;
}
}
}
现在只需要考虑如何获取该移动到多少行,以及怎么更新移动后到数组
- 合并
当前元素到顶行中,遇到的第一个非0的数,与其相等
- 不合并
当前元素到顶行中,遇到的第一个非0的数,与其不相等
获取Step函数
private int getMoveStep(int[] x, int col, int row, int currentValue, int len) {
// 记录移动到多少行
int res = 0;
for (res = row; res < x.length - 1 - len; res++) {
// 当前位置上的元素不等于上面的元素且上一个元素不等于零则不动
if (currentValue != x[res + 1] && x[res + 1] != 0) return res;
// 当前元素等于上一个元素 当起行+1
else if (currentValue == x[res + 1]) return res + 1;
}
return res;
}
我们还需要维护一个len
,寻找第一个非0的数,边界应该是顶行元素,注意这里的顶行元素不应该是被合并过的值(如下图
当我们遍历到蓝色的4,这时候我们就不能以最初的顶行为标准了
那len是从哪里来的,len的大小应该与合并的次数有关,只有当该列进行了合并,才会修改边界
update函数
在执行完move函数,循环遍历该列更新辅助数组
private void update(int[] x, int col) {
for (int r = 0; r < board.size(); r++) {
if (board.tile(col, r) != null) {
x[r] = board.tile(col, r).value();
} else {
x[r] = 0;
}
}
}
计算Score函数
借助
moveStep
的值,只需要判断,移动的位置元素的值,是否与它本身元素值相等并且返回的
moveStep
不能与它本身的位置相等。
if (board.tile(c, moveStep) != null && moveStep != r) {
score += 2 * board.tile(c, moveStep).value();
len++;
}