UPDATE: Thanks a lot M Oehm for your awesome answer, really helped me a lot. That struct pos moves is really helpful, haven't studied it yet on class. Im working on a fully solution of my code adding yours as a bone on the programs skeleton. Already fixed the problem of updating fila and columna, the random choice and the switch from 0 to 7 without the ' ' because they're not characters as you and davidc pointed. My program still have some problems which im working on before posting the fully operational program here. I'll update the code tomorrow if not today. Thank you all for your comments and solutions, and M oehm for the time you spent making that wonderful answer.
------------------------------------------------------------------------------------------------------------------------------------
UPDATE 2: Finnished it, made some little changes on M Oehm code and instead of putting manually the first location of the horse i used my previous PosicionCaballo(). Had to delete the code of the MoverCaballo() which had a Switch with 8 possible moves which was set by a random number because i couldn't make it work (i guess the main problem was that part because already was a mess).
Now the program with the code below should ask the user for the initial position of the horse, after that the screen will print a 10x10 table filled with 0's (free spaces), fill it with 1's (taken spaces which did the horse moving randomly) and when it finnishes display a message on how many positions did it take.
COORD cxy;
#define posicion(x,y) {(cxy.X)= (x);(cxy.Y)= (y); SetConsoleCursorPosition((GetStdHandle(STD_OUTPUT_HANDLE)), (cxy) );}
int ajedrez[10][10];
int fila, columna;
void GenerarTablero(int m[10][10]){
int i, j;
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
m[i][j] = 0;
}
}
}
GenerarTablero makes the chess board and fills it with 0's.
Global are fila (row) and columna (column) the parts of the ajedrez[10][10]
ajedrez[10][10] is the chess table in a 10x10 size.
void PosicionCaballo(int m[10][10]){
printf("Fila: ");
scanf_s("%d", &fila);
printf("Columna: ");
scanf_s("%d", &columna);
printf("\n");
m[fila][columna] = 2;
system("cls");
}
PosicionCaballo does ask the user for the initial position of the horse and puts the horse on the table.
Example: Row: 5 Column: 5
int horse(int y, int x)
{
int visited[SIZE][SIZE] = { { 0 } };
int count = 0;
if (on_board(y, x) == 0) return -1;
/* Set starting position */
visited[y][x] = 1;
while (1) { /* Infinite loop - must use break */
int poss[8]; /* Possible moves */
int nposs = 0; /* Actual length of poss */
int i, k = 1;
for (i = 0; i < 8; i++) {
int xx = x + moves[i].x;
int yy = y + moves[i].y;
if (on_board(yy, xx) && visited[yy][xx] == 0) {
poss[nposs++] = i;
}
}
/* No more valid moves: return */
if (nposs == 0){
posicion(0, 11);
printf("El tablero se ha bloqueado con ");
return count;
}
/* pick one of the valid moves */
i = poss[rand() % nposs];
x = x + moves[i].x;
y = y + moves[i].y;
/* update horse's position */
visited[y][x] = 1;
count++;
/* print position */
posicion(y, x);
printf("1");
}
return -1; /* Should never be reached */
}
void MostrarMapa(int m[10][10]){
int i, j;
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
printf("%d", ajedrez[i][j]);
}
printf("\n");
}
}
MostrarMapa only prints the chess table on the screen.
int main(void){
int n;
srand(time(NULL));
GenerarTablero(ajedrez);
PosicionCaballo(ajedrez);
MostrarMapa(ajedrez);
n = horse(fila, columna);
posicion(31, 11);
printf("%d movimientos\n", n);
getch();
return 0;
}
and then my main which im using all the functions stated upside.
Thank you very much in advance for your help guys :).
I guess that your assignment is about finding a valid path that visits all squares. Your code tries to find one random path.
Your code has several errors:
ajedrez[fila - 2][columna - 1]
, you don't check whether fila - 2
or columna - 1
are really valid indices of your chess board. If you access invalid indices, way -1 or 11, you invoke undefined behaviour.fila
and columna
, that is: You don't move your horse.rand() % 8
, which yields numbers from 0 to 7. (David has already pointed this out in a comment.)case 0:
, not case '0':
.Your eight switch cases manifest another flaw: You have the same repeated code eight times over. The only difference is the jump pattern. Such a set-up lends itself to either writing a function where you pass the row and columns distance to jump or to using an array of possible jump patterns.
Your code should instead do something like this for each move:
Below is an example implementation that uses an array of jump patterns. It will give one random path. You can adapt this code to your problem.
#include <stdlib.h>
#include <stdio.h>
#include <time.h> /* for time() */
#define SIZE 10 /* Fixed board size */
struct pos {
int x, y;
};
struct pos moves[8] = { /* Jump patterns */
{1, 2},
{2, 1},
{2, -1},
{1, -2},
{-1, -2},
{-2, -1},
{-2, 1},
{-1, 2}
};
/*
* Is position (y, x) a valid board coordinate?
*/
int on_board(int y, int x)
{
if (x < 0 || x >= SIZE) return 0;
if (y < 0 || y >= SIZE) return 0;
return 1;
}
/*
* Move the horse randomly, starting from (y, x). Print the
* visited fields and return the number of moves made or
* -1 if an error occurs.
*/
int horse(int y, int x)
{
int visited[SIZE][SIZE] = {{0}};
int count = 0;
if (on_board(y, x) == 0) return -1;
/* Set starting position */
visited[y][x] = 1;
printf("%c%d, ", 'A' + y, x + 1);
while (1) { /* Infinite loop - must use break */
int poss[8]; /* Possible moves */
int nposs = 0; /* Actual length of poss */
int i;
for (i = 0; i < 8; i++) {
int xx = x + moves[i].x;
int yy = y + moves[i].y;
if (on_board(yy, xx) && visited[yy][xx] == 0) {
poss[nposs++] = i;
}
}
/* No more valid moves: return */
if (nposs == 0){
printf("whoa!\n");
return count;
}
/* pick one of the valid moves */
i = poss[rand() % nposs];
x = x + moves[i].x;
y = y + moves[i].y;
/* update horse's position */
visited[y][x] = 1;
count++;
/* print position */
printf("%c%d, ", 'A' + y, x + 1);
}
return -1; /* Should never be reached */
}
int main()
{
int n;
srand(time(NULL));
n = horse(3, 6);
printf("%d moves\n", n);
return 0;
}