Morpion solitaire: Difference between revisions

→‎{{header|C}}: reinterpreted rules when one position can complete multiple lines
m (link to rules)
(→‎{{header|C}}: reinterpreted rules when one position can complete multiple lines)
Line 29:
 
/* 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 = 10;
 
int **board = 0, width, height;
Line 49:
s_dir_nw_se = 1 << 4,
s_newly_added = 1 << 5,
s_current = 1 << 6,
};
 
Line 107 ⟶ 108:
int i, j;
for_i for_j mvprintw(i + 1, j * 2,
(board[i][j] & s_newly_addeds_current) ? "[]X "
: (board[i][j] & s_occupieds_newly_added) ? "*O " : " ");
if : (board[yi][xj] & s_occupied) return? 0"+ " : " ");
refresh();
}
Line 130 ⟶ 132:
{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 */
intvoid add_piecetest_postion(int xy, int yx, intmove_t * test_onlyrec)
{
int m, k, s, dx, dy, xx, yy, dir;
if (board[y][x] |=& s_occupied) return;
if (test_only) {
if (board[y][x] & s_occupied) return 0;
} else
board[y][x] |= s_occupied;
 
for (m = 0; m < 4; m++) { /* 4 directions */
Line 162 ⟶ 163:
if (k != line_len) continue;
 
/* position ok; */irand() to even each option's chance of
* being selectedpicked */
if (test_only) return 1;
if (! irand(++rec->seq))
 
rec->m = m, rec->s = s, rec->x = x, rec->y = y;
/* mark existing pieces for direction taken */
for (k = 0; k < line_len; k++) {
xx = x + dx * (k + s);
yy = y + dy * (k + s);
board[yy][xx] |= s_newly_added;
if (k >= disjoint || k < line_len - disjoint)
board[yy][xx] |= dir;
}
}
}
}
return 0;
 
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, x = -1, y = -1, found = 0;
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
for_i for_j test_postion(i, j, &rec);
/* irand() ensures every legal move gets equal chance of
* being selected */
if (add_piece(j, i, 1) && !irand(++found))
x = j, y = i;
 
/* didn't find any move, game over */
if (x == -1) return 0;
if (test_only!rec.seq) return 10;
 
add_piece(x, y, 0&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;
}
Anonymous user