Jeu morpion 5 croix

Fermé
Cy - Modifié le 3 avril 2021 à 11:07
 Cy - 5 avril 2021 à 22:23
Bonjour,

J'ai essayé de faire un jeu morpion solitaire (qui consiste d'alligner 5 croix) je n'ai pas réussi , pouvez-vous m'aider s'il vous plait.
voici un exemple de code :
#include <stdlib.h>

#include <unistd.h>

#include <time.h>

/* option: how long a line is. Options probably should have been made into

commandline args, if I were not lazy. Also, if line_len is set to 3,
the game may keep going indefinitely: best use auto mode. */
int line_len = 5;

/* option: whether two lines are allowed to be in the same direction and

connected end to end. Note: two lines crossing are always ok. */
int disjoint = 0;

int **board = 0, width, height;

#define for_i for(i = 0; i < height; i++)

#define for_j for(j = 0; j < width; j++)
enum {
s_blank = 0,
s_occupied = 1 << 0,
s_dir_ns = 1 << 1,
s_dir_ew = 1 << 2,
s_dir_ne_sw = 1 << 3,
s_dir_nw_se = 1 << 4,
s_newly_added = 1 << 5,
s_current = 1 << 6,
};

int irand(int n)
{
int r, rand_max = RAND_MAX - (RAND_MAX % n);
while ((r = rand()) >= rand_max);
return r / (rand_max / n);
}

int alloc_board(int w, int h)
{
int i;
int buf = calloc(1, sizeof(int *) * h + sizeof(int) * h * w);

buf[0] = (int*)(buf + h);
for (i = 1; i < h; i++)
buf[i] = buf[i - 1] + w;
return buf;
}

/* -1: expand low index end; 1: exten high index end */
void expand_board(int dw, int dh)
{
int i, j;
int nw = width + !!dw, nh = height + !!dh;

/* garanteed to fragment heap: not realloc because copying elements
  • is a bit tricky */int **nbuf = alloc_board(nw, nh);dw = -(dw < 0), dh = -(dh < 0);for (i = 0; i < nh; i++) { if (i + dh < 0 || i + dh >= height) continue; for (j = 0; j < nw; j++) { if (j + dw < 0 || j + dw >= width) continue; nbuf[i][j] = board[i + dh][j + dw]; }}free(board);board = nbuf;width = nw;height = nh;}void array_set(int **buf, int v, int x0, int y0, int x1, int y1){ int i, j; for (i = y0; i <= y1; i++) for (j = x0; j <= x1; j++) buf[i][j] = v;}void show_board(){ int i, j; for_i for_j mvprintw(i + 1, j * 2, (board[i][j] & s_current) ? "X " : (board[i][j] & s_newly_added) ? "O " : (board[i][j] & s_occupied) ? "+ " : " "); refresh();}void init_board(){ width = height = 3 * (line_len - 1); board = alloc_board(width, height);array_set(board, s_occupied, line_len - 1, 1, 2 * line_len - 3, height - 2);array_set(board, s_occupied, 1, line_len - 1, width - 2, 2 * line_len - 3);array_set(board, s_blank, line_len, 2, 2 * line_len - 4, height - 3);array_set(board, s_blank, 2, line_len, width - 3, 2 * line_len - 4);}int ofs[4][3] = { {0, 1, s_dir_ns}, {1, 0, s_dir_ew}, {1, -1, s_dir_ne_sw}, {1, 1, s_dir_nw_se}};typedef struct { int m, s, seq, x, y; } move_t;/* test if a point can complete a line, or take that point */void test_postion(int y, int x, move_t * rec){ int m, k, s, dx, dy, xx, yy, dir; if (board[y][x] & s_occupied) return;for (m = 0; m < 4; m++) { /* 4 directions */ dx = ofs[m][0]; dy = ofs[m][1]; dir = ofs[m][2]; for (s = 1 - line_len; s <= 0; s++) { /* offset line */ for (k = 0; k < line_len; k++) { if (s + k == 0) continue; xx = x + dx * (s + k); yy = y + dy * (s + k); if (xx < 0 || xx >= width || yy < 0 || yy >= height) break; /* no piece at position */ if (!(board[yy][xx] & s_occupied)) break; /* this direction taken */ if ((board[yy][xx] & dir)) break; } if (k != line_len) continue; /* position ok; irand() to even each option's chance of being picked */ if (! irand(++rec->seq)) rec->m = m, rec->s = s, rec->x = x, rec->y = y; }}}void add_piece(move_t *rec) { int dx = ofs[rec->m][0]; int dy = ofs[rec->m][1]; int dir= ofs[rec->m][2]; int xx, yy, k;board[rec->y][rec->x] |= (s_current | s_occupied);for (k = 0; k < line_len; k++) { xx = rec->x + dx * (k + rec->s); yy = rec->y + dy * (k + rec->s); board[yy][xx] |= s_newly_added; if (k >= disjoint || k < line_len - disjoint) board[yy][xx] |= dir;}}int next_move(){ int i, j; move_t rec; rec.seq = 0;/* wipe last iteration's new line markers */for_i for_j board[i][j] &= ~(s_newly_added | s_current);/* randomly pick one of next legal moves */for_i for_j test_postion(i, j, &rec);/* didn't find any move, game over */if (!rec.seq) return 0;add_piece(&rec);rec.x = (rec.x == width - 1) ? 1 : rec.x ? 0 : -1;rec.y = (rec.y == height - 1) ? 1 : rec.y ? 0 : -1;if (rec.x || rec.y) expand_board(rec.x, rec.y);return 1;}int main(){ int ch = 0; int move = 0; int wait_key = 1;init_board();srand(time(0));initscr();noecho();cbreak();do { mvprintw(0, 0, "Move %d", move++); show_board(); if (!next_move()) { next_move(); show_board(); break; } if (!wait_key) usleep(100000); if ((ch = getch()) == ' ') { wait_key = !wait_key; if (wait_key) timeout(-1); else timeout(0); }} while (ch != 'q');timeout(-1);nocbreak();echo();endwin();return 0;}

