我正在做一个2048年的克隆,我的移动和合并瓷砖的方法真的很长。我听说过助手方法,但我有点不知道该如何使用它们。我觉得我的代码有点长,可以缩短,但我不知道怎么做。我能做些什么使它更短更干净?我也会接受任何建设性的批评,任何其他部分的方法。
public boolean move(Direction direction)
{
boolean didMove = false;
int multiplier = 2;
if (direction == Direction.RIGHT) {
//int i represents rows; int j represents columns
for (int i = 0; i < GRID_SIZE; i++ ) {
ArrayList<Integer> slideTile = new ArrayList<>();
//Copying row w/o 0s to ArrayList
for (int j = 0; j < GRID_SIZE; j++) {
if(grid[i][j] != 0) {
slideTile.add(grid[i][j]);
}
}
//Merging tiles that are next to each other if
//they are equal and updating score.
for (int j = slideTile.size()-1; j > 0; j--) {
if (slideTile.get(j).equals(slideTile.get(j-1))) {
slideTile.set(j, multiplier*slideTile.get(j-1));
score = score + multiplier*slideTile.get(j-1);
slideTile.set(j-1, 0);
}
}
//Removing 0s that may have resulted from merging
for (int j = 0; j < slideTile.size(); j++ ) {
if (slideTile.get(j) == 0) {
slideTile.remove(j);
}
}
//Adding 0s to beginning of ArrayList to slide tiles right
int size = slideTile.size();
for (int j = 0; j < (GRID_SIZE - size); j++){
slideTile.add(0, 0);
}
//Copying ArrayList row back to game grid.
for (int j = 0; j < GRID_SIZE; j++) {
this.grid[i][j] = slideTile.get(j);
}
}
didMove = true;
}
if (direction == Direction.LEFT) {
//int i represents rows; int j represents columns
for (int i = 0; i < GRID_SIZE; i++ ) {
ArrayList<Integer> slideTile = new ArrayList<>();
//Copying row w/o 0s to ArrayList
for (int j = 0; j < GRID_SIZE; j++) {
if(grid[i][j] != 0) {
slideTile.add(grid[i][j]);
}
}
//Merging tiles that are next to each other if
//they are equal and updating score.
for (int j = 0; j < slideTile.size()-1; j++) {
if (slideTile.get(j).equals(slideTile.get(j+1))) {
slideTile.set(j, multiplier*slideTile.get(j+1));
score = score + multiplier*slideTile.get(j+1);
slideTile.set(j+1, 0);
}
}
//Removing 0s that may have resulted from merging
for (int j = 0; j < slideTile.size(); j++ ) {
if (slideTile.get(j) == 0) {
slideTile.remove(j);
}
}
//Adding 0s to end of ArrayList to slide tiles left
int size = slideTile.size();
for (int j = 0; j < (GRID_SIZE - size); j++){
slideTile.add(0);
}
//Copying ArrayList row back to game grid.
for (int j = 0; j < GRID_SIZE; j++) {
this.grid[i][j] = slideTile.get(j);
}
}
didMove = true;
}
if (direction == Direction.UP) {
//int i represents rows; int j represents columns
for (int j = 0; j < GRID_SIZE; j++ ) {
ArrayList<Integer> slideTile = new ArrayList<>();
//Copying row w/o 0s to ArrayList
for (int i = 0; i < GRID_SIZE; i++) {
if ( grid [i][j] != 0 )
slideTile.add(grid[i][j]);
}
//Merging tiles that are next to each other if
//they are equal and updating score.
for (int i = 0; i < slideTile.size()-1; i++) {
if (slideTile.get(i).equals(slideTile.get(i+1))) {
slideTile.set(i, multiplier*slideTile.get(i+1));
System.out.println(slideTile.get(i));
score = score + multiplier*slideTile.get(i+1);
slideTile.set(i+1, 0);
}
}
//Removing 0s that may have resulted from merging
for (int i = 0; i < slideTile.size(); i++ ) {
if (slideTile.get(i) == 0) {
slideTile.remove(i);
}
}
//Adding 0s to end of ArrayList to slide tiles up
int size = slideTile.size();
for (int i = 0; i < (GRID_SIZE - size); i++){
slideTile.add(0);
}
//Copying ArrayList row back to game grid.
for (int i = 0; i < GRID_SIZE; i++) {
this.grid[i][j] = slideTile.get(i);
}
}
didMove = true;
}
if (direction == Direction.DOWN) {
//int i represents rows; int j represents columns
for (int j = 0; j < GRID_SIZE; j++ ) {
ArrayList<Integer> slideTile = new ArrayList<>();
//Copying row w/o 0s to ArrayList
for (int i = 0; i < GRID_SIZE; i++) {
if(grid[i][j] != 0) {
slideTile.add(grid[i][j]);
}
}
//Merging tiles that are next to each other if
//they are equal and updating score.
for (int i = slideTile.size()-1; i > 0; i--) {
if (slideTile.get(i).equals(slideTile.get(i-1))) {
slideTile.set(i, multiplier*slideTile.get(i-1));
score = score + multiplier*slideTile.get(i-1);
slideTile.set(i-1, 0);
}
}
//Removing 0s that may have resulted from merging
for (int i = 0; i <slideTile.size(); i++ ) {
if (slideTile.get(i) == 0) {
slideTile.remove(i);
}
}
//Adding 0s to end of ArrayList to slide tiles up
int size = slideTile.size();
for (int i = 0; i < (GRID_SIZE - size); i++){
slideTile.add(0, 0);
}
//Copying ArrayList row back to game grid.
for (int i = 0; i < GRID_SIZE; i++) {
this.grid[i][j] = slideTile.get(i);
}
}
didMove = true;
}
return didMove;
} 发布于 2015-02-05 20:37:48
孟曼妮有很多好的建议。我不知道这个2048游戏是什么,但这里有一些建议,以改变结构,以消除重复的代码。
ETA:一个快速的变化是,您的注释是I是行,j是列。为什么不直接使用"row“和"col”作为变量名呢?
你有四个看起来非常相似的长箱子。一个“代码嗅觉”规则是,明确的案例分析几乎总是表明您做错了什么。
我首先看到的是计算分数的算法。无论您是通过slideTile列表还是向后前进,有两个变体。我将其分离成一个SlideDirection枚举:
public enum SlideDirection
{
FORWARD {
@Override public int slide(List<Integer> slideTile, int multiplier)
{
int score = 0;
for (int idx = 0; idx < slideTile.size() - 1; idx++)
{
if (slideTile.get(idx).equals(slideTile.get(idx + 1)))
{
slideTile.set(idx, multiplier * slideTile.get(idx + 1));
score += multiplier * slideTile.get(idx + 1);
slideTile.set(idx + 1, 0);
}
}
return score;
}
},
BACKWARD {
@Override public int slide(List<Integer> slideTile, int multiplier)
{
int score = 0;
for (int idx = slideTile.size() - 1; idx > 0; idx--)
{
if (slideTile.get(idx).equals(slideTile.get(idx - 1)))
{
slideTile.set(idx, multiplier * slideTile.get(idx - 1));
score += multiplier * slideTile.get(idx - 1);
slideTile.set(idx - 1, 0);
}
}
return score;
}
};
public abstract int slide(List<Integer> slideTile, int multiplier);
}我看到的第二件事是循环,不管你是水平的还是垂直的。我也把它放进了定向灯里。注意,move方法使用SlideDirection来执行任何版本的幻灯片()是合适的!
public enum Orientation
{
Vertical {
@Override public int move(SlideDirection direction, int[][]grid, int multiplier)
{
int score = 0;
for (int col = 0; col < GRID_SIZE; col++)
{
ArrayList<Integer> slideTile = new ArrayList<>();
// Copying col w/o 0s to ArrayList
for (int row = 0; row < GRID_SIZE; row++)
if (grid[row][col] != 0)
slideTile.add(grid[row][col]);
// Merging tiles that are next to each other if
// they are equal and updating score.
score += direction.slide(slideTile, multiplier);
cleanUpSlideTile(slideTile);
// Copying ArrayList col back to game grid.
for (int row = 0; row < GRID_SIZE; row++)
grid[row][col] = slideTile.get(row);
}
return score;
}
},
Horizontal {
@Override public int move(SlideDirection direction, int[][]grid, int multiplier)
{
int score = 0;
for (int row = 0; row < GRID_SIZE; row++)
{
List<Integer> slideTile = new ArrayList<>();
// Copying row w/o 0s to ArrayList
for (int col = 0; col < GRID_SIZE; col++)
if (grid[row][col] != 0)
slideTile.add(grid[row][col]);
score += direction.slide(slideTile, multiplier);
cleanUpSlideTile(slideTile);
// Copying ArrayList row back to game grid.
for (int col = 0; col < GRID_SIZE; col++)
grid[row][col] = slideTile.get(col);
}
return score;
}
};
/**
* Merging tiles that are next to each other if they are equal and
* @param direction
* @param grid
* @param multiplier
* @return
*/
public abstract int move(SlideDirection direction, int[][]grid, int multiplier);
private static void cleanUpSlideTile(List<Integer> slideTile)
{
// Removing 0s that may have resulted from merging
for (int idx = 0; idx < slideTile.size(); idx++)
if (slideTile.get(idx) == 0)
slideTile.remove(idx);
// Adding 0s to beginning of ArrayList to slideDirection tiles right
int size = slideTile.size();
for (int idx = 0; idx < (GRID_SIZE - size); idx++)
slideTile.add(0, 0);
}
}现在你的方向灯将由这两个端点组成:
public enum Direction
{
RIGHT(Orientation.Horizontal, SlideDirection.FORWARD),
LEFT(Orientation.Horizontal, SlideDirection.BACKWARD),
UP(Orientation.Vertical, SlideDirection.FORWARD),
DOWN(Orientation.Vertical, SlideDirection.BACKWARD);
private Orientation orientation;
public Orientation getOrientation() { return orientation; }
private SlideDirection slideDirection;
public SlideDirection getSlideDirection() { return slideDirection; }
Direction(Orientation orientation, SlideDirection slide)
{
this.orientation = orientation;
this.slideDirection = slide;
}
}然后,您的移动函数看起来如下所示:
/**
* Return the score for the given direction.
* @param direction
* @return score
*/
public int move(Direction direction)
{
int multiplier = 2;
// TODO: Initialize the grid with values
int[][] grid = new int[GRID_SIZE][];
for (int i = 0; i < GRID_SIZE; i++)
grid[i] = new int[GRID_SIZE];
int score = direction.getOrientation().move(direction.getSlideDirection(), grid, multiplier);
return score;
}可能还有一些额外的清理可以完成,更好的名称,一些职责的改变,以及单元测试将有助于验证行为,但是最好能看到所有这些都在代码的其余部分中。
https://codereview.stackexchange.com/questions/79424
复制相似问题