Некорректно работает перемещение по полю 8х8 клавишами W,A,S,D

Столкнулся с непонятным пока для меня поведением вложенных массивов в Си. цифра 1 должна перемещаться по полю 8х8 клавишами W,A,S,D, но есть проблемка

Вообщем вверх, вниз, вправо - работает, но вот при движении влево происходят странные вещи. может кто в курсе, где тут собака зарыта?

/*
Author:
Functionality: We have game field 8x8 as a checkerboard, all cells are 0 as default, 1 is piece (cell:[0][0] at start)
We can move the piece(w-up,s-down,a-left,d-right). If the piece leaves the playing field, it automatically appears from another side.
*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void setField(char gameField[][9], int *posX, int *posY);
void setPicePosition(char gameField[][9],int *posX, int *posY);

void setField(char gameField[][9], int *posX, int *posY)
{   //The 'gameField[][]' second index must contain the number of elements.
    //otherwise the compiler does not know how much to change the offset when the first index is incremented/decremented
    char ch0 = '0';

    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            gameField[i][j] = ch0;//default = 0
        }
    }

    setPicePosition(gameField,posX,posY);
    system("cls");//clear screen(Just for Windows)

    for(int i=0;i<8;i++)
    {
        printf("----------");

        for(int j=0;j<8;j++)
        {
            printf("%c",gameField[i][j]);
        }

        printf("----------");

        printf("\n");
    }
    printf( "Press 'w'-up, 's'-down, 'a'-left, 'd'-right or 'x'-to EXIT\n" );
}

void setPicePosition(char gameField[][9],int *posX, int *posY)
{
    char ch1 = '1';
    gameField[*posY][*posX]=ch1;
}

int main()
{
    char gameField[9][9];
    int posX = 0;
    int posY = 0;
    int c;

    setField(gameField,&posX,&posY);

    while(c!=120)//120 is ASCII for 'x'
    {
        c = getch();//reads chars from console-input
        switch(c)
        {
            case 120:
                exit(1);
            case 119:
                posY = (posY-1)%8;//%8, because we want to stay in range between 0 and 7
                break;
            case 115:
                posY = (posY+1)%8;
                break;
            case 97:
                posX = (posX-1)%8;
                break;
            case 100:
                posX = (posX+1)%8;
                break;
        }

        setField(gameField,&posX,&posY);
    }


    return 0;
}

Ответы (1 шт):

Автор решения: AlexGlebe

Функция остатка от деления возвращает неожиданные числа при делении отрицательного числа.

x   | -4 -3 -2 -1 0 1 2 3 4 
x%3 | -1  0 -2 -1 0 1 2 0 1 

Помогает добавление ещё одного делителя, чтобы остаток возвращал положительное.

posX = (posX +8 -1)%8;

posY = (posY +8 -1)%8;

В вашем коде индексы становятся отрицательными и выходят за пределы массива, что и даёт неожиданные результаты.

→ Ссылка