대망의
ScheduledWalk (). 여기서 잠시 테스트에 따른 구현을 했는데도 에러가 나네요. 왜 그럴까?
{{{~cpp
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey) {
testIsFinished();
testMoveNext();
int currentJourneyPosition = 0;
IntPair currentRoachPosition = startRoachPosition;
int totalMoveCount = 0;
IncrementBoardBlockCount(board, currentRoachPosition, maxRow, maxCol);
while (!IsFinished(journey, currentJourneyPosition, board, maxRow, maxCol)) {
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
totalMoveCount++;
currentJourneyPosition++;
}
return totalMoveCount;
}
void testScheduledWalk() {
char journey[MAX_JOURNEY_LENGTH] = "22222"; // 여정을 '22222' 를 받았다고 가정했습니다.
int maxCol = 10; // 판 사이즈는 10, 10
int maxRow = 10;
IntPair startRoachPosition;
startRoachPosition.n1 = 0; // Roach 의 시작 포인트는 0,0
startRoachPosition.n2 = 0;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[i*maxRow+j] = 0;
}
}
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey); // 전체 이동 기대수는
printf ("total move count : %d \n", totalMoveCount);
assert (totalMoveCount == 5); // 5 가 나와야 합니다. 근데 여기까지 작성한 바로는 6이 나오죠.
}
왜 그럴까요? 버그가 무엇인가를 먼저 파악해봐야 하겠죠.
1. ScheduledWalk 에서의 오류는 totalMoveCount 의 값이 다르다는 것이다.
2. totalMoveCount 의 값이 다르다는 것은 while 루프 조건이 틀리다는 뜻이다.
3. while 루프 조건이 틀리다는 뜻은 IsFinished() 가 올바르지 않았다라는 뜻이다.
4. IsFinished() 가 잘못되었다는 뜻은 IsJourneyEnd, IsAllBoardChecked 둘 중 하나 이상이 잘못되었다는 뜻이다.
하지만, 위의 모듈들은 Test Case를 다 만족을 시켜줬습니다. 그럼 Test Case 자체를 의심해봐야겠죠?
{{{~cpp
void testIsJourney() {
char journey[MAX_JOURNEY_LENGTH] = "111122222";
int currentPosition = 1;
assert (IsJourneyEnd(journey, currentPosition) == false);
currentPosition = 9; // <---- 전체 배열은 9개. 0번부터 시작하므로 8번까지여야 함.
assert (IsJourneyEnd(journey, currentPosition) == false); // <--- 고로 이건 true!
currentPosition = 10;
assert (IsJourneyEnd(journey, currentPosition) == true);
}
}}}
그렇다면, 틀린 생각을 맞다라고 가정하고 만들어진 IsJourneyEnd 또한 틀린 함수가 되겠군요. 이를 수정하고, 해당 소스도 수정합니다. 그리고 계속 프로그램을 돌려봅니다. 그리고 Test Case를 추가합니다.
{{{~cpp
void testScheduledWalk() {
char journey[MAX_JOURNEY_LENGTH] = "22222";
int maxCol = 10;
int maxRow = 10;
IntPair startRoachPosition;
startRoachPosition.n1 = 0;
startRoachPosition.n2 = 0;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[i*maxRow+j] = 0;
}
}
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
printf ("total move count : %d \n", totalMoveCount);
assert (totalMoveCount == 5);
assert (board[0*maxRow+0] == 1);
assert (board[0*maxRow+1] == 1);
assert (board[0*maxRow+2] == 1);
assert (board[0*maxRow+3] == 1);
assert (board[0*maxRow+4] == 1);
assert (board[0*maxRow+5] == 1);
}
}}}
=== Version 0.6 - Implementation : Output & 전체적 ===
여기까지 완료되었다면 ScheduledWalk 도 완료이군요. 그럼 Output 을 간단하게 구현합니다.
아직 Acceptance TestCase 를 거치지 않은 1차 완료 버전은 다음과 같습니다.
{{{~cpp
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef int BOOL;
typedef char* PSTR;
typedef unsigned int UINT;
const int MAX_JOURNEY_LENGTH = 1000;
typedef struct __IntegerPair {
int n1; // Row 와 관계된것들.
int n2; // Col 와 관계된것들.
} IntPair;
typedef struct __InputDataStructure {
IntPair boardSize;
IntPair roachPosition;
char journey[MAX_JOURNEY_LENGTH];
} InputData;
InputData Input();
IntPair InputBoardSize();
IntPair InputStartRoachPosition();
void InputRoachJourney(PSTR journey);
void testInput();
void InitializeArray(int* board, int maxRow, int maxCol);
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey);
BOOL IsFinished(PSTR journey, int currentPosition, int* board, int maxRow, int maxCol);
BOOL IsJourneyEnd(PSTR journey, int currentPosition);
BOOL IsAllBoardChecked(int* board, int maxRow, int maxCol);
void testIsJourney();
void testIsAllBoardCheck();
IntPair MoveNext(IntPair currentRoachPosition, PSTR journey, int currentJourneyPosition, int* board, int maxRow, int maxCol);
IntPair GetMoveVector(char* journey, int currentPosition);
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol);
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol);
void testGetMoveVector();
void testMoveRoach();
void testIncrementBoardBlockCount();
void testIsFinished();
void testMoveNext();
void testScheduledWalk();
void Output(int totalMoveCount, int* board, int maxRow, int maxCol);
void OutputMoveCount(int totalMaxCount);
void OutputBoardStatus(int* board, int maxRow, int maxCol);
int main()
{
/* ------------- excute test code -------------
testInput();
testScheduledWalk();
------------- excute test code ------------- */
InputData inputData = Input();
int maxRow = inputData.boardSize.n1;
int maxCol = inputData.boardSize.n2;
int* board = new int[maxRow * maxCol];
InitializeArray(board, maxRow, maxCol);
IntPair startRoachPosition = inputData.roachPosition;
char journey[MAX_JOURNEY_LENGTH]="";
strcpy(journey, inputData.journey);
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
Output(totalMoveCount, board, maxRow, maxCol);
delete board;
return 0;
}
void InitializeArray(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[i*maxRow+j] = 0;
}
}
}
InputData Input() {
InputData inputData;
inputData.boardSize = InputBoardSize();
inputData.roachPosition = InputStartRoachPosition();
InputRoachJourney(inputData.journey);
InputEndCode();
return inputData;
}
void testInput() {
InputData inputData;
inputData = Input();
// For Input() Testing....
printf ("Board Size value : %d, %d \n", inputData.boardSize.n1, inputData.boardSize.n2);
printf ("Start Position value : %d, %d \n", inputData.roachPosition.n1, inputData.roachPosition.n2);
printf ("Journey : %s \n", inputData.journey);
}
IntPair InputBoardSize() {
IntPair size;
int boardRow;
int boardCol;
scanf("%d%d", &boardRow, &boardCol);
size.n1 = boardRow;
size.n2 = boardCol;
return size;
}
IntPair InputStartRoachPosition() {
IntPair position;
int startRow;
int startCol;
scanf("%d%d", &startRow, &startCol);
position.n1 = startRow;
position.n2 = startCol;
return position;
}
void InputRoachJourney(PSTR journey) {
scanf ("%s", journey);
}
void InputEndCode() {
int endCode;
scanf("%d", &endCode);
}
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey) {
testIsFinished();
testMoveNext();
int currentJourneyPosition = 0;
IntPair currentRoachPosition = startRoachPosition;
int totalMoveCount = 0;
IncrementBoardBlockCount(board, currentRoachPosition, maxRow, maxCol);
while (!IsFinished(journey, currentJourneyPosition, board, maxRow, maxCol)) {
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
totalMoveCount++;
currentJourneyPosition++;
}
return totalMoveCount;
}
void testScheduledWalk() {
char journey[MAX_JOURNEY_LENGTH] = "22222";
int maxCol = 10;
int maxRow = 10;
IntPair startRoachPosition;
startRoachPosition.n1 = 0;
startRoachPosition.n2 = 0;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[i*maxRow+j] = 0;
}
}
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
printf ("total move count : %d \n", totalMoveCount);
assert (totalMoveCount == 5);
assert (board[0*maxRow+0] == 1);
assert (board[0*maxRow+1] == 1);
assert (board[0*maxRow+2] == 1);
assert (board[0*maxRow+3] == 1);
assert (board[0*maxRow+4] == 1);
assert (board[0*maxRow+5] == 1);
}
void testIsFinished() {
// Test Data.
char journey[MAX_JOURNEY_LENGTH] = "22";
int currentPosition = 0;
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 0;
}
}
int maxRow = 10;
int maxCol = 10;
int roachPositionRow = 0;
int roachPositionCol = 0;
assert(IsFinished(journey, currentPosition, board, maxRow, maxCol) == false);
}
BOOL IsFinished(PSTR journey, int currentPosition, int* board, int maxRow, int maxCol) {
testIsJourney();
testIsAllBoardCheck();
return IsJourneyEnd(journey, currentPosition) || IsAllBoardChecked(board, maxRow, maxCol);
}
BOOL IsJourneyEnd(PSTR journey, int currentPosition) {
return strlen(journey) <= (UINT)currentPosition;
}
void testIsJourney() {
char journey[MAX_JOURNEY_LENGTH] = "111122222";
int currentPosition = 1;
assert (IsJourneyEnd(journey, currentPosition) == false);
currentPosition = 9;
assert (IsJourneyEnd(journey, currentPosition) == true);
currentPosition = 10;
assert (IsJourneyEnd(journey, currentPosition) == true);
}
BOOL IsAllBoardChecked(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
if (board[i*maxRow+j] <= 0) return false;
}
}
return true;
}
void testIsAllBoardCheck() {
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 1;
}
}
assert (IsAllBoardChecked(board, 10, 10) == true);
board[0] = 0;
assert (IsAllBoardChecked(board, 10, 10) == false);
}
IntPair MoveNext(IntPair currentRoachPosition, PSTR journey, int currentJourneyPosition, int* board, int maxRow, int maxCol) {
testGetMoveVector();
testMoveRoach();
testIncrementBoardBlockCount();
IntPair updatedRoachPosition;
IntPair moveVector = GetMoveVector(journey, currentJourneyPosition);
updatedRoachPosition = MoveRoach(currentRoachPosition, moveVector, maxRow, maxCol);
IncrementBoardBlockCount(board, updatedRoachPosition, maxRow, maxCol);
return updatedRoachPosition;
}
void testMoveNext() {
IntPair currentRoachPosition;
char journey[] = "333";
int maxRow = 10;
int maxCol = 10;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[i*maxRow+j] = 0;
}
}
currentRoachPosition.n1 = 9;
currentRoachPosition.n2 = 9;
int currentJourneyPosition = 0;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 0);
assert (board[0*maxRow+0] == 1);
currentJourneyPosition = 1;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 1);
assert (currentRoachPosition.n2 == 1);
assert (board[1*maxRow+1] == 1);
currentJourneyPosition = 2;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 2);
assert (currentRoachPosition.n2 == 2);
assert (board[2*maxRow+2] == 1);
}
IntPair GetMoveVector(char* journey, int currentJourneyPosition) {
IntPair moveVector;
// vector - row move vector, col move vector.
int MOVE_VECTOR_PAIR_ROW[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int MOVE_VECTOR_PAIR_COL[8] = { 0, 1, 1, 1, 0, -1, -1, -1};
int moveVectorPairIndex = journey[currentJourneyPosition] - '0';
moveVector.n1 = MOVE_VECTOR_PAIR_ROW[moveVectorPairIndex];
moveVector.n2 = MOVE_VECTOR_PAIR_COL[moveVectorPairIndex];
return moveVector;
}
void testGetMoveVector() {
char journey[MAX_JOURNEY_LENGTH] = "247";
IntPair nextMoveVector;
nextMoveVector = GetMoveVector(journey, 0);
assert (nextMoveVector.n1 == 0);
assert (nextMoveVector.n2 == 1);
nextMoveVector = GetMoveVector(journey, 1);
assert (nextMoveVector.n1 == 1);
assert (nextMoveVector.n2 == 0);
nextMoveVector = GetMoveVector(journey, 2);
assert (nextMoveVector.n1 == -1);
assert (nextMoveVector.n2 == -1);
}
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol) {
IntPair updatedRoachPosition;
updatedRoachPosition.n1 = (currentRoachPosition.n1 + moveVector.n1) % maxRow;
updatedRoachPosition.n2 = (currentRoachPosition.n2 + moveVector.n2) % maxCol;
return updatedRoachPosition;
}
void testMoveRoach() {
IntPair currentRoachPosition;
IntPair moveVector;
currentRoachPosition.n1 = 0;
currentRoachPosition.n2 = 0;
// case move type '2':
moveVector.n1 = 0;
moveVector.n2 = 1;
currentRoachPosition = MoveRoach(currentRoachPosition, moveVector, 10, 10);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 1);
// One More Time..~
moveVector.n1 = 0;
moveVector.n2 = 1;
currentRoachPosition = MoveRoach(currentRoachPosition, moveVector, 10, 10);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 2);
// Checking Boundary Warp.
int maxCol = 10;
int maxRow = 10;
currentRoachPosition.n1 = 9;
currentRoachPosition.n2 = 9;
moveVector.n1 = 1;
moveVector.n2 = 1;
currentRoachPosition = MoveRoach(currentRoachPosition, moveVector, maxRow, maxCol);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 0);
}
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol) {
assert (roachPosition.n1 < maxRow);
assert (roachPosition.n2 < maxCol);
board[roachPosition.n1*maxRow + roachPosition.n2]++;
}
void testIncrementBoardBlockCount() {
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 0;
}
}
IntPair currentRoachPosition;
currentRoachPosition.n1 = 1;
currentRoachPosition.n2 = 1;
IncrementBoardBlockCount(board, currentRoachPosition, 10, 10);
assert (board[1*10+1] == 1);
}
void Output(int totalMoveCount, int* board, int maxRow, int maxCol) {
OutputMoveCount(totalMoveCount);
OutputBoardStatus(board, maxRow, maxCol);
}
void OutputMoveCount(int totalMaxCount) {
printf ("%d\n", totalMaxCount);
printf ("\n");
}
void OutputBoardStatus(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
printf ("%d ", board[maxRow*i+j]);
}
printf ("\n");
}
}
}}}
=== Test & 버그 분석 ===
자. 이제 슬슬 ["RandomWalk2/TestCase"] 에 있는 ["AcceptanceTest"] 의 경우가 되는 예들을 하나하나 실행해봅니다.
{{{~cpp
F:\WorkingTemp\ScheduledWalk\Debug>ScheduledWalk
5 5
0 0
22224444346
999
11
2 1 1 1 2
1 0 0 0 1
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
본래 기대값 :
2 1 1 1 1
1 0 0 0 2
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
}}}
오호라 버그이군요. 결과 자체에 촛점을 맞춰봅시다. 마지막 6에 대한 이동이 마치 1에 대한 이동처럼 되어버렸군요. 일단, 바로 의심되는 것으로는 6번에 대한 이동부분. 이동방향벡터를 결정해주는 루틴을 찾아보면 GetMoveVector 이므로 이부분이 첫번째 의심을 받겠군요.
{{{~cpp
IntPair GetMoveVector(char* journey, int currentJourneyPosition) {
IntPair moveVector;
// vector - row move vector, col move vector.
int MOVE_VECTOR_PAIR_ROW[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int MOVE_VECTOR_PAIR_COL[8] = { 0, 1, 1, 1, 0, -1, -1, -1};
int moveVectorPairIndex = journey[currentJourneyPosition] - '0';
moveVector.n1 = MOVE_VECTOR_PAIR_ROW[moveVectorPairIndex];
moveVector.n2 = MOVE_VECTOR_PAIR_COL[moveVectorPairIndex];
return moveVector;
}
}}}
음.. Vector 자체로는 별 문제없어 보이네요. 그렇다면 다음은 실제 Roach를 이동시키는 Position 과 관련된 MoveRoach 부분을 살펴보죠. (여기서는 반드시 이동방향을 결정하는 함수와 실제 이동시키는 함수에 촛점을 맞춰야 합니다. board 배열의 값이 update 가 되기 위해선 어떠어떠한 값에 영향을 받는지를 먼저 머릿속에 그려야 겠죠.) 그림이 안 그려지는 경우에는 Debugger 와 Trace, break point 를 이용할 수 있습니다. 하지만, 구조화를 잘 시켜놓았을 경우 해당 문제발생시 버그 예상부분이 어느정도 그림이 그려집니다.
{{{~cpp
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol) {
IntPair updatedRoachPosition;
updatedRoachPosition.n1 = (currentRoachPosition.n1 + moveVector.n1) % maxRow;
updatedRoachPosition.n2 = (currentRoachPosition.n2 + moveVector.n2) % maxCol;
return updatedRoachPosition;
}
}}}
이 부분에 대해서 퍽 하고 깨우침을 얻었는데; (아이디어가 떠오르지 않을때 이 부분이 잘못되었음을 알려면 Debugger 를 써야겠죠.)
바로 index가 -1 이 되었을 경우이죠. 그러므로 Modular 연산으로 계산할 수 없다.
row 1, col 0 에서 row 0, col -1 을 더했을 경루를 생각한다면 row 1, col -1 입니다. -1 에 대해 modular 5를 한다면? 다름아닌 4가 나옵니다. 즉, 1, 4 가 되어버리죠.
일단 main ()을 test code 실행 모드로 바꾸고.
{{{~cpp
int main()
{
/* ------------- excute test code -------------
testInput();
testScheduledWalk();
------------- excute test code ------------- */
/*
InputData inputData = Input();
int maxRow = inputData.boardSize.n1;
int maxCol = inputData.boardSize.n2;
int* board = new int[maxRow * maxCol];
InitializeArray(board, maxRow, maxCol);
IntPair startRoachPosition = inputData.roachPosition;
char journey[MAX_JOURNEY_LENGTH]="";
strcpy(journey, inputData.journey);
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
Output(totalMoveCount, board, maxRow, maxCol);
delete board;
*/
testScheduledWalk();
return 0;
}
}}}
MoveRoach 코드를 일단은 가장 쉬운 코드로 고쳐봤습니다.
{{{~cpp
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol) {
IntPair updatedRoachPosition;
updatedRoachPosition.n1 = (currentRoachPosition.n1 + moveVector.n1);
updatedRoachPosition.n2 = (currentRoachPosition.n2 + moveVector.n2);
if (updatedRoachPosition.n1 >= maxRow) updatedRoachPosition.n1 = 0;
else if (updatedRoachPosition.n1 < 0) updatedRoachPosition.n1 = maxRow-1;
if (updatedRoachPosition.n2 >= maxCol) updatedRoachPosition.n2 = 0;
else if (updatedRoachPosition.n2 < 0) updatedRoachPosition.n2 = maxCol-1;
return updatedRoachPosition;
}
}}}
일단 assert 문 걸어놓은 부분에 대해선 ok.
{{{~cpp
5 5
0 0
22224444346
999
11
2 1 1 1 1
1 0 0 0 2
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
Press any key to continue
}}}
일단 Test Case 하나에 대해선 ok. 계속 테스트를 해 나갑니다.
["RandomWalk2/TestCase"] 에 대해서도 ok.
["RandomWalk2/TestCase2"] 의 Test1,2,3 에 대해서 ok. 오. 그럼 더이상의 테스트가 의미가 없을까요?
여기에 복병이 있었으니..
Test4 에 대해서는
{{{~cpp
5 4
0 0
2224444666
999
10
1 1 1 1
0 0 0 1
0 0 0 1
0 0 0 1
1 1 1 1
}}}
그리고 잘못된 연산 오류.
원하는 기대값은
{{{~cpp
10
1 1 1 1 0
0 0 0 1 0
0 1 0 1 0
1 1 1 1 0
}}}
["RandomWalk2/TestCase"] 에서 멈췄다면 큰일날 뻔 했군요. 테스트는 자주 해줄수록 그 프로그램의 신용도를 높여줍니다. 일종의 Quality Assurance 라고 해야겠죠.
일단 아웃풋 만을 두고 본다면, 배열 자체의 행과 열의 크기가 뒤집혔군요. 그렇다면 그에 따른 에러 가능성 높음. 그렇다고 한다면, 배열에 값을 증가시키는 IncrementBoardBlockCount() 에 에러가능성이 높겠습니다.
{{{~cpp
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol) {
assert (roachPosition.n1 < maxRow);
assert (roachPosition.n2 < maxCol);
board[roachPosition.n1*maxRow + roachPosition.n2]++; // <--- maxRow 가 아닌 maxCol 이여야 한다.
}
}}}
음? 이런 계산이 이 프로그램 내에서 굉장히 많이 나오죠. 2차원 동적배열을 1차원 배열로 구현해줬기 때문에. 오호라..
(그 밖에 1차원 배열로 계산했었던 부분들을 찾기 위해 Search 에서 '*maxRow+' 로 검색해봤습니다. 13군데 나오더군요;;)
여기서 얻을 수 있는 교훈 - 이런 변환 부분은 차라리 함수로 만들자는 겁니다. -_-; 이 경우 OO Language 라면 1차원 배열을 이용한 2차원 배열 클래스를 만들어 쓰는 것이 가장 편합니다. 문제를 해당 배열 클래스 내로 지역화 시킬 수 있죠. 여기서는 일단 C로 만들었다고 가정하고 배제합니다.
{{{~cpp
int _2to1(int row, int col, int maxCol) {
return maxCol*row + col;
}
}}}
중간에 ["NewTestsForOldBugs"] 을 읽음.
=== 최종 테스트들을 만족시키는 코드 ===
최종 테스트 (["RandomWalk2/TestCase"], ["RandomWalk2/TestCase2"]) 를 만족시키는 코드.
{{{~cpp
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef int BOOL;
typedef char* PSTR;
typedef unsigned int UINT;
const int MAX_JOURNEY_LENGTH = 1000;
typedef struct __IntegerPair {
int n1; // Row 와 관계된것들.
int n2; // Col 와 관계된것들.
} IntPair;
typedef struct __InputDataStructure {
IntPair boardSize;
IntPair roachPosition;
char journey[MAX_JOURNEY_LENGTH];
} InputData;
InputData Input();
IntPair InputBoardSize();
IntPair InputStartRoachPosition();
void InputRoachJourney(PSTR journey);
void InputEndCode();
void testInput();
void InitializeArray(int* board, int maxRow, int maxCol);
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey);
BOOL IsFinished(PSTR journey, int currentPosition, int* board, int maxRow, int maxCol);
BOOL IsJourneyEnd(PSTR journey, int currentPosition);
BOOL IsAllBoardChecked(int* board, int maxRow, int maxCol);
void testIsJourney();
void testIsAllBoardCheck();
IntPair MoveNext(IntPair currentRoachPosition, PSTR journey, int currentJourneyPosition, int* board, int maxRow, int maxCol);
IntPair GetMoveVector(char* journey, int currentPosition);
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol);
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol);
void testGetMoveVector();
void testMoveRoach();
void testIncrementBoardBlockCount();
void testIsFinished();
void testMoveNext();
void testScheduledWalk();
void Output(int totalMoveCount, int* board, int maxRow, int maxCol);
void OutputMoveCount(int totalMaxCount);
void OutputBoardStatus(int* board, int maxRow, int maxCol);
int _2to1(int row, int col, int maxCol) {
return maxCol*row+col;
}
int main()
{
/* ------------- excute test code -------------
testInput();
testScheduledWalk();
------------- excute test code ------------- */
InputData inputData = Input();
int maxRow = inputData.boardSize.n1;
int maxCol = inputData.boardSize.n2;
int* board = new int[maxRow * maxCol];
InitializeArray(board, maxRow, maxCol);
IntPair startRoachPosition = inputData.roachPosition;
char journey[MAX_JOURNEY_LENGTH]="";
strcpy(journey, inputData.journey);
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
Output(totalMoveCount, board, maxRow, maxCol);
delete board;
return 0;
}
void InitializeArray(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[_2to1(i,j,maxCol)] = 0;
}
}
}
InputData Input() {
InputData inputData;
inputData.boardSize = InputBoardSize();
inputData.roachPosition = InputStartRoachPosition();
InputRoachJourney(inputData.journey);
InputEndCode();
return inputData;
}
void testInput() {
InputData inputData;
inputData = Input();
// For Input() Testing....
printf ("Board Size value : %d, %d \n", inputData.boardSize.n1, inputData.boardSize.n2);
printf ("Start Position value : %d, %d \n", inputData.roachPosition.n1, inputData.roachPosition.n2);
printf ("Journey : %s \n", inputData.journey);
}
IntPair InputBoardSize() {
IntPair size;
int boardRow;
int boardCol;
scanf("%d%d", &boardCol, &boardRow);
size.n1 = boardRow;
size.n2 = boardCol;
return size;
}
IntPair InputStartRoachPosition() {
IntPair position;
int startRow;
int startCol;
scanf("%d%d", &startRow, &startCol);
position.n1 = startRow;
position.n2 = startCol;
return position;
}
void InputRoachJourney(PSTR journey) {
scanf ("%s", journey);
}
void InputEndCode() {
int endCode;
scanf("%d", &endCode);
}
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey) {
testIsFinished();
testMoveNext();
int currentJourneyPosition = 0;
IntPair currentRoachPosition = startRoachPosition;
int totalMoveCount = 0;
IncrementBoardBlockCount(board, currentRoachPosition, maxRow, maxCol);
while (!IsFinished(journey, currentJourneyPosition, board, maxRow, maxCol)) {
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
totalMoveCount++;
currentJourneyPosition++;
}
return totalMoveCount;
}
void testScheduledWalk() {
char journey[MAX_JOURNEY_LENGTH] = "22222";
int maxCol = 10;
int maxRow = 10;
IntPair startRoachPosition;
startRoachPosition.n1 = 0;
startRoachPosition.n2 = 0;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[_2to1(i,j,maxCol)] = 0;
}
}
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
printf ("total move count : %d \n", totalMoveCount);
assert (totalMoveCount == 5);
assert (board[_2to1(0,0,maxCol)] == 1);
assert (board[_2to1(0,1,maxCol)] == 1);
assert (board[_2to1(0,2,maxCol)] == 1);
assert (board[_2to1(0,3,maxCol)] == 1);
assert (board[_2to1(0,4,maxCol)] == 1);
assert (board[_2to1(0,5,maxCol)] == 1);
}
void testIsFinished() {
// Test Data.
char journey[MAX_JOURNEY_LENGTH] = "22";
int currentPosition = 0;
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 0;
}
}
int maxRow = 10;
int maxCol = 10;
int roachPositionRow = 0;
int roachPositionCol = 0;
assert(IsFinished(journey, currentPosition, board, maxRow, maxCol) == false);
}
BOOL IsFinished(PSTR journey, int currentPosition, int* board, int maxRow, int maxCol) {
testIsJourney();
testIsAllBoardCheck();
return IsJourneyEnd(journey, currentPosition) || IsAllBoardChecked(board, maxRow, maxCol);
}
BOOL IsJourneyEnd(PSTR journey, int currentPosition) {
return strlen(journey) <= (UINT)currentPosition;
}
void testIsJourney() {
char journey[MAX_JOURNEY_LENGTH] = "111122222";
int currentPosition = 1;
assert (IsJourneyEnd(journey, currentPosition) == false);
currentPosition = 9;
assert (IsJourneyEnd(journey, currentPosition) == true);
currentPosition = 10;
assert (IsJourneyEnd(journey, currentPosition) == true);
}
BOOL IsAllBoardChecked(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
if (board[_2to1(i,j,maxCol)] <= 0) return false;
}
}
return true;
}
void testIsAllBoardCheck() {
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 1;
}
}
assert (IsAllBoardChecked(board, 10, 10) == true);
board[0] = 0;
assert (IsAllBoardChecked(board, 10, 10) == false);
}
IntPair MoveNext(IntPair currentRoachPosition, PSTR journey, int currentJourneyPosition, int* board, int maxRow, int maxCol) {
testGetMoveVector();
testMoveRoach();
testIncrementBoardBlockCount();
IntPair updatedRoachPosition;
IntPair moveVector = GetMoveVector(journey, currentJourneyPosition);
updatedRoachPosition = MoveRoach(currentRoachPosition, moveVector, maxRow, maxCol);
IncrementBoardBlockCount(board, updatedRoachPosition, maxRow, maxCol);
return updatedRoachPosition;
}
void testMoveNext() {
IntPair currentRoachPosition;
char journey[] = "333";
int maxRow = 10;
int maxCol = 10;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[_2to1(i,j,maxCol)] = 0;
}
}
currentRoachPosition.n1 = 9;
currentRoachPosition.n2 = 9;
int currentJourneyPosition = 0;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 0);
assert (board[_2to1(0,0,maxCol)] == 1);
currentJourneyPosition = 1;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 1);
assert (currentRoachPosition.n2 == 1);
assert (board[_2to1(1,1,maxCol)] == 1);
currentJourneyPosition = 2;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 2);
assert (currentRoachPosition.n2 == 2);
assert (board[_2to1(2,2,maxCol)] == 1);
}
IntPair GetMoveVector(char* journey, int currentJourneyPosition) {
IntPair moveVector;
// vector - row move vector, col move vector.
int MOVE_VECTOR_PAIR_ROW[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int MOVE_VECTOR_PAIR_COL[8] = { 0, 1, 1, 1, 0, -1, -1, -1};
int moveVectorPairIndex = journey[currentJourneyPosition] - '0';
moveVector.n1 = MOVE_VECTOR_PAIR_ROW[moveVectorPairIndex];
moveVector.n2 = MOVE_VECTOR_PAIR_COL[moveVectorPairIndex];
return moveVector;
}
void testGetMoveVector() {
char journey[MAX_JOURNEY_LENGTH] = "247";
IntPair nextMoveVector;
nextMoveVector = GetMoveVector(journey, 0);
assert (nextMoveVector.n1 == 0);
assert (nextMoveVector.n2 == 1);
nextMoveVector = GetMoveVector(journey, 1);
assert (nextMoveVector.n1 == 1);
assert (nextMoveVector.n2 == 0);
nextMoveVector = GetMoveVector(journey, 2);
assert (nextMoveVector.n1 == -1);
assert (nextMoveVector.n2 == -1);
}
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol) {
IntPair updatedRoachPosition;
updatedRoachPosition.n1 = (currentRoachPosition.n1 + moveVector.n1);
updatedRoachPosition.n2 = (currentRoachPosition.n2 + moveVector.n2);
if (updatedRoachPosition.n1 >= maxRow) updatedRoachPosition.n1 = 0;
else if (updatedRoachPosition.n1 < 0) updatedRoachPosition.n1 = maxRow-1;
if (updatedRoachPosition.n2 >= maxCol) updatedRoachPosition.n2 = 0;
else if (updatedRoachPosition.n2 < 0) updatedRoachPosition.n2 = maxCol-1;
return updatedRoachPosition;
}
void testMoveRoach() {
IntPair currentRoachPosition;
IntPair moveVector;
currentRoachPosition.n1 = 0;
currentRoachPosition.n2 = 0;
// case move type '2':
moveVector.n1 = 0;
moveVector.n2 = 1;
currentRoachPosition = MoveRoach(currentRoachPosition, moveVector, 10, 10);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 1);
// One More Time..~
moveVector.n1 = 0;
moveVector.n2 = 1;
currentRoachPosition = MoveRoach(currentRoachPosition, moveVector, 10, 10);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 2);
// Checking Boundary Warp.
int maxCol = 10;
int maxRow = 10;
currentRoachPosition.n1 = 9;
currentRoachPosition.n2 = 9;
moveVector.n1 = 1;
moveVector.n2 = 1;
currentRoachPosition = MoveRoach(currentRoachPosition, moveVector, maxRow, maxCol);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 0);
}
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol) {
assert (roachPosition.n1 < maxRow);
assert (roachPosition.n2 < maxCol);
board[roachPosition.n1*maxCol + roachPosition.n2]++;
}
void testIncrementBoardBlockCount() {
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 0;
}
}
IntPair currentRoachPosition;
currentRoachPosition.n1 = 1;
currentRoachPosition.n2 = 1;
IncrementBoardBlockCount(board, currentRoachPosition, 10, 10);
assert (board[1*10+1] == 1);
}
void Output(int totalMoveCount, int* board, int maxRow, int maxCol) {
OutputMoveCount(totalMoveCount);
OutputBoardStatus(board, maxRow, maxCol);
}
void OutputMoveCount(int totalMaxCount) {
printf ("%d\n", totalMaxCount);
printf ("\n");
}
void OutputBoardStatus(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
printf ("%d ", board[maxCol*i+j]);
}
printf ("\n");
}
}
}}}
여기서 약간 더 나가서. 현재 테스트 코드와 메인 코드가 섞여있어서 상당히 소스가 복잡해보입니다. 그리고 AcceptanceTest 에 대해서는 자동화되지 않았습니다.
=== 마무리 소스 ===
==== main.cpp ====
{{{~cpp
#include "ScheduledWalkTestCase.h"
#include "ScheduledWalk.h"
int main()
{
/* ------------- Acceptance Test -------------
AcceptanceTestAll ();
------------- Acceptance Test ------------- */
AcceptanceTestAll (); // <--- For Acceptance Test
UnitTestAll();
// ScheduledWalkMain(); // <--- Main Routine
return 0;
}
void ScheduledWalkMain() {
InputData inputData;
IntPair startRoachPosition;
int maxRow;
int maxCol;
int* board;
char journey[MAX_JOURNEY_LENGTH]="";
int totalMoveCount = 0;
inputData = Input();
maxRow = inputData.boardSize.n1;
maxCol = inputData.boardSize.n2;
board = CreateBoard(maxRow, maxCol);
startRoachPosition = inputData.roachPosition;
strcpy(journey, inputData.journey);
totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
Output(totalMoveCount, board, maxRow, maxCol);
DestroyBoard(board);
}
}}}
==== ScheduledWalk.h ====
{{{~cpp
#ifndef _SCHEDULEDWALK_H_
#define _SCHEDULEDWALK_H_
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef int BOOL;
typedef char* PSTR;
typedef unsigned int UINT;
const int MAX_JOURNEY_LENGTH = 1000;
typedef struct __IntegerPair {
int n1; // Row 와 관계된것들.
int n2; // Col 와 관계된것들.
} IntPair;
typedef struct __InputDataStructure {
IntPair boardSize;
IntPair roachPosition;
char journey[MAX_JOURNEY_LENGTH];
} InputData;
InputData Input();
IntPair InputBoardSize();
IntPair InputStartRoachPosition();
void InputRoachJourney(PSTR journey);
void InputEndCode();
void InitializeArray(int* board, int maxRow, int maxCol);
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey);
BOOL IsFinished(PSTR journey, int currentPosition, int* board, int maxRow, int maxCol);
BOOL IsJourneyEnd(PSTR journey, int currentPosition);
BOOL IsAllBoardChecked(int* board, int maxRow, int maxCol);
IntPair MoveNext(IntPair currentRoachPosition, PSTR journey, int currentJourneyPosition, int* board, int maxRow, int maxCol);
IntPair GetMoveVector(char* journey, int currentPosition);
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol);
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol);
void Output(int totalMoveCount, int* board, int maxRow, int maxCol);
void OutputMoveCount(int totalMaxCount);
void OutputBoardStatus(int* board, int maxRow, int maxCol);
int _2to1(int row, int col, int maxCol);
int* CreateBoard(int maxRow, int maxCol);
void DestroyBoard(int* board);
#endif
}}}
==== ScheduledWalk.cpp ====
{{{~cpp
#include "ScheduledWalk.h"
int _2to1(int row, int col, int maxCol) {
return maxCol*row+col;
}
int* CreateBoard(int maxRow, int maxCol) {
int* board = new int[maxRow * maxCol];
InitializeArray(board, maxRow, maxCol);
return board;
}
void DestroyBoard(int* board) {
delete board;
}
void InitializeArray(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[_2to1(i,j,maxCol)] = 0;
}
}
}
InputData Input() {
InputData inputData;
inputData.boardSize = InputBoardSize();
inputData.roachPosition = InputStartRoachPosition();
InputRoachJourney(inputData.journey);
InputEndCode();
return inputData;
}
IntPair InputBoardSize() {
IntPair size;
int boardRow;
int boardCol;
scanf("%d%d", &boardCol, &boardRow);
size.n1 = boardRow;
size.n2 = boardCol;
return size;
}
IntPair InputStartRoachPosition() {
IntPair position;
int startRow;
int startCol;
scanf("%d%d", &startRow, &startCol);
position.n1 = startRow;
position.n2 = startCol;
return position;
}
void InputRoachJourney(PSTR journey) {
scanf ("%s", journey);
}
void InputEndCode() {
int endCode;
scanf("%d", &endCode);
}
int ScheduledWalk(int* board, int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey) {
int currentJourneyPosition = 0;
IntPair currentRoachPosition = startRoachPosition;
int totalMoveCount = 0;
IncrementBoardBlockCount(board, currentRoachPosition, maxRow, maxCol);
while (!IsFinished(journey, currentJourneyPosition, board, maxRow, maxCol)) {
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
totalMoveCount++;
currentJourneyPosition++;
}
return totalMoveCount;
}
BOOL IsFinished(PSTR journey, int currentPosition, int* board, int maxRow, int maxCol) {
return IsJourneyEnd(journey, currentPosition) || IsAllBoardChecked(board, maxRow, maxCol);
}
BOOL IsJourneyEnd(PSTR journey, int currentPosition) {
return strlen(journey) <= (UINT)currentPosition;
}
BOOL IsAllBoardChecked(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
if (board[_2to1(i,j,maxCol)] <= 0) return false;
}
}
return true;
}
IntPair MoveNext(IntPair currentRoachPosition, PSTR journey, int currentJourneyPosition, int* board, int maxRow, int maxCol) {
IntPair updatedRoachPosition;
IntPair moveVector = GetMoveVector(journey, currentJourneyPosition);
updatedRoachPosition = MoveRoach(currentRoachPosition, moveVector, maxRow, maxCol);
IncrementBoardBlockCount(board, updatedRoachPosition, maxRow, maxCol);
return updatedRoachPosition;
}
IntPair GetMoveVector(char* journey, int currentJourneyPosition) {
IntPair moveVector;
// vector - row move vector, col move vector.
int MOVE_VECTOR_PAIR_ROW[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int MOVE_VECTOR_PAIR_COL[8] = { 0, 1, 1, 1, 0, -1, -1, -1};
int moveVectorPairIndex = journey[currentJourneyPosition] - '0';
moveVector.n1 = MOVE_VECTOR_PAIR_ROW[moveVectorPairIndex];
moveVector.n2 = MOVE_VECTOR_PAIR_COL[moveVectorPairIndex];
return moveVector;
}
IntPair MoveRoach(IntPair currentRoachPosition, IntPair moveVector, int maxRow, int maxCol) {
IntPair updatedRoachPosition;
updatedRoachPosition.n1 = (currentRoachPosition.n1 + moveVector.n1);
updatedRoachPosition.n2 = (currentRoachPosition.n2 + moveVector.n2);
if (updatedRoachPosition.n1 >= maxRow) updatedRoachPosition.n1 = 0;
else if (updatedRoachPosition.n1 < 0) updatedRoachPosition.n1 = maxRow-1;
if (updatedRoachPosition.n2 >= maxCol) updatedRoachPosition.n2 = 0;
else if (updatedRoachPosition.n2 < 0) updatedRoachPosition.n2 = maxCol-1;
return updatedRoachPosition;
}
void IncrementBoardBlockCount(int* board, IntPair roachPosition, int maxRow, int maxCol) {
assert (roachPosition.n1 < maxRow);
assert (roachPosition.n2 < maxCol);
board[roachPosition.n1*maxCol + roachPosition.n2]++;
}
void Output(int totalMoveCount, int* board, int maxRow, int maxCol) {
OutputMoveCount(totalMoveCount);
OutputBoardStatus(board, maxRow, maxCol);
}
void OutputMoveCount(int totalMaxCount) {
printf ("%d\n", totalMaxCount);
printf ("\n");
}
void OutputBoardStatus(int* board, int maxRow, int maxCol) {
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
printf ("%d ", board[maxCol*i+j]);
}
printf ("\n");
}
}
}}}
==== ScheduledWalkTestCase.h ====
{{{~cpp
#include <assert.h>
#include <stdio.h>
#include "ScheduledWalk.h"
void testScheduledWalk1_1();
void testScheduledWalk1_2();
void testScheduledWalk1_3();
void testScheduledWalk1_4();
void testScheduledWalk2_1();
void testScheduledWalk2_2();
void testScheduledWalk2_3();
void testScheduledWalk2_4();
void testInput();
void testIsFinished();
void testIsJourney();
void testIsAllBoardCheck();
void testMoveNext();
void testGetMoveVector();
void testMoveRoach();
void testIncrementBoardBlockCount();
void testScheduledWalk();
void AcceptanceTestAll();
void UnitTestAll();
void testScheduledWalking(int maxRow, int maxCol, IntPair startRoachPosition, PSTR journey, int expectedTotalMoveCount, int* expectedBoardArray);
void excuteTest (void (*func)(void), PSTR message);
}}}
==== ScheduledWalkTestCase.cpp ====
{{{~cpp
#include "ScheduledWalkTestCase.h"
void testInput() {
InputData inputData;
printf ("Input data ... :");
inputData = Input();
// For Input() Testing....
printf ("Board Size value : %d, %d \n", inputData.boardSize.n1, inputData.boardSize.n2);
printf ("Start Position value : %d, %d \n", inputData.roachPosition.n1, inputData.roachPosition.n2);
printf ("Journey : %s \n", inputData.journey);
}
void testScheduledWalk() {
char journey[MAX_JOURNEY_LENGTH] = "22222";
int maxCol = 10;
int maxRow = 10;
IntPair startRoachPosition;
startRoachPosition.n1 = 0;
startRoachPosition.n2 = 0;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[_2to1(i,j,maxCol)] = 0;
}
}
int totalMoveCount = ScheduledWalk(board, maxRow, maxCol, startRoachPosition, journey);
assert (totalMoveCount == 5);
assert (board[_2to1(0,0,maxCol)] == 1);
assert (board[_2to1(0,1,maxCol)] == 1);
assert (board[_2to1(0,2,maxCol)] == 1);
assert (board[_2to1(0,3,maxCol)] == 1);
assert (board[_2to1(0,4,maxCol)] == 1);
assert (board[_2to1(0,5,maxCol)] == 1);
}
void testIsFinished() {
// Test Data.
char journey[MAX_JOURNEY_LENGTH] = "22";
int currentPosition = 0;
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 0;
}
}
int maxRow = 10;
int maxCol = 10;
int roachPositionRow = 0;
int roachPositionCol = 0;
assert(IsFinished(journey, currentPosition, board, maxRow, maxCol) == false);
}
void testIsJourney() {
char journey[MAX_JOURNEY_LENGTH] = "111122222";
int currentPosition = 1;
assert (IsJourneyEnd(journey, currentPosition) == false);
currentPosition = 9;
assert (IsJourneyEnd(journey, currentPosition) == true);
currentPosition = 10;
assert (IsJourneyEnd(journey, currentPosition) == true);
}
void testIsAllBoardCheck() {
int board[10*10];
for (int i=0;i<10;i++) {
for (int j=0;j<10;j++) {
board[i*10+j] = 1;
}
}
assert (IsAllBoardChecked(board, 10, 10) == true);
board[0] = 0;
assert (IsAllBoardChecked(board, 10, 10) == false);
}
void testMoveNext() {
IntPair currentRoachPosition;
char journey[] = "333";
int maxRow = 10;
int maxCol = 10;
int board[10*10];
for (int i=0;i<maxRow;i++) {
for (int j=0;j<maxCol;j++) {
board[_2to1(i,j,maxCol)] = 0;
}
}
currentRoachPosition.n1 = 9;
currentRoachPosition.n2 = 9;
int currentJourneyPosition = 0;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 0);
assert (currentRoachPosition.n2 == 0);
assert (board[_2to1(0,0,maxCol)] == 1);
currentJourneyPosition = 1;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 1);
assert (currentRoachPosition.n2 == 1);
assert (board[_2to1(1,1,maxCol)] == 1);
currentJourneyPosition = 2;
currentRoachPosition = MoveNext (currentRoachPosition, journey, currentJourneyPosition, board, maxRow, maxCol);
assert (currentRoachPosition.n1 == 2);
assert (currentRoachPosition.n2 == 2);
assert (board[_2to1(2,2,maxCol)] == 1);
}
void testGetMoveVector() {
char journey[MAX_JOURNEY_LENGTH] = "247";
IntPair nextMoveVector;
nextMoveVector = GetMoveVector(journey, 0);
assert (nextM