sachant que la premiere fois je l'ai compilé ça marche , mais maint ça me fait des erreurs . merci d'avance.

Configuration: Windows / Chrome 89.0.4389.114
A voir également:

2 réponses

yg_be Messages postés 22692 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 16 avril 2024 1 471
3 avril 2021 à 13:59
bonjour,
quelle erreur obtiens-tu?
merci d'utiliser les balises de code: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
0
re bonjour ;
j'ai ça comme erreur :
morpion.c:46:4: error: subscripted value is neither array nor pointer nor vector
   46 | buf[0] = (int*)(buf + h);
      |    ^
morpion.c:46:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   46 | buf[0] = (int*)(buf + h);
      |          ^
morpion.c:48:8: error: subscripted value is neither array nor pointer nor vector
   48 |     buf[i] = buf[i - 1] + w;
      |        ^
morpion.c:48:17: error: subscripted value is neither array nor pointer nor vector
   48 |     buf[i] = buf[i - 1] + w;    
0
je vais renvoyer le code ici car je n'arrive pas à le modifier :
	
#include <ncurses.h>

#include <stdlib.h>

#include <unistd.h>

#include <time.h>

/* option: la longueur d'une ligne. */
int line_length = 5;

/* option: si deux lignes sont autorisées à être dans la même direction et
 connectées bout à bout. Remarque: deux lignes qui se croisent sont toujours correctes. */

int disjoint = 0;

int **grille = 0, width, height;

enum {
    s_blank        = 0,
    s_occupied    = 1 << 0,
    s_dir_ns    = 1 << 1,
    s_dir_ew    = 1 << 2,
    s_dir_ne_sw    = 1 << 3,
    s_dir_nw_se    = 1 << 4,
    s_newly_added    = 1 << 5,
    s_current    = 1 << 6,
};

int irand(int n)
{
    int r, rand_max = RAND_MAX - (RAND_MAX % n);
    while ((r = rand()) >= rand_max);
    return r / (rand_max / n);
}

int alloc_grille(int w, int h)
{
    int i;
    int buf = calloc(1, sizeof(int *) * h + sizeof(int) * h * w);

buf[0] = (int*)(buf + h);
for (i = 1; i < h; i++)
    buf[i] = buf[i - 1] + w;
return buf;
}

/* -1: élargit l'extrémité inférieure de l'index; 1: exten high index end */

void elargir_grille(int dw, int dh)
{
    int i, j;
    int nlargeur = width + !!dw, nhauteur = height + !!dh;

/* garanti pour fragmenter le tas: pas de réallocation car la copie d'éléments
  est un peu délicate */


int **nbuf = alloc_grille(nlargeur, nhauteur);

dw = -(dw < 0), dh = -(dh < 0);

for (i = 0; i < nhauteur; i++) {
    if (i + dh < 0 || i + dh >= height) continue;
    for (j = 0; j < nlargeur; j++) {
        if (j + dw < 0 || j + dw >= width) continue;
        nbuf[i][j] = grille[i + dh][j + dw];
    }
}
free(grille);

grille = nbuf;
width = nlargeur;
height = nhauteur;
}

void tab_set(int **buf, int v, int x0, int y0, int x1, int y1)
{
    int i, j;
    for (i = y0; i <= y1; i++)
        for (j = x0; j <= x1; j++)
            buf[i][j] = v;
}

void show_grille()
{
    int i, j;
    for(i = 0; i < height; i++)
    {
        for(j = 0; j < width; j++)
        {
            mvprintw(i + 1, j * 2,
            (grille[i][j] & s_current) ? "X "
            : (grille[i][j] & s_newly_added) ? "O "
            : (grille[i][j] & s_occupied) ? "+ " : "  ");
    refresh();
        }
    }
}

void init_grille()
{
    width = height = 3 * (line_length - 1);
    grille = alloc_grille(width, height);

tab_set(grille, s_occupied, line_length - 1, 1, 2 * line_length - 3, height - 2);
tab_set(grille, s_occupied, 1, line_length - 1, width - 2, 2 * line_length - 3);

tab_set(grille, s_blank, line_length, 2, 2 * line_length - 4, height - 3);
tab_set(grille, s_blank, 2, line_length, width - 3, 2 * line_length - 4);
}

