Una cosa: tienes las coordenadas invertidas, fijate bien en la funcion 'getpos()' que te colgué en el otro post
indice = (numero de columnas * coordenada y) + coordenada x
En tu juego como los valores inician en 1 añado la adaptacion de restar 1 a las coordenadas para basarlas en 0 que es tal como funciona este truco. Tal como lo tienes tu tendrias que cambiar el numero de columnas por el numero de filas, pero entonces se interpreta como que la lista se recorre de arriba a abajo y de izquierda a derecha. Esto es importante porque cuando pintas el tablero estas mostrando las celdas de izquierda a derecha y de arriba a abajo; junto con esto deberas modificar los limites de las coordenadas: las coordenadas x son las horizontales y pueden estar entre 1 y 7 (extremos incluidos), luego las coordenadas y serán las verticales y pueden estar entre 1 y 3 ok? Ahora sabiendo esto y sabiendo que esas coordenadas se convirten en un indice lineal (la matriz simple), no es necesario que pongas limites, con solo comprobar que la posicion basada en las coordenadas esté dentro del rango de la matriz (entre 0 y 20, ambos incluidos).
Algo mas: el bucle infinito para el juego es una buena idea pero está mal diseñado, no podras salir nunca del juego a menos que mates la aplicacion. Tienes que usar un flag de estado, que suena muy profesional pero no es mas que una variable que indica si el ciclo continua o no:
Código:
//lo declaras con las globales
char running;
//lo inicias en 'valores()'
running= 1;
//y lo usas como control del ciclo
while (running) {
...
}
Esto te sirve para controlar desde cualquier sitio de la aplicacion el bucle del juego. Supongamos que añades un menu del tipo 'pulse 1 para nueva partida y 2 para salir', en la condicion de salida simplemente asignas 0 al flag y sales limpiamente. Tambien te sirve para cuando se de la condicion de juego ganado: supongo que pondras algun mensaje del tipo 'quieres otra partida?', si no quieres continuar solo asignas 0 al flag y dejas que lo demas se haga solo.
Aun otra cosa: cuando inicias los valores puedes usar la funcion memset para reiniciar el tablero:
Código:
memset(matriz, ' ', sizeof(matriz));
Una ultima cosa: deberias reorganizar tu codigo para quitar las llamadas recursivas a 'Jug()' en el caso de casilla ocupada. Puedes poner un flag en la funcion que se ejecute mientras no se produjo ningun error, de forma que inicias con flag 1, recoges las coordenadas, pides la posicion, compruebas que es valida, si no es valida lanzas un continue para que reinicie el ciclo, si es valida intentas insertarla, si ya esta ocupada lanzas otro continue, y al final antes de salir del bucle si todo fue bien asignas 0 al flag y dejas que salga limpio, algo asi:
Código:
void Jug(int Njug) {
int pos = 0;
char done = 0;
while(!done) {
//entrada de datos
printf("Jugador %d - Introduce el numero: ", Njug);
scanf("\n%d,%d", &coordx, &coordy);
//comprovacion de coordenadas
pos = getpos(coordx, coordy);
if(pos < 0 || pos >= WORLDSIZE) {
printf("err 1\n");
continue;
}
//comprovacion de casilla
if(!is_empty(pos)) {
printf("err 2\n");
continue;
}
//ejecutas jugada
casillas(pos);
//cambias de jugador
switch_player();
//finalizas el estado de jugada para el player actual
done = 1;
}
}
//esta funcion solo comprueba que este libre
char is_empty(int pos) {
return (matriz[pos] != ' ')? 0 : 1;
}
//y esta cambia el turno
void switch_player() {
pjug = (pjug == 1)? 2 : 1;
}
Es importante que separes cada cosa en varias funciones: esto te proporciona una ventaja a la hora de hacer modificaciones y de encontrar errores.
Saludos
vosk