Попытка сравнить символы из матрицы C

Я пытаюсь сравнить символы из матрицы, но не добавляет никаких значений, и я не знаю, почему

так вот мой код:

#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>

#define MAX_LINES 1000
#define MAX_LINE_LENGTH 1000

//---------------------
//READING & WRITING
//---------------------

char *ints_new(int n)
{
    return (char *) malloc(n * sizeof(char));
} 

char **ints2_new(int rows, int cols)
{
    char **result = (char **) malloc(rows * sizeof(char *));
    char *p = ints_new(rows * cols);
    for (int i = 0; i < rows; i++, p += cols)
        result[i] = p;
    return result;
} 


int str_readline(FILE *f, char *s) 
{   
    int result = EOF; 
    char *p = fgets(s, INT_MAX, f); 
    if (p != NULL) 
    { 
        result = (int) strlen(s); 
        if (result > 0 && s[result-1] == '\n') 
            s[--result] = '\0'; 
    } 
    return result; 
} 

char *str_dup(const char *s) 
{ 
    char *result = (char *) malloc(strlen(s) + 1); 
    strcpy(result, s); 
    return result; 
} 

int strings_read(FILE *f, char **a) 
{ 
    int result = 0; 
    char line[MAX_LINE_LENGTH + 2]; 
    while (str_readline(f, line) != EOF) 
        a[result++] = str_dup(line); 
    return result; 
}  
// --------------------
//    Problema A
// --------------------

void values_to_m(char **m, int rows, int cols, char **readings)
{
    int i;
    int j;
    int k = 0;
    int l = 0;
    for(i = 0; i < rows; i++)
    {
        for(j = 0; j < cols; j++)
        {
            m[i][j] = readings[k][l];
            l++;
        }
        k++;
        l = 0;
    }
}

int count_points(char **m, int i, int j, int rows, int cols)
{
    int result = 0;
    if(i < rows-2)
    {
        if(m[i][j] == m[i+1][j] == m[i+2][j])
            result++;
        if(j < cols-2)
        {
            if(m[i][j] == m[i][j+1] == m[i][j+2])
                result++;
            if(m[i][j] == m[i+1][j+1] == m[i+2][j+2])
                result++;
        }
        if(j > 1)
        {
            if(m[i][j] == m[i+1][j-1] == m[i+2][j-2])
                result++;
        }
    }
    else
    {
        if(j < cols-2)
        {
            if(m[i][j] == m[i][j+1] == m[i][j+2])
                result++;
        }
    }
    printf("%d\n", result);
    return result;
}

void points(char **m, int rows, int cols)
{
    int i;
    int j;
    int player1 = 0; //O's
    int player2 = 0; //X's
    for(i = 0; i < rows; i++)
    {
        for(j = 0; j < cols; j++)
        {
            int count;
            count = count_points(m, i, j, rows, cols); //counts points
            if (m[i][j] == 'X') //if values i'm couning are X, points go to player 2
                player2 += count;
            else if(m[i][j] == 'O') //if O go to player 1
                player1 += count;
        }
    }
    printf("%d %d\n", player1, player2);
}

// --------------------
// --------------------

void test_problem_A()
{
    char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char) + 1);
    int rows = strings_read(stdin, readings); //to read from console
    int cols = strlen(readings[0]);

    printf("%d\n%d\n", rows, cols); //just to make sure nr of rows and cols is right
    char **m = ints2_new(rows, cols); //create matrix

    values_to_m(m, rows, cols, readings); //put the values to matrix
    points(m, rows, cols); //calculate points

    ints2_printf(m, rows, cols, "%c");
}

// --------------------
// --------------------

int main(int argc, char **argv)
{
    test_problem_A();
    return 0;
}

Моя программа должна прочитать кучу «X», «O» и «.».

Если в ряду выпало 3 символа «Х» (по вертикали, горизонтали или диагонали), игрок 2 получает 1 очко, если то же самое происходит с «О», игрок 1 получает 1 очко. '.' не считайте очки.

моя матрица должна была иметь минимум 3 строки и столбца и максимум 1000 строк и столбца.

пример: если я введу в консоль

XXO
OXO
OXO

игроки 1 и 2 получают по 1 очку

если я поставлю:

XXXXXO  //(int this line Player 2 get 3 points because there are 3 times 3 X in a row)
OXOXOO
OXOOXO
OXOXOO

игрок 1 получает 5 очков, а игрок 2 получает 6 очков

Итак, моя проблема заключается в том, что функция «count_points» не считает баллы, когда я печатаю «результат», она всегда дает мне 0 баллов.

Разве я не могу сравнить 2 символа, если они принадлежат матрице?

Спасибо


person Dário Hermann    schedule 01.05.2015    source источник


Ответы (2)


В count_points вы пытаетесь сравнить три значения с помощью таких выражений, как

if (a == b == c) ...

Это не делает то, что вы думаете. Вы рассматриваете это как сравнение в математической нотации, но C интерпретирует это как:

if ((a == b) == c) ...

Сравнение a == b дает либо 0, либо 1. Затем этот результат сравнивается с c.

Вы можете переписать желаемое выражение как

if (a == b && b == c) ...

Учитывая, что ваши a, b и c являются составными выражениями, вы можете написать для этого небольшую функцию:

static int eq3(int a, int b, int c)
{
    return (a == b && b == c);
}

int count_points(char **m, int i, int j, int rows, int cols)
{
    int result = 0;

    if (i < rows-2) {
        if (eq3(m[i][j], m[i+1][j], m[i+2][j]))
            result++;

        if (j < cols - 2) {
            if (eq3(m[i][j], m[i][j+1], m[i][j+2]))
                result++;
            if (eq3(m[i][j], m[i+1][j+1], m[i+2][j+2]))
                result++;
        }

        if (j > 1) {
            if (eq3(m[i][j], m[i+1][j-1], m[i+2][j-2]))
                result++;
        }
    } else {
        if (j < cols-2) {
            if (eq3(m[i][j], m[i][j+1], m[i][j+2]))
                result++;
        }
    }

    return result;
}

Что касается распределения вашей матрицы, см. ответ Алка. Ваш метод распределения - один char ** для строк, а затем дублирование строк для данных строки, может оставить вас с рваным массивом, и вы не можете безопасно получить доступ к m[j + 1][i] в некоторых случаях, когда i является допустимым индексом для строки j, но не для строки j + 1.

person M Oehm    schedule 01.05.2015
comment
Я чувствую себя тупым, это не первый раз, когда эта ошибка происходит со мной. Спасибо - person Dário Hermann; 01.05.2015

Для начала здесь нужно выделить указатели на char:

char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char) + 1);

So do so:

char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char*) + 1);

или еще лучше:

char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof *readings + 1);
person alk    schedule 01.05.2015
comment
Да, хороший улов. Я предполагаю, однако, что он хочет только MAX_LINES, потому что затем он назначает выделенную строку каждому указателю. (Я понятия не имею, для чего нужен +1; он не добавляет NULL дозорного в конце.) - person M Oehm; 01.05.2015