int ofs[4][3] = {
    {0, 1, s_dir_ns},
    {1, 0, s_dir_ew},
    {1, -1, s_dir_ne_sw},
    {1, 1, s_dir_nw_se}
};

typedef struct { int m, s, seq, x, y; } move_t;

/* teste si un point peut compléter une ligne, ou prendre ce point */

void test_postion(int y, int x, move_t * rec)
{
    int m, k, s, dx, dy, xx, yy, dir;
    if (grille[y][x] & s_occupied) return;

for (m = 0; m < 4; m++) { /* 4 directions */
    dx = ofs[m][0];
    dy = ofs[m][1];
    dir = ofs[m][2];

    for (s = 1 - line_length; s <= 0; s++) { /* ligne de décalage */
        for (k = 0; k < line_length; k++) {
            if (s + k == 0) continue;

            xx = x + dx * (s + k);
            yy = y + dy * (s + k);
            if (xx < 0 || xx >= width || yy < 0 || yy >= height)
                break;

            /* aucune pièce à la position */
            if (!(grille[yy][xx] & s_occupied)) break;

            /* cette direction prise */
            if ((grille[yy][xx] & dir)) break;
        }
        if (k != line_length) continue;

        /* position ok; irand () pour égaliser la chance de chaque option d'
           être choisit */
        if (! irand(++rec->seq))
            rec->m = m, rec->s = s, rec->x = x, rec->y = y;
    }
}
}

void add_piece(move_t *rec) {
    int dx = ofs[rec->m][0];
    int dy = ofs[rec->m][1];
    int dir= ofs[rec->m][2];
    int xx, yy, k;

grille[rec->y][rec->x] |= (s_current | s_occupied);

for (k = 0; k < line_length; k++) {
    xx = rec->x + dx * (k + rec->s);
    yy = rec->y + dy * (k + rec->s);
    grille[yy][xx] |= s_newly_added;
    if (k >= disjoint || k < line_length - disjoint)
        grille[yy][xx] |= dir;
}
}

int next_move()
{
    int i, j;
    move_t rec;
    rec.seq = 0;

/* effacer les nouveaux marqueurs de ligne de la dernière itération */

for(i = 0; i < height; i++)
{
    for(j = 0; j < width; j++)
    {
         grille[i][j] &= ~(s_newly_added | s_current);
    }
}

/* choisir au hasard l'un des prochains coups légaux */

for(i = 0; i < height; i++)
{
    for(j = 0; j < width; j++)
    {
        test_postion(i, j, &rec);
    }
}

/* n'a trouvé aucun coup, jeu terminé */

if (!rec.seq) return 0;

add_piece(&rec);

if (rec.x == width - 1)
{
 rec.x == 1;
}
else {
      if (rec.x)
    {
        rec.x = 0;
    }
      else {
        rec.x = -1;
    }
}

if (rec.y == height - 1)
{
 rec.y == 1;
}
else {
        if (rec.y)
        {
            rec.y = 0;
        }
        else {
            rec.y = -1;
        }
}

if (rec.x || rec.y) elargir_grille(rec.x, rec.y);
return 1;
}

int main()
{
    int ch = 0;
    int move = 0;
    int wait_key = 1;

init_grille();
srand(time(0));

initscr();
noecho();
cbreak();

do  {
    mvprintw(0, 0, "Move %d", move++);
    show_grille();
    if (!next_move()) {
        next_move();
        show_grille();
        break;
    }
    if (!wait_key) usleep(100000);
    if ((ch = getch()) == ' ') {
        wait_key = !wait_key;
        if (wait_key) timeout(-1);
        else timeout(0);
    }
} while (ch != 'q');

timeout(-1);
nocbreak();
echo();

endwin();
return 0;
}

0
yg_be Messages postés 22692 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 16 avril 2024 1 471
3 avril 2021 à 14:25
il me semble que tes déclarations sont bizarres.
par exemple:
int **nbuf = alloc_board();

mais:
int alloc_board()


par ailleurs:
int buf 

mais
buf[0]
0
Cy > yg_be Messages postés 22692 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 16 avril 2024
Modifié le 3 avril 2021 à 14:26
vous pouvez m'expliquer encore plus? s'il vous plait
0
yg_be Messages postés 22692 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 16 avril 2024 1 471 > Cy
3 avril 2021 à 15:08
ce sont vraiment des concepts de base de la programmation en C.
je pense que tu dois te former avant de faire des programmes compliqués.
d'où vient le code que tu as montré?
0
Cy > yg_be Messages postés 22692 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 16 avril 2024
3 avril 2021 à 15:11
c'est un exemple de solution qu'on m'a envoyé,
0
yg_be Messages postés 22692 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 16 avril 2024 1 471 > Cy
3 avril 2021 à 15:37
je pense que tu devrais commencer par des exercices plus simples. le C est un langage assez complexe à utiliser.
0