下面的代码实现了在游戏2048中移动瓷砖的逻辑。“移动”(游戏板::moveRight(),游戏板::moveUp(),等等)方法似乎在重复实现。对于消除“移动”方法中的重复,有何想法?我希望每个“移动”方法的时间复杂度是相等的。我认为,一个轮转板以促进可重用运动的实现会导致非等效的时间复杂性。
#include "GameBoard.h"
GameBoard::GameBoard(std::vector<std::vector<double>> _board) :
board(std::move(_board)),
N(board.size())
{
if (N == 0)
throw std::runtime_error("Empty board.");
for (const auto &row : board)
if (row.size() != N)
throw std::runtime_error("Invalid board dimensions.");
}
const std::vector<std::vector<double>> &GameBoard::getBoard()
{
return board;
}
void GameBoard::moveRight()
{
for (size_t row = 0; row < N; ++row)
{
std::vector<bool> hasBeenCombined(N, false);
for (size_t adjacentCol = N - 1; adjacentCol > 0; --adjacentCol)
{
const auto col = adjacentCol - 1;
const auto value = board[row][col];
const auto nextNonzeroOrLastColumn = getNextNonzeroOrLastColumn(row, col);
if (board[row][nextNonzeroOrLastColumn] == 0)
board[row].back() = value;
else if (
board[row][nextNonzeroOrLastColumn] == value &&
!hasBeenCombined[nextNonzeroOrLastColumn])
{
board[row][nextNonzeroOrLastColumn] += value;
hasBeenCombined[nextNonzeroOrLastColumn] = true;
}
else if (nextNonzeroOrLastColumn != adjacentCol)
board[row][nextNonzeroOrLastColumn - 1] = value;
else
continue;
board[row][col] = 0;
}
}
}
void GameBoard::moveLeft()
{
for (size_t row = 0; row < N; ++row)
{
std::vector<bool> hasBeenCombined(N, false);
for (size_t adjacentCol = 0; adjacentCol < N - 1; ++adjacentCol)
{
const auto col = adjacentCol + 1;
const auto value = board[row][col];
const auto previousNonzeroOrFirstColumn = getPreviousNonzeroOrFirstColumn(row, col);
if (board[row][previousNonzeroOrFirstColumn] == 0)
board[row].front() = value;
else if (
board[row][previousNonzeroOrFirstColumn] == value &&
!hasBeenCombined[previousNonzeroOrFirstColumn])
{
board[row][previousNonzeroOrFirstColumn] += value;
hasBeenCombined[previousNonzeroOrFirstColumn] = true;
}
else if (previousNonzeroOrFirstColumn != adjacentCol)
board[row][previousNonzeroOrFirstColumn + 1] = value;
else
continue;
board[row][col] = 0;
}
}
}
void GameBoard::moveDown()
{
for (size_t col = 0; col < N; ++col)
{
std::vector<bool> hasBeenCombined(N, false);
for (size_t adjacentRow = N - 1; adjacentRow > 0; --adjacentRow)
{
const auto row = adjacentRow - 1;
const auto value = board[row][col];
const auto nextNonzeroOrLastRow = getNextNonzeroOrLastRow(row, col);
if (board[nextNonzeroOrLastRow][col] == 0)
board.back()[col] = value;
else if (
board[nextNonzeroOrLastRow][col] == value &&
!hasBeenCombined[nextNonzeroOrLastRow])
{
board[nextNonzeroOrLastRow][col] += value;
hasBeenCombined[nextNonzeroOrLastRow] = true;
}
else if (nextNonzeroOrLastRow != adjacentRow)
board[nextNonzeroOrLastRow - 1][col] = value;
else
continue;
board[row][col] = 0;
}
}
}
void GameBoard::moveUp()
{
for (size_t col = 0; col < N; ++col)
{
std::vector<bool> hasBeenCombined(N, false);
for (size_t adjacentRow = 0; adjacentRow < N - 1; ++adjacentRow)
{
const auto row = adjacentRow + 1;
const auto value = board[row][col];
const auto previousNonzeroOrFirstRow = getPreviousNonzeroOrFirstRow(row, col);
if (board[previousNonzeroOrFirstRow][col] == 0)
board.front()[col] = value;
else if (
board[previousNonzeroOrFirstRow][col] == value &&
!hasBeenCombined[previousNonzeroOrFirstRow])
{
board[previousNonzeroOrFirstRow][col] += value;
hasBeenCombined[previousNonzeroOrFirstRow] = true;
}
else if (previousNonzeroOrFirstRow != adjacentRow)
board[previousNonzeroOrFirstRow + 1][col] = value;
else
continue;
board[row][col] = 0;
}
}
}
size_t GameBoard::getNextNonzeroOrLastColumn(size_t row, size_t col)
{
while (col < N - 1 && board[row][++col] == 0)
;
return col;
}
size_t GameBoard::getPreviousNonzeroOrFirstColumn(size_t row, size_t col)
{
while (col > 0 && board[row][--col] == 0)
;
return col;
}
size_t GameBoard::getNextNonzeroOrLastRow(size_t row, size_t col)
{
while (row < N - 1 && board[++row][col] == 0)
;
return row;
}
size_t GameBoard::getPreviousNonzeroOrFirstRow(size_t row, size_t col)
{
while (row > 0 && board[--row][col] == 0)
;
return row;
}相应的标题:
#pragma once
#include <vector>
#ifdef GAME_EXPORTS
#define GAME_API __declspec(dllexport)
#else
#define GAME_API __declspec(dllimport)
#endif
class GameBoard
{
// Order important for construction.
std::vector<std::vector<double>> board;
const size_t N;
public:
GAME_API GameBoard(std::vector<std::vector<double>> board);
GAME_API const std::vector<std::vector<double>> &getBoard();
GAME_API void moveRight();
GAME_API void moveLeft();
GAME_API void moveDown();
GAME_API void moveUp();
private:
size_t getNextNonzeroOrLastColumn(size_t row, size_t col);
size_t getPreviousNonzeroOrFirstColumn(size_t row, size_t col);
size_t getNextNonzeroOrLastRow(size_t row, size_t col);
size_t getPreviousNonzeroOrFirstRow(size_t row, size_t col);
};以下测试演示了预期的使用:
#include "stdafx.h"
#include "CppUnitTest.h"
#include <GameBoard.h>
#include "assert_utility.h"
#include "test_board_utility.h"
namespace MSTest
{
TEST_CLASS(GameBoardTester)
{
public:
TEST_METHOD(testInvalidBoardThrows)
{
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
Assert::ExpectException<std::runtime_error>([]() { GameBoard({}); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ {}, {} }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ { 0 }, {} }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ {}, { 0 } }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ { 0 }, { 0 } }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ { 0, 0 }, {} }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ {}, { 0, 0 } }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ { 0, 0 }, { 0 } }); });
Assert::ExpectException<std::runtime_error>([]() { GameBoard({ { 0 }, { 0, 0 } }); });
GameBoard(
{
{ 0 }
}
);
GameBoard(
{
{ 0, 0 },
{ 0, 0 }
});
GameBoard(
{
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
});
GameBoard(
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testAllZeros)
{
assertAllRotatedTransformTransitions(
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
private:
void assertAllRotatedTransformTransitions(
std::vector<std::vector<double>> initial,
std::string movement,
std::vector<std::vector<double>> final
)
{
for (int i = 0; i < 4; i++) {
assertBoardTransition(initial, movement, final);
initial = rotateClockwise(std::move(initial));
movement = clockwiseMovementTransform(std::move(movement));
final = rotateClockwise(std::move(final));
}
}
void assertBoardTransition(
const std::vector<std::vector<double>> &initial,
const std::string &movement,
const std::vector<std::vector<double>> &final
)
{
GameBoard board(initial);
for (const auto &c : movement)
switch (c)
{
case 'r':
case 'R':
board.moveRight();
break;
case 'd':
case 'D':
board.moveDown();
break;
case 'l':
case 'L':
board.moveLeft();
break;
case 'u':
case 'U':
board.moveUp();
break;
}
assertAreEqual(final, board.getBoard());
}
std::string clockwiseMovementTransform(std::string movement)
{
for (auto &c : movement)
switch (c)
{
case 'r':
case 'R':
c = 'd';
break;
case 'd':
case 'D':
c = 'l';
break;
case 'l':
case 'L':
c = 'u';
break;
case 'u':
case 'U':
c = 'r';
break;
}
return movement;
}
public:
TEST_METHOD(testOneTwo)
{
assertAllRotatedTransformTransitions(
{
{ 2, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 0, 2, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 0, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testTwoTwos)
{
assertAllRotatedTransformTransitions(
{
{ 2, 2, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 0, 2, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 0, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 2, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 0, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testThreeTwos)
{
assertAllRotatedTransformTransitions(
{
{ 2, 2, 2, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 2, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 0, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testFourTwos)
{
assertAllRotatedTransformTransitions(
{
{ 2, 2, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 4, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testTwoUnequals)
{
assertAllRotatedTransformTransitions(
{
{ 2, 4, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 0, 4, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 0, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 4, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 0, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 2, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testThreeUnequals)
{
assertAllRotatedTransformTransitions(
{
{ 2, 4, 8, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 2, 4, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 4, 0, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 2, 4, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 2, 0, 4, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 2, 4, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 2, 4, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 2, 4, 8 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testFourUnequals)
{
assertAllRotatedTransformTransitions(
{
{ 2, 4, 8, 16 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 2, 4, 8, 16 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testCombinesOnlyOnce)
{
assertAllRotatedTransformTransitions(
{
{ 4, 2, 2, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 4, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 4, 2, 0, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 4, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 4, 0, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 4, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
assertAllRotatedTransformTransitions(
{
{ 0, 4, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"r",
{
{ 0, 0, 4, 4 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testTwiceAllZeros)
{
assertAllRotatedTransformTransitions(
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"rr",
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testThreeCombos)
{
assertAllRotatedTransformTransitions(
{
{ 8, 4, 2, 2 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
},
"rrr",
{
{ 0, 0, 0, 16 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
TEST_METHOD(testUnfortunateBoard)
{
assertAllRotatedTransformTransitions(
{
{ 2, 4, 2, 4 },
{ 4, 2, 4, 2 },
{ 2, 4, 2, 4 },
{ 4, 2, 4, 2 }
},
"rdlu",
{
{ 2, 4, 2, 4 },
{ 4, 2, 4, 2 },
{ 2, 4, 2, 4 },
{ 4, 2, 4, 2 }
});
}
TEST_METHOD(testVeryFortunateBoard)
{
assertAllRotatedTransformTransitions(
{
{ 2, 2, 2, 2 },
{ 2, 2, 2, 2 },
{ 2, 2, 2, 2 },
{ 2, 2, 2, 2 }
},
"rdlu",
{
{ 32, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
});
}
};
};包含测试的存储库可以找到这里。
发布于 2018-09-06 04:02:50
从廷塔法尔中汲取灵感,我实现了一个方法(游戏板::moveAlong),它结合了每个方向共有的平铺运动逻辑,以消除重复。
#include "GameBoard.h"
GameBoard::GameBoard(std::vector<std::vector<double>> _board) :
board(std::move(_board)),
N(board.size())
{
if (N == 0)
throw std::runtime_error("Empty board.");
for (const auto &row : board)
if (row.size() != N)
throw std::runtime_error("Invalid board dimensions.");
}
const std::vector<std::vector<double>> &GameBoard::getBoard()
{
return board;
}
void GameBoard::moveRight()
{
moveAlong(&GameBoard::toTheRight);
}
void GameBoard::moveLeft()
{
moveAlong(&GameBoard::toTheLeft);
}
void GameBoard::moveDown()
{
moveAlong(&GameBoard::downwards);
}
void GameBoard::moveUp()
{
moveAlong(&GameBoard::upwards);
}
void GameBoard::moveAlong(double &(GameBoard::*direction)(size_t slice, size_t element))
{
for (size_t slice = 0; slice < N; ++slice) {
std::vector<bool> hasBeenCombined(N, false);
for (size_t adjacentElement = N - 1; adjacentElement > 0; --adjacentElement)
{
const auto element = adjacentElement - 1;
const auto value = (this->*direction)(slice, element);
auto nextNonzeroOrLastElement = element;
while (nextNonzeroOrLastElement < N - 1 && (this->*direction)(slice, ++nextNonzeroOrLastElement) == 0)
;
if ((this->*direction)(slice, nextNonzeroOrLastElement) == 0)
(this->*direction)(slice, N - 1) = value;
else if (
(this->*direction)(slice, nextNonzeroOrLastElement) == value &&
!hasBeenCombined[nextNonzeroOrLastElement])
{
(this->*direction)(slice, nextNonzeroOrLastElement) += value;
hasBeenCombined[nextNonzeroOrLastElement] = true;
}
else if (nextNonzeroOrLastElement != adjacentElement)
(this->*direction)(slice, nextNonzeroOrLastElement - 1) = value;
else
continue;
(this->*direction)(slice, element) = 0;
}
}
}
double & GameBoard::toTheRight(size_t slice, size_t element)
{
return board[slice][element];
}
double & GameBoard::toTheLeft(size_t slice, size_t element)
{
return board[slice][N - 1 - element];
}
double & GameBoard::upwards(size_t slice, size_t element)
{
return board[N - 1 - element][slice];
}
double & GameBoard::downwards(size_t slice, size_t element)
{
return board[element][slice];
}这实现了我消除“迁移”方法之间的重复(至少是一些)的初衷。然而,非静态成员函数的传递似乎很奇怪,但我发现它在访问板时很有用。我认为代码将受益于帕帕加加的回答中演示的一些标准算法库函数,但我对这些函数还不太熟悉。
发布于 2018-09-04 00:24:55
要做到这一点,一种方法是拥有一个Cell类。通过这种方式,您可以使您的板成为一个vector<vector<Cell*>>,您可以拥有一个按行组织的集合和一个按列组织的集合。开销最小,因为它们是作为指针存储的。
现在,一个函数可以通过传递对集合的引用和使用集合的正向或反向迭代器的指示来完成所有的移动。
https://codereview.stackexchange.com/questions/203041
复制相似问题