mardi 28 novembre 2017

Internal compiler error at runtime CLion

I am getting a weird error when running my program inside CLion. I checked my code and couldn't find any open braces or semicolon missing or hanging. I have 1 class (.cpp and .h) and a main.cpp. It's a really small program but I can't figure out what's wrong. The error I get is as follow

internal compiler error: in finish_expr_stmt, at cp/semantics.c:677 xword::xword(map words) {

This application has requested the Runtime to terminate it in an unusual way.

Please contact the application's support team for more information. C:\Users\marti\CLionProjects\crossword\xword.cpp:8:37: internal compiler error: Aborted

This application has requested the Runtime to terminate it in an unusual way.

Please contact the application's support team for more information. g++.exe: internal compiler error: Aborted (program cc1plus)

Please submit a full bug report, with preprocessed source if appropriate.

xword.cpp

#include <iostream>
#include <sstream>
#include "xword.h"
//Constructor que acepta las palabras con su orientacion en un mapa como parametro y basicamente
//crea e inicializa la matriz
//ademas llena los espacios vacios con letras al azar

xword::xword(map<string, char> words) {
    //Inicializamos la matr9z
    grid = new char*[SIZE];
    for(int x = 0;x < SIZE;x++){
        grid[x] = new char[SIZE];
    }

    //Se valida las palabras y su orientacion
    //en caso sean validas se añaden a la lista
    //sino son descartadas
    for(pair<string, char> w : words){
        if(validate_word(w.first, w.second)){
            add_word(w.first, w.second);
        }
    }

    srand(NULL);

}
bool xword::validate_word(string word, char pos) {
    //Validacion de longitud
    if(word.length() > 10)
        return false;
    //Validacion de que no este repetida
    for(const auto iter : words_i){
        if(iter.first.compare(word) == 0)
            return false;
    }

    //Validacion de espacion para la orientacion deseada
    for(int x = 0;x < SIZE;x++){
        for(int y = 0;y < SIZE;y++){
            char tmp  = grid[x][y];
            if(tmp != 0){
                break;
            }
            if(!has_space(word.size(), pos, x, y))
                return false;
        }
    }

    //TODO verificar caracteres validos


    return true;
}
//Imprime la matriz
void xword::prnt_grid() {
    for(int x = 0;x < SIZE;x++){
        for(int y = 0;y < SIZE;y++){
            cout << grid[x][y] << " ";
        }
        cout << endl;
    }
}
//Añadir una palabra al mapa miembro
bool xword::add_word(string word, char pos){
    if(validate_word(word, pos)){
        words_i[word] = pos;
        int x1, y1, x2, y2;
        get_espacio_libre(word.size(), pos, x1, y1, x2, y2);

        for(int x = x1, count = 0;x <= x2;x++){
            for(int y = y1;y < y2;y++){
                grid[x][y] = word[count];
                count++;
            }
        }
        return true;
    }
    return false;
}

//Verifica si ya se han acabado las palabras para encontrar
bool xword::ganado(){
    vector<string> keys;
    for(pair<string, char>& par : words_i){
        keys.push_back(par.first);
    }
    return keys.size() == p_encontradas.size();
}

//Añade una palabra a la lista de encontradas
void xword::encontrar_palabra(string palabra) {
    p_encontradas.push_back(palabra);

}
//Itera sobre todas las palabras encontradas y retorna true si la encuentra
bool xword::is_p_encontrada(string palabra) {
    for (string p : p_encontradas){
        if(p == palabra)
            return true;
    }
    return false;
}

//Busca letras entre las coordenadas propuestas y retorna en forma de palabra
string xword::palabra_at(int x1, int y1, int x2, int y2){
    stringstream ss;
    for(;x1 < x2;x1++){
        for(;y1 < y2;y1++){
            ss << grid[x1][y1];
        }
    }
    return ss.str();
}

//Verificacion de que la matriz tenga espacio en la orientacion
//dadas las posiciones x e y
bool xword::has_space(char word_size, char orientation, char xpos, char ypos) {
    if(orientation == 'V')
    {
        for(int x = xpos;x < word_size;x++){
            char tmp = grid[x][ypos];
            if(tmp != 0)
                return false;
        }
    }
    else if(orientation == 'H')
    {
        for(int y = ypos;y < word_size;y++){
            char tmp = grid[xpos][y];
            if(tmp != 0)
                return false;
        }
    }
    return true;
}

//Consigue el primer espacion libre para una palabra de len word_size y orientacion definida
void xword::get_espacio_libre(char word_size, char orientation, int& x1, int& y1, int& x2, int& y2){
    for(char x = 0;x < SIZE;x++){
        for(char y = 0;y < SIZE;y++){
            if(grid[x][y] == 0 && has_space(word_size, orientation, x, y))
            {
                if(orientation == 'V'){
                    x1 = x;
                    y1 = y;
                    x2 * x+word_size;
                    y2 = y;
                    return;
                }
                else{
                    x1 = x;
                    y1 = y;

                    x2 = x;
                    y2 = y+word_size;
                    return;
                }
            }
        }
    }
}

xword.h

#include <string>
#include <vector>
#include <map>

//Tamaña predefinido de matriz eg. 10x10
#define SIZE 10

#ifndef CROSSWORD_XWORD_H
#define CROSSWORD_XWORD_H


using namespace std;

class xword {
private:

    //Mapa de las palabras y orientaciones
    map<string, char> words_i;

    //Palabras encontradas
    vector<string> p_encontradas;

    //Matriz
    char** grid = nullptr;

    //Caracteres permitidos
    char ls[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    //Validar palabra y orienta
    bool validate_word(string word, char pos);

    //Validar espacion en matriz
    bool has_space(char word_size, char orientation, char xpos, char ypos);

    //Retornar coordenadas de espacio libre en los numeros que se le pasan
    void get_espacio_libre(char word_size, char orientation,  int& x1, int& y1, int& x2, int& y2);

public:
    //Retorna true si ya se gano el juego
    bool ganado();
    //Añade a palabras encontradas
    void encontrar_palabra(string palabra);
    //Retorna true si la palabra ya se ha encontrado
    bool is_p_encontrada(string palabra);
    //Retorna la palabra entre 2 coordenadas
    string palabra_at(int x1, int x2, int y1, int y2);
    //Imprime matriz
    void prnt_grid();
    //Añade palabra al mapa
    bool add_word(string word, char pos);
    //Constructor que deberia ser usado
    xword(map<string, char> words);

};


#endif //CROSSWORD_XWORD_H

main.cpp

#include <iostream>
#include <assert.h>
#include "xword.h"

#define VERTICAL 'V'
#define HORIZONTAL 'H'

using namespace std;

xword* xw;
map<string, char> lista_palabras =
        {
                make_pair("cuadro", VERTICAL),
                make_pair("mesa", HORIZONTAL),
                make_pair("palabra", VERTICAL),
                make_pair("raton", HORIZONTAL),
                make_pair("poste", VERTICAL),
                make_pair("comida", HORIZONTAL),
                make_pair("letrero", VERTICAL),
                make_pair("usar", HORIZONTAL),
                make_pair("dos", VERTICAL),
                make_pair("quince", HORIZONTAL)
        };

void ingresar_palabras(){
    map<string, char> words;
    string inpt;
    cout << "Ingresa la palabra seguida de un espacio y una letra indicando la orientacion deseada " << endl;
    cout << "o un 0(cero) para que sea al azar eg( palabra (V, vertical, v, VERTICAL) )" << endl;
    //Mientras se siga alimentando palabras y orientaciones el programa sigue corriendo
    while(getline(cin, inpt)){
        if(inpt.empty())
            break;
        string name;
        char orient;

        string tmp = inpt.substr(inpt.find(" "));
        name = inpt.substr(0, inpt.find(" "));
        //Asignamos la orientacion basado en lo que se encuentra despues de la palabra inicial al macro VERTICAL o HORIZONTAL
        orient = (tmp.compare("v") || tmp.compare("V") || tmp.compare("vertical") || tmp.compare("VERTICAL")) ? VERTICAL :
                 (tmp.compare("h") || tmp.compare("H") || tmp.compare("horizontal") || tmp.compare("HORIZONTAL")) ? HORIZONTAL :
                 HORIZONTAL;

        words[name] = orient;
    }
    lista_palabras = words;
}
bool in_lista(string palabra){
    for(pair<string, char> pal : lista_palabras){
        if(pal.first == palabra) {
            return true;
        }
    }
    return false;
}
bool main_loop(){
    bool inicia = true;
    while(inicia){
        xw->prnt_grid();
        int x1, y1, x2, y2;
        cout << "Elige una posicion x y";
        cin >> x1, y1;
        cout << "Elige otra posicion x y";
        cin >> x2, y2;
        string palabra = xw->palabra_at(x1, y1, x2, y2);
        if(in_lista(palabra) ){
            cout << "Encontraste una palabra!";
            xw->encontrar_palabra(palabra);
            if(xw->ganado()) {
                cout << "Ganaste el juego!";
                break;
            }
            continue;
        }
        cout << "Esa palabra no es valida, sigue intentando";

    }
}

int main() {
    //Eliges usar la lista que ua hay de palabras o ingresar una nueva lista
    int opt;
    cout << "Desea ingresar palabras (0) o usar la lista predetermina de palabras (1): ";
    cin >> opt;

    //Se asegura de que sea opcion 1 o 2 sino muestra un error
    assert(opt == 1 | opt == 0);

    if (opt == 0) {
        ingresar_palabras();
    }

    xw = new xword(lista_palabras);
    main_loop();

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire