Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-如何检查谁赢得了一场NxN游戏的O/X?_C_Arrays - Fatal编程技术网

C-如何检查谁赢得了一场NxN游戏的O/X?

C-如何检查谁赢得了一场NxN游戏的O/X?,c,arrays,C,Arrays,我正在做一个抽签游戏 我有一个功能,寻找一个赢家后,每一步是做 功能如下int-won(char-sym) 其中char sym是玩家的字母,例如X或O 我的游戏可以在任何尺寸的3-8板上玩,例如(3z3-8x8) 并且基于名为S[][] 大小也由用户选择,并存储在可验证的整数刻度中(全局可验证) 如何检查玩家是否获胜?(如果行、列或对角线都是同一个字母) 我只是震惊,因为我不知道如何使它适用于任何大小的表 请帮忙 您可以检查水平线、垂直线和对角线。这些线与数组的大小无关。您应该能够在O(n)中

我正在做一个抽签游戏

我有一个功能,寻找一个赢家后,每一步是做

功能如下int-won(char-sym) 其中char sym是玩家的字母,例如X或O

我的游戏可以在任何尺寸的3-8板上玩,例如(3z3-8x8) 并且基于名为S[][] 大小也由用户选择,并存储在可验证的整数刻度中(全局可验证)

如何检查玩家是否获胜?(如果行、列或对角线都是同一个字母) 我只是震惊,因为我不知道如何使它适用于任何大小的表


请帮忙

您可以检查水平线、垂直线和对角线。这些线与数组的大小无关。

您应该能够在
O(n)
中执行此操作,其中
n
是方块数,而不是像传统的3x3那样的
O(1)
,并且只需检查每个方块,就可以不修改结构。你只需要检查一个方向,因为它是可交换的。像这样的,

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

struct Tic {
    unsigned size;
    char board[65];
};

static const char is_valid[] = "XO ";

/** This is a strict parser.
 @param tic Overwriten with stdin on success. On failure, is corrupted.
 @return Success.
 @throws EDOM if the file is not correct, fgets, getc. */
static int load(struct Tic *const tic) {
    char s[10];
    size_t s_len, row = 0;
    int is_size = 0;
    assert(tic);
    errno = 0;
    tic->board[0] = '\0';
    do {
        if(!fgets(s, sizeof s, stdin)) return errno ? 0 : (errno = EDOM, 0);
        if(s_len = strcspn(s, "\n\r\f"), s_len != strspn(s, is_valid))
            return errno = EDOM, 0;
        if(is_size) {
            if(s_len != (size_t)tic->size) return errno = EDOM, 0;
        } else {
            if(s_len < 3 || s_len > 8) return errno = EDOM, 0;
            tic->size = (unsigned)s_len;
            is_size = 1;
        }
        s[s_len] = '\0';
        strcat(tic->board, s);
    } while(++row < tic->size);
    /* Enforce EOF. */
    if(getc(stdin) != EOF) return errno = EDOM, 0; else if(errno) return 0;
    return 1;
}

/** Doesn't do bounds checks; should be inlined. */
static int is_owned(const struct Tic *const tic,
    const size_t x, const size_t y, const char sym) {
    return tic->board[y * tic->size + x] == sym;
}

/** @param tic A valid tic-tac-toe.
 @param sym Either X or O.
 @return Whether sym has won the game. */
static int won(const struct Tic *const tic, const char sym) {
    const size_t size = tic->size;
    size_t x, y;
    int is_x, is_y;
    assert(tic && (sym == 'X' || sym == 'O'));
    for(y = 0; y < size; y++) {
        for(x = 0; x < size; x++) {
            if(!is_owned(tic, x, y, sym)) continue;
            is_x = x < size - 2 ? 1 : 0;
            is_y = y < size - 2 ? 1 : 0;
            /* There are 3 cases. */
            if(is_x && is_owned(tic, y, x + 1, sym)
                && is_owned(tic, y, x + 2, sym)) return 1;
            if(is_y && is_owned(tic, y + 1, x, sym)
                && is_owned(tic, y + 2, x, sym)) return 1;
            if(is_x && is_y && is_owned(tic, y + 1, x + 1, sym)
               && is_owned(tic, y + 2, x + 2, sym)) return 1;
        }
    }
    return 0;
}

int main(void) {
    struct Tic tic;
    if(!load(&tic)) return perror("stdin"), EXIT_FAILURE;
    printf("Xs won? %s.\n", won(&tic, 'X') ? "yes" : "no");
    return EXIT_SUCCESS;
}

对于初学者,您可以尝试查看每一行、每一列和每一对角线。每次,您都会尝试在该行、列或对角线中找到足够长的
X
s或
O
s的连续序列。
static int won_row(const struct Tic *const tic, const size_t y,
    const char sym) {
    const size_t size = tic->size;
    size_t x;
    for(x = 0; x < size; x++) if(!is_owned(tic, x, y, sym)) return 0;
    return 1;
}

static int won_col(const struct Tic *const tic, const size_t x,
    const char sym) {
    const size_t size = tic->size;
    size_t y;
    for(y = 0; y < size; y++) if(!is_owned(tic, x, y, sym)) return 0;
    return 1;
}

static int won_diag(const struct Tic *const tic, const char sym) {
    const size_t size = tic->size;
    size_t x;
    for(x = 0; x < size; x++) if(!is_owned(tic, x, x, sym)) return 0;
    return 1;
}

static int won_anti_diag(const struct Tic *const tic, const char sym) {
    const size_t size = tic->size;
    size_t x;
    for(x = 0; x < size; x++) if(!is_owned(tic, x, size - x - 1, sym)) return 0;
    return 1;
}

/** @param tic A valid tic-tac-toe.
 @param sym Either X or O.
 @return Whether sym has won the game. */
static int won(const struct Tic *const tic, const char sym) {
    const size_t size = tic->size;
    size_t x, y;
    assert(tic && (sym == 'X' || sym == 'O'));
    /* These do a short-circuit evaluation. */
    for(y = 0; y < size; y++) if(won_row(tic, y, sym)) return 1;
    for(x = 0; x < size; x++) if(won_col(tic, x, sym)) return 1;
    return won_diag(tic, sym) || won_anti_diag(tic, sym);
}