0

This program changes the position of a chessboard from 0 to 1 when the knight moves from one position to another. If I try the case 0 the program works. Then after the case 0 if I try the case 1 the position changed to 1 is the one that is placed up-left from the case 0 one. Instead it should be the one placed up-up-right from the case 0 one. Why is the output like this?

#include <stdio.h>

int main(){

    int board[8][8]={0};
    int currentRow=4, currentColumn=4;
    int cont=0, moveNumber=0, i, j;

    while(moveNumber>=0 && moveNumber<=7){
        printf("Enter a move: ");
        scanf("%d", &moveNumber);
        cont++;
        switch(moveNumber){
            case 0:
                board[currentRow-1][currentColumn+2]=1;
                break;
            case 1:
                board[currentRow-2][currentColumn+1]=1;
                break;
            case 2:
                board[currentRow-2][currentColumn-1]=1;
                break;
            case 3:
                board[currentRow-1][currentColumn-2]=1;
                break;
            case 4:
                board[currentRow+1][currentColumn-2]=1;
                break;
            case 5:
                board[currentRow+2][currentColumn-1]=1;
                break;
            case 6:
                board[currentRow+2][currentColumn+1]=1;
                break;
            case 7:
                board[currentRow+1][currentColumn+2]=1;
                break;
        }
        for(i=0; i<8; i++){
            for(j=0; j<8; j++){
                printf("%d ", board[i][j]);
            }
            printf("\n");
        }
        printf("Total moves: %d\n",cont);
    }

    return 0;
}
user10198594
  • 79
  • 1
  • 1
  • 6
  • 3
    You never update `currentRow` or `currentColumn`. Is that intentional? – 001 Aug 27 '18 at 14:06
  • 2
    Welcome to stackoverflow.com. Please take some time to read [the help pages](http://stackoverflow.com/help), especially the sections named ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also please [take the tour](http://stackoverflow.com/tour) and [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask). Lastly please read [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Aug 27 '18 at 14:06
  • 1
    I also recommend that you [learn how to debug your programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Some programmer dude Aug 27 '18 at 14:06
  • 2
    Oh, and you should probably have some bounds-checking on your array indexing. Going out of bounds will lead to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). – Some programmer dude Aug 27 '18 at 14:07

3 Answers3

3

The main issue is that you never update currentRow or currentColumn, so all moves happen from their initial values.

Some other notes: You should avoid "magic numbers" - 8 in this case. If you decide to change the size of the array, you have to search through all the code and find the eights and replace them. Use a define or const int.

You should always check the return value from scanf. What if the user types a, for example?

Array bounds checking is needed. What happens when a move takes the knight off the board - and past the bounds of the array?

#include <stdio.h>

// Avoid magic numbers
#define ROWS 8
#define COLS 8

int main(){

    int board[ROWS][COLS] = {0};
    int currentRow = 4, currentColumn = 4;
    int cont = 0, moveNumber = 0, i, j;

    // Loop forever
    while (1) {
        printf("Enter a move: ");
        // Make sure user enters a number
        while (1 != scanf("%d", &moveNumber)) {
            // clear stdin
            int c;
            while((c = getchar()) != '\n' && c != EOF);
            // See https://stackoverflow.com/a/6277391/669576
            // for why fgets/sscanf is a better option than scanf

            // Prompt user for new input
            printf("Enter a valid integer:");
        }
        // Moved this here
        if (moveNumber < 0 || moveNumber > 7) break;
        cont++;
        // Going to use some temp vars to calculate indices
        int tempRow, tempCol;
        // Calc new indices
        switch (moveNumber) {
            case 0:
                tempRow = currentRow - 1;
                tempCol = currentColumn + 2;
                break;
            case 1:
                tempRow = currentRow - 2;
                tempCol = currentColumn + 1;
                break;
            case 2:
                tempRow = currentRow - 2;
                tempCol = currentColumn - 1;
                break;
            case 3:
                tempRow = currentRow - 1;
                tempCol = currentColumn - 2;
                break;
            case 4:
                tempRow = currentRow + 1;
                tempCol = currentColumn - 2;
                break;
            case 5:
                tempRow = currentRow + 2;
                tempCol = currentColumn - 1;
                break;
            case 6:
                tempRow = currentRow + 2;
                tempCol = currentColumn + 1;
                break;
            case 7:
                tempRow = currentRow + 1;
                tempCol = currentColumn + 2;
                break;
        }
        // Make sure we have valid indices
        if (tempRow < 0 || tempCol < 0 || tempRow >= ROWS || tempCol >= COLS) {
            printf("Illegal move\n");
        }
        else {
           // Update the board
           currentRow = tempRow;
           currentColumn = tempCol;
           board[currentRow][currentColumn] = 1;
           // And print
           for(i = 0; i < ROWS; i++){
               for(j = 0; j < COLS; j++){
                   printf("%d ", board[i][j]);
               }
               printf("\n");
           }
           printf("Total moves: %d\n", cont);
        }
    }

    return 0;
}
001
  • 13,291
  • 5
  • 35
  • 66
1

As @Jonhnny Mopp pointed out, you never update currentRow or currentColumn.

So after case 0 you set board[3][6] and after case 1 you set board[2][5].

So the return of case 1 is up-left of case 0.

B.Letz
  • 136
  • 1
  • 16
0

I recommend you write a function TryToMoveKnight(int* x, int* y, int moveNumber) that attempts to move a knight in the desired direction.

You already have eight lines of very similar code, and the more work you need to do to move the piece, the worse it's going to get.

Things the function needs to do:

  1. determine the target coordinates from the moveNumber and current position
  2. verify that the target coordinates are on the board
  3. possibly check for a piece at that position
  4. assign the new coordinates to your variables x and y whose addresses you passed in

This last step was missing from your original code, but checking that the target position is on the board is also going to be essential.

So where you currently have switch(moveNumber)... you would instead call TryToMoveKnight(&currentRow,&currentColumn,moveNumber);

Tim Randall
  • 4,040
  • 1
  • 17
  • 39