/***************************************** ** File: campusid_knight.c ** Author: Your Name ** Date: Today's Date ** Section: 01 ** E-mail: Your Email ** ** This file contains the contents of a program that ** simulates a Knight's tour of a chess board. For a ** given number of simulations, a knight is placed on ** a random square on the board, then makes as many ** random moves as possible until no more are available, ** while never landing on the same square twice. ** After the given number of simulations are complete, ** the board with the best run is printed and the average ** number of moves per run are printed. ** ** Other files required are: N/A ***********************************************/ #include #include #include #define TOTAL_RUNS 10000 #define BOARD_WIDTH 8 #define RANDOM_SEED time(NULL) int GenerateRandomXShift(); int GenerateRandomYShift(int x); void ClearBoard(int chessBoard[][BOARD_WIDTH]); void PrintBoard(int chessBoard[][BOARD_WIDTH]); void CopyBoard(int src[][BOARD_WIDTH], int dest[][BOARD_WIDTH]); int HasMoreMoves(int x, int y, int chessBoard[][BOARD_WIDTH]); int IsValidMove(int x, int y, int chessBoard[][BOARD_WIDTH]); /* NOTE: You may NOT modify the main function in any way! */ int main() { int currentX; /* Our Knight's current X coordinate */ int currentY; /* Our Knight's current Y coordinate */ int nextX; /* Our Knight's proposed next X coordinate */ int nextY; /* Our Knight's proposed next Y coordinate */ int moveNumber; /* A counter variable for our move */ int randomXShift; /* A temporary variable to hold the random X shift */ int runNum; /* A counter variable for our simulation number */ int chessBoard[BOARD_WIDTH][BOARD_WIDTH]; /* Our current Chess Board */ int bestRun[BOARD_WIDTH][BOARD_WIDTH]; /* The chess board of the best run */ int totalMoves = 0; /* A counter for the total moves the Knight has made */ int totalMovesInBestRun = 0; /* A counter for the total moves in the best run */ /* Seed the Random Number Generator */ srand(RANDOM_SEED); /* Run a configurable number of sumulations, counted by runNum */ for(runNum = 0 ; runNum < TOTAL_RUNS ; runNum++) { /* Reset our moveNumber variable and clear the chessboard */ moveNumber = 0; ClearBoard(chessBoard); /* Randomly select our start position */ currentX = rand() % BOARD_WIDTH; currentY = rand() % BOARD_WIDTH; chessBoard[currentX][currentY] = moveNumber++; /* While the Knight has more moves available... */ while (HasMoreMoves(currentX, currentY, chessBoard)) { /* Randomly select a next move until we find a valid one. */ do { randomXShift = GenerateRandomXShift(); nextX = currentX + randomXShift; nextY = currentY + GenerateRandomYShift(randomXShift); } while (!IsValidMove(nextX, nextY, chessBoard)); /* We found a valid next move. Move our piece there. */ currentX = nextX; currentY = nextY; chessBoard[currentX][currentY] = moveNumber++; } /* We incremented one too many moves above, so remove one. */ moveNumber--; /* Increment our total number of moves */ totalMoves += moveNumber; /* If this is our new best run... */ if(moveNumber > totalMovesInBestRun) { /* Set our new value for total moves in best run */ totalMovesInBestRun = moveNumber; /* Copy the moves from our current board onto the best run board */ CopyBoard(chessBoard, bestRun); } } /* Print the board of the best run */ printf("Total simulations run: %d\n", TOTAL_RUNS); printf("Best run move list:\n"); PrintBoard(bestRun); /* Print the total moves in the best run, and the average moves per run. */ printf("Total moves in best run: %d\n", totalMovesInBestRun); printf("Average moves per run: %lf\n", ((double)totalMoves / TOTAL_RUNS)); return 0; } /************************************************ ** GenerateRandomXShift -- ** Generates a random X shift for the knight to move. ** Inputs: None ** Output: A valid random X space shift (-2, -1, 1, 2) ** Notes : DO NOT MODIFY THIS FUNCTION! **************************************************/ int GenerateRandomXShift() { return ((rand() % 2) + 1) * (rand() % 2 ? 1 : -1); } /************************************************ ** GenerateRandomYShift -- ** Generates a random Y shift for the knight to move. ** Inputs: A random X shift ** Output: A valid random Y space shift (-2, -1, 1, 2) ** based on the X shift. For example, if x ** shift is -1, valid Y shifts include 2 and -2. ** Notes : DO NOT MODIFY THIS FUNCTION! **************************************************/ int GenerateRandomYShift(int x) { return ((x == 1 || x == -1) ? 2 : 1) * (rand() % 2 ? 1 : -1); } /* ************* DO NOT REMOVE THIS LINE *******************/ /* ****** DO NOT MODIFY ANYTHING ABOVE THIS LINE ***********/ /************************************************ ** ClearBoard -- ** This function sets the value of each cell in ** a two-dimensional array to -1. ** Inputs: A two-dimensional array representing a ** chess board. ** Output: No return value, however the given array ** is updated such that each cell is assigned ** the value -1. **************************************************/ void ClearBoard(int chessBoard[][BOARD_WIDTH]) { /* Your code here! */ } /************************************************ ** PrintBoard -- ** This function neatly prints the values of a ** two-dimensional array. ** Inputs: A two-dimensional array representing a ** chess board. ** Output: No return value, however the given array ** is printed neatly to the screen. **************************************************/ void PrintBoard(int chessBoard[][BOARD_WIDTH]) { /* Your code here! */ } /************************************************ ** CopyBoard -- ** This function copies all the values in the src ** array into the dest array. ** Inputs: src - A two-dimensional array representing ** the source chess board to be copied. ** dest - A two-dimensional array representing ** the destination chess board to be copied to. ** Output: No return value, however the source array ** values are copied to the destination array. **************************************************/ void CopyBoard(int src[][BOARD_WIDTH], int dest[][BOARD_WIDTH]) { /* Your code here! */ } /************************************************ ** HasMoreMoves -- ** This function evaluates whether a knight has ** any available moves on a given chessboard assuming ** the knight is located at the given x and y coordinates. ** Inputs: x - The current x position of the knight on the ** chess board. ** y - The current y position of the knight on the ** chess board. ** chessBoard - A two-dimensional array representing ** the current chess board to be analyzed. ** Output: Returns non-zero if the knight has at least ** one available move. Returns 0 if there ** are no remaining moves available for the knight. **************************************************/ int HasMoreMoves(int x, int y, int chessBoard[][BOARD_WIDTH]) { /* Your code here! */ } /************************************************ ** IsValidMove -- ** This function evaluates whether a knight can ** move to a given x,y coordinate pair on a given ** chess board. A knight cannot move to a space ** that has already been used and cannot move outside ** the chessboard. ** Inputs: x - The proposed x position of the knight on the ** chess board. ** y - The proposed y position of the knight on the ** chess board. ** chessBoard - A two-dimensional array representing ** the current chess board to be analyzed. ** Output: Returns non-zero if the proposed move is valid. ** Returns 0 if the move is not valid (i.e. the ** knight has already landed on the proposed space ** OR the proposed space is outside of the bounds ** of the chess board. **************************************************/ int IsValidMove(int x, int y, int chessBoard[][BOARD_WIDTH]) { /* Your code here! */ }