Thread: Problem with added header file in code::blocks

  1. #1
    Registered User
    Join Date
    Aug 2013
    Posts
    73

    Problem with added header file in code::blocks

    In my c project in code blocks , I have added another source file (KillerMoves.c) and a header file under the same name (KillerMoves.h). I added the "include guard" to prevent double inclusion.
    But from some reason, the program suddenly crashes with no warning or specific error. Without the new files,the program runs without any problems.

    This is the source .c file:
    Code:
    #include "KillerMoves.h"
    
    
    void initKillersTable(){
        for(int i = 0; i < 15; i++){
            killersTable[i] = -1;
        }
    }
    
    
    void addKiller(int killer,int depth){
        killersTable[depth] = killer;
    }
    
    
    int getKiller(int depth){
        return killersTable[depth];
    }
    And this is the header file:
    Code:
    #ifndef KILLERMOVES_H
    #define KILLERMOVES_H
    
    
    
    
    int killersTable[15];
    
    
    void initKillersTable();
    void addKiller(int killer,int depth);
    int getKiller(int depth);
    
    
    #endif
    In the main file (where the main function is) I have included the header as follows:
    Code:
    #include "KillerMoves.h"
    what am i doing wrong?

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    What is your greatest depth? Is 15 ply deep the limit?

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Program crashes are not caused by things like double inclusions, those would cause compilers errors (redefinition of symbols), and you couldn't run your program because it couldn't be built.

    Post the contents of the main file that causes the crash. I would bet you access the killersTable array out of bounds somewhere, by passing in an invalid depth, but I can't be certain without seeing the code. Accessing memory you don't own (e.g. writing to read-only memory or reading from invalid memory) results in undefined behavior, which often manifests as a program crash. If this is caused by something like an uninitialized variable, your compiler should warn you about that, so if it doesn't, crank up the warning level (read your compiler docs) and fix them all.

    Also, as some matters of good design:
    1. If you only intend for the rest of the program to manipulate the killersTable through the functions, then place the actual array definition in your KillerMoves.c file and add the static type qualifier. This is good encapsulation.

    2. If you have a fixed limit on the number of killers in killersTable, you should #define that constant either in the .c or .h file (depending on whether the rest of the program needs to know what that limit is), and use it in initKillersTable for your loop, and to check the value of depth before you read/write to it in addKiller and getKiller, to prevent out-of-bounds errors crashing your program (it should fail gracefully). That no only will help you make sure there are no out-of-bounds errors, but also allows you to change the number of killers easily, by changing 1 line instead of a bunch of separate places.

  4. #4
    Registered User
    Join Date
    Aug 2013
    Posts
    73
    Ok, thank you for the helpful replis and the tips. and i know that this code is dirty and that i use raw numbers instead of names and definitions (not like me,coming from OOP java)
    but i was just trying to do a quick and dirty try to write my connect4 engine in C so i didn't put much effort into it.
    Anyway,this is the whole main file with the game loop inside the main() function, and the rest of the function below (- the evaluation function which is very long and unnecesary here) you can scroll down and see the negamax() function, where i use the killersTable. Actually i use depth 10 so the KillersTable size 15 should be more than enough ( i don't even use the last 4 indexes of the table). I don't know what could be wrong..this is like the 1000th time i write this engine, but the first time i do it in C

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "KillerMoves.h"
    
    
    
    
    
    
    int board[49];
    int height[7];
    int ply;
    int lastMove;
    int getColumnByIndex[] = {0,0,0,0,0,0,-1,1,1,1,1,1,1,-1,2,2,2,2,2,2,-1,3,3,3,3,3,3,-1,4,4,4,4,4,4,-1,5,5,5,5,5,5,-1,6,6,6,6,6,6,-1};
    //int columns[] = {3,2,4,1,5,0,6};
    
    
    int rootNegamax(int depth,int alpha,int beta,int color);
    void reset();
    int checkFullBoard();
    int checkWin();
    void makeMove(int *n,int *color);
    
    
    
    
    int main()
    {
        int turn = 1; // set to 1 for engine as first player ,0 for engine as second
        int m;
        int engineNumber = 1;
        int opponentNumber = -1;
        const int DEPTH = 10;
        const int INFINITY = 1001;
        reset();
        if(turn){
            while(1 < 2){
                initKillersTable();
                printf("Thinking..\n");
                m = rootNegamax(DEPTH,-INFINITY,INFINITY,engineNumber);
                makeMove(&m,&engineNumber);
                printf("Engine played in column %d\n",m);
                if(checkWin()){
                    printf("Engine Wins!");
                    break;
                }
                else if(checkFullBoard()){
                    printf("Draw");
                    break;
                }
                printf("Enter column\n");
                scanf("%d",&m);
                makeMove(&m,&opponentNumber);
                if(checkWin()){
                    printf("You won!");
                    break;
                }
                else if(checkFullBoard()){
                    printf("Draw");
                    break;
                }
            }
        }
        else{
             while(1 < 2){
                printf("Enter column\n");
                scanf("%d",&m);
                makeMove(&m,&opponentNumber);
                if(checkWin()){
                    printf("You won!");
                    break;
                }
                else if(checkFullBoard()){
                    printf("Draw");
                    break;
                }
                initKillersTable();
                printf("Thinking..\n");
                m = rootNegamax(DEPTH,-INFINITY,INFINITY,engineNumber);
                makeMove(&m,&engineNumber);
                printf("Engine played in column %d\n",m);
                if(checkWin()){
                    printf("Engine Wins!");
                    break;
                }
                else if(checkFullBoard()){
                    printf("Draw");
                    break;
                }
             }
        }
        return 0;
    }
    
    
    
    
    void reset(){
        for(int i = 0; i < 49; i++){
            board[i] = 0;
        }
        for(int i = 0; i < 7; i++){
            height[i] = i*7;
        }
        ply = 0;
    }
    
    
    
    
    void makeMove(int *n,int *color){
        board[height[*n]] = *color;
        lastMove = height[*n];
        height[*n]++;
        ply++;
    }
    
    
    
    
    void unmakeMove(int *n){
        height[*n]--;
        board[height[*n]] = 0;
        ply--;
    }
    
    
    
    
    int checkFullColumn(int *n){
        return board[(*n)*7+5] != 0;
    }
    
    
    
    
    int checkFullBoard(){
        return ply == 42;
    }
    
    
    
    
    int checkValidSquare(int *square){
        return *square >= 0 && *square <= 48;
    }
    
    
    
    
    int checkWin(){
        int color = board[lastMove];
        int counter;
        int startPoint;
        int endPoint;
        //check horizontal
        startPoint = lastMove-21;
        endPoint = lastMove+21;
        counter = 0;
        while(startPoint <= endPoint){
            if(checkValidSquare(&startPoint)){
                if(board[startPoint] == color){
                    counter++;
                }
                else{
                    counter = 0;
                }
            }
            if(counter == 4){
                return 1;
            }
            startPoint+=7;
        }
        //check diagonal down right
        startPoint = lastMove-18;
        endPoint = lastMove+18;
        counter = 0;
        while(startPoint <= endPoint){
            if(checkValidSquare(&startPoint)){
                if(board[startPoint] == color){
                    counter++;
                }
                else{
                    counter = 0;
                }
            }
            if(counter == 4){
                return 1;
            }
            startPoint+=6;
        }
        //check diagonal up right
        startPoint = lastMove-24;
        endPoint = lastMove+24;
        counter = 0;
        while(startPoint <= endPoint){
            if(checkValidSquare(&startPoint)){
                if(board[startPoint] == color){
                    counter++;
                }
                else{
                    counter = 0;
                }
            }
            if(counter == 4){
                return 1;
            }
            startPoint+=8;
        }
        //check vertical
        startPoint = lastMove-3;
        endPoint = lastMove+3;
        counter = 0;
        while(startPoint <= endPoint){
            if(checkValidSquare(&startPoint)){
               if(board[startPoint] == color){
                    counter++;
               }
               else{
                    counter = 0;
               }
            }
            if(counter == 4){
                return 1;
            }
            startPoint++;
        }
        return 0;
    }
    
    
    
    
    
    
    int evaluate(){
        int i;
        int j;
        int k;
        int enThree = 0;
        int enTwo = 0;
        int enOne = 0;
        int opThree = 0;
        int opTwo = 0;
        int opOne = 0;
        int enCount;
        int opCount;
        //horizontal
        for(i = 0; i <= 5; i++){
            for(j = i; j <= i+21; j+=7){
                enCount = 0;
                opCount = 0;
                for(k = j; k <= j+21; k+=7){
                    if(board[k] == 1){
                        enCount++;
                    }
                    else if(board[k] == -1){
                        opCount++;
                    }
                }
                if(enCount > 0 && opCount == 0){
                    switch(enCount){
                        case 1:
                            enOne++;
                            break;
                        case 2:
                            enTwo++;
                            break;
                        case 3:
                            enThree++;
                            break;
                    }
                }
                else if(enCount == 0 && opCount > 0){
                    switch(opCount){
                        case 1:
                            opOne++;
                            break;
                        case 2:
                            opTwo++;
                            break;
                        case 3:
                            opThree++;
                            break;
                    }
                }
            }
        }
    
    
        //diagonals
        for(i = 5; i <= 17; i+=6){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+18; j+=6){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        for(i = 4; i <= 10; i+=6){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+18; j+=6){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        enCount = 0;
        opCount = 0;
        for(j = 3; j <= 21; j+=6){
            if(board[j] == 1){
                enCount++;
            }
            else if(board[j] == -1){
                opCount++;
            }
        }
        if(enCount > 0 && opCount == 0){
            switch(enCount){
                case 1:
                    enOne++;
                    break;
                case 2:
                    enTwo++;
                    break;
                case 3:
                    enThree++;
                    break;
            }
        }
        else if(enCount == 0 && opCount > 0){
            switch(opCount){
                case 1:
                    opOne++;
                    break;
                case 2:
                    opTwo++;
                    break;
                case 3:
                    opThree++;
                    break;
            }
        }
    
    
        for(i = 12; i <= 24; i+=6){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+18; j+=6){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        for(i = 19; i <= 25; i+=6){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+18; j+=6){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        enCount = 0;
        opCount = 0;
        for(j = 26; j <= 44; j+=6){
            if(board[j] == 1){
                enCount++;
            }
            else if(board[j] == -1){
                opCount++;
            }
        }
        if(enCount > 0 && opCount == 0){
            switch(enCount){
                case 1:
                    enOne++;
                    break;
                case 2:
                    enTwo++;
                    break;
                case 3:
                    enThree++;
                    break;
            }
        }
        else if(enCount == 0 && opCount > 0){
            switch(opCount){
                case 1:
                    opOne++;
                    break;
                case 2:
                    opTwo++;
                    break;
                case 3:
                    opThree++;
                    break;
            }
        }
    
    
        for(i = 7; i <= 23; i+=8){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+24; j+=8){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        for(i = 14; i <= 22; i+=8){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+24; j+=8){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        enCount = 0;
        opCount = 0;
        for(j = 21; j <= 45; j+=8){
            if(board[j] == 1){
                enCount++;
            }
            else if(board[j] == -1){
                opCount++;
            }
        }
        if(enCount > 0 && opCount == 0){
            switch(enCount){
                case 1:
                    enOne++;
                    break;
                case 2:
                    enTwo++;
                    break;
                case 3:
                    enThree++;
                    break;
            }
        }
        else if(enCount == 0 && opCount > 0){
            switch(opCount){
                case 1:
                    opOne++;
                    break;
                case 2:
                    opTwo++;
                    break;
                case 3:
                    opThree++;
                    break;
            }
        }
    
    
        for(i = 0; i <= 16; i+=8){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+24; j+=8){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        for(i = 1; i <= 9; i+=8){
            enCount = 0;
            opCount = 0;
            for(j = i; j <= i+24; j+=8){
                if(board[j] == 1){
                    enCount++;
                }
                else if(board[j] == -1){
                    opCount++;
                }
            }
            if(enCount > 0 && opCount == 0){
                switch(enCount){
                    case 1:
                        enOne++;
                        break;
                    case 2:
                        enTwo++;
                        break;
                    case 3:
                        enThree++;
                        break;
                }
            }
            else if(enCount == 0 && opCount > 0){
                switch(opCount){
                    case 1:
                        opOne++;
                        break;
                    case 2:
                        opTwo++;
                        break;
                    case 3:
                        opThree++;
                        break;
                }
            }
        }
    
    
        enCount = 0;
        opCount = 0;
        for(j = 2; j <= 26; j+=8){
            if(board[j] == 1){
                enCount++;
            }
            else if(board[j] == -1){
                opCount++;
            }
        }
        if(enCount > 0 && opCount == 0){
            switch(enCount){
                case 1:
                    enOne++;
                    break;
                case 2:
                    enTwo++;
                    break;
                case 3:
                    enThree++;
                    break;
            }
        }
        else if(enCount == 0 && opCount > 0){
            switch(opCount){
                case 1:
                    opOne++;
                    break;
                case 2:
                    opTwo++;
                    break;
                case 3:
                    opThree++;
                    break;
            }
        }
    
    
        return ((enThree*32) + (enTwo*4) + enOne) - ((opThree*32) + (opTwo*4) + opOne);
    
    
    
    
    }
    
    
    
    
    
    
    int negamax(int depth,int alpha,int beta,int color){
        if(checkWin()){
            return -1000;
        }
        else if(depth == 0 || checkFullBoard()){
            return color*evaluate();
        }
        else{
            int val;
            int killerAdded = 0;
            int killer = getKiller(depth);
            if(killer != -1 && height[getColumnByIndex[killer]] == killer){
                killerAdded = 1;
                makeMove(getColumnByIndex[killer],&color);
                val = -negamax(depth-1,-beta,-alpha,-color);
                unmakeMove(getColumnByIndex[killer]);
                if(val >= beta){
                    return val;
                }
                if(val > alpha){
                    alpha = val;
                }
            }
    
    
            for(int i = 0; i < 7; i++){
                if(killerAdded && i == getColumnByIndex[killer]){
                    continue;
                }
                if(checkFullColumn(&i)){
                    continue;
                }
                makeMove(&i,&color);
                val = -negamax(depth-1,-beta,-alpha,-color);
                unmakeMove(&i);
                if(val >= beta){
                    addKiller(height[i],depth);
                    return val;
                }
                if(val > alpha){
                    alpha = val;
                }
            }
            return alpha;
        }
    }
    
    
    
    
    int rootNegamax(int depth,int alpha,int beta,int color){
        int bestMove = -1;
        int val;
        for(int i = 0; i < 7; i++){
            if(checkFullColumn(&i)){
                continue;
            }
            makeMove(&i,&color);
            val = -negamax(depth-1,-beta,-alpha,-color);
            unmakeMove(&i);
            if(val > alpha){
                alpha = val;
                bestMove = i;
            }
        }
        return bestMove;
    }
    Last edited by patishi; 08-27-2013 at 07:11 PM.

  5. #5
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Some of your naming conventions are very odd and not exactly obvious for a connect-4 game. I probably wouldn't know what it did unless I looked closely at it, which I don't want to do right now. I would suggest renaming or rethinking some of your names and adding comments.
    "Some people think they can outsmart me, maybe. Maybe. I've yet to meet one that can outsmart bullet" - Meet the Heavy, Team Fortress 2

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Your code gives the following warnings/errors. In particular, the function evaluate() is nowhere to be found.

    >gcc -std=c99 -Wall -Wextra connect4.c killermoves.c
    connect4.c: In function 'negamax':
    connect4.c:236:9: warning: implicit declaration of function 'evaluate' [-Wimplic
    it-function-declaration]
    connect4.c:244:13: warning: passing argument 1 of 'makeMove' makes pointer from
    integer without a cast [enabled by default]
    connect4.c:104:6: note: expected 'int *' but argument is of type 'int'
    connect4.c:246:13: warning: passing argument 1 of 'unmakeMove' makes pointer fro
    m integer without a cast [enabled by default]
    connect4.c:114:6: note: expected 'int *' but argument is of type 'int'
    C:\DOCUME~1\Me\LOCALS~1\Temp\ccemVfNt.o:connect4.c :(.text+0x59e): undefined refe
    rence to `evaluate'
    collect2.exe: error: ld returned 1 exit status
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    Registered User
    Join Date
    Aug 2013
    Posts
    73
    yes,I said that i removed the evaluate() function from the code because it is unrelevant here and very long and messy. I also removed the checkWin function. every thing works fine without the inclusion of the killerMoves file and functions. something is wrong with that and i don't know what. I was certain that it was because of the include statement,but people here say that this is not the case.
    Last edited by patishi; 08-27-2013 at 07:10 PM.

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    As already suggested! (In post number 3)

    Remove the line "int killersTable[15];" from the header; it is a very bad idea to allocate space for variables in a C header.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  9. #9
    Registered User
    Join Date
    Aug 2013
    Posts
    73
    Ok now i added back the rest of the functions. please try to run this, without the inclusion of the killerMoves file. In my code::blocks it runs fine

    @stahta01 I will try to do that. so to include it directly in the c source file? (The killerMoves.c )

    EDIT: tried that..didn't solved my problem though
    Last edited by patishi; 08-27-2013 at 07:14 PM.

  10. #10
    Registered User
    Join Date
    Aug 2013
    Posts
    73
    Ok problem solved.. forgot to put a & in the makeMove call (before the first argumant

    Code:
     makeMove(&getColumnByIndex[killer],&color);
    Still need to get used to using pointers

  11. #11
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You have the same problem with unmakeMove. Actually, those two functions shouldn't be accepting pointers anyway since you aren't modifying the values (and they aren't structs or arrays).

    Also note that the problem had absolutely nothing to do with the included file!
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  12. #12
    Registered User
    Join Date
    Aug 2013
    Posts
    73
    Edit: forget about my last question...I will open new Thread for that, i think it is better ,maybe others will learn too
    Last edited by patishi; 08-27-2013 at 07:41 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with code::blocks
    By kinsomicrote in forum C Programming
    Replies: 9
    Last Post: 07-05-2012, 07:12 PM
  2. Replies: 5
    Last Post: 02-01-2012, 07:45 PM
  3. Code::Blocks run problem
    By Coga1900 in forum C++ Programming
    Replies: 34
    Last Post: 09-20-2011, 03:49 AM
  4. Code Blocks compiling problem
    By Lehsyrus in forum Tech Board
    Replies: 2
    Last Post: 07-13-2010, 02:28 PM
  5. Code::Blocks problem
    By eaane74 in forum C++ Programming
    Replies: 6
    Last Post: 05-24-2007, 07:24 PM

Tags for this Thread