Clockowl 56 Posting Whiz

Hey, this code executes flawlessly:

scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\digi.obj", true);

I also added a extra line in the .obj parser, and pretty sure the error is in their when checking it's additional output (when loading anubis.obj)

Counting...WARNING: Line not supported:
WARNING: Line not supported:
WARNING: Line not supported:
WARNING: Line not supported:
WARNING: Line not supported: g Anubis head
WARNING: Line not supported:
WARNING: Line not supported: g Anubis garment
WARNING: Line not supported: //3525 2906//3436
WARNING: Line not supported: 41 2860//3237 2863//3240

See, those last two warnings are reallllyyy important! Hahaha, I'm rechecking that part, pretty sure that if I fix that error, the char* to string conversion will work like a charm. ;)

Clockowl 56 Posting Whiz

When I run the code, but remove that second line, it also segfaults! But, when changing the object, the file I'm passing, it doesn't segfault... However, I don't understand that it always segfaults with the same object (and doesn't with others). Anyone with a fair share of OpenGL knowledge? Maybe I'm messing up somewhere. I use GLUT by the way, on my windows machine. So it's ported, obviously.

Clockowl 56 Posting Whiz

Oh, the backtrace that is offered, is not really useful. It looks like it's data:

#0 7D62BD7E	??() (??:??)
#1 00000036	??() (??:??)
#2 003F0000	??() (??:??)
#3 00000001	??() (??:??)
#4 7D623710	??() (??:??)
#5 003F0000	??() (??:??)
#6 7D61CA05	??() (??:??)
#7 7D623938	??() (??:??)
#8 FFFFFFFF	??() (??:??)
#9 0022F58C	??() (??:??)
#10 0000159A	??() (??:??)
#11 0022F57C	??() (??:??)
#12 7D623710	??() (??:??)
#13 003F0000	??() (??:??)
#14 03882330	??() (??:??)
#15 003F0000	??() (??:??)
#16 03882330	??() (??:??)
#17 00001103	??() (??:??)
#18 03840000	??() (??:??)
#19 0100039A	??() (??:??)
#20 0022F5B0	??() (??:??)
#21 7D623A9A	??() (??:??)
#22 0000159A	??() (??:??)
#23 10882330	??() (??:??)
#24 00000000	??() (??:??)
Clockowl 56 Posting Whiz

Hey guys,

An char* to string conversion looks to be generating a segfault. I'm pretty sure that's not it, but that's when GDB says it received one...

Well, here's the, what I think, relevant code. If you think more code is relevant I'll post that too of course.

Entity.h (objLocation definition, ctor definition)

public:
    entity(char *location, bool loadNow);
(...)
private:
(...)
    string objLocation;
};

Entity.cpp (constructor only)

entity::entity(char *modellocation, bool loadNow):
visible(true)
{
    for(int i = 0; i < 3; i++){
        location[i] = rotation[i] = 0;
    }

    objLocation = modellocation; //BOOM segfault. :(
    if(loadNow){
        loadentity();
    }

    return;
}

World.cpp (createAndAddEntity method, origin of the call to the entity constructor)

void world::createAndAddEntity(char *location, bool loadNow){
    entity *holdThis = new entity(location, loadNow);
    world::addEntity(holdThis);

    return;
}

And too make it just the bit more confusing for me:

main.cpp

scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\anubis.obj", true);
    scene.createAndAddEntity("C:\\Code\\BowViceJetDeux\\testobj\\anubis.obj", true);

First works good, second one gives that segfault mentioned earlier. Why does it do that? :(

Thanks in Advance,
Nick

Clockowl 56 Posting Whiz

Use clock(), clock_t and CLOCKS_PER_SECOND. That way you can get the time in milliseconds, nanoseconds.. whatever you want. ;)

Clockowl 56 Posting Whiz

Feel free to ask questions, my email and msn in in your inbox.

Clockowl 56 Posting Whiz

I just meant to say he's trying to create a C program I guess, using a C++ compiler since only a C++ compiler will throw that error. Nothing more.

Clockowl 56 Posting Whiz

Hey, of course. It's pretty straightforward tho, only loading vertices, faces and normals, but not polygons and other things (like textures for instance).

The main bottleneck is I/O: sscanf. The only way I see to speed this program up is to:

Multithread it

Store the .obj files as binary data instead of their ASCII representation, so you won't have to use scanf anymore.

loadObj.c

#include <stdio.h> //obvious
#include <stdlib.h> //malloc and such
#include <string.h> //memory copy stuff
#include <time.h> //time stuff, ofc.
#include <ctype.h> //isspace, isdigit
#include <math.h> //only for fabs

#define TIMEELAPSED {printf("\tTime elapsed: %lu\n", (clock() - startTime)*1000 / CLOCKS_PER_SEC);}

//this is in BowViceJet.c
void dbgError(char *msg);

int countSpaces(char *str){
  int cnt = 0;
  while(*str != '\0'){
    if(*str == ' ') cnt++;
    str++;
  }

  //remove trailing spaces
  str--;
  while(isspace(*str)){
    if(*str == ' ') cnt--;
    str--;
  }

  return cnt;
}

int loadObj(const char const *loc,\
            float **retvertices, float **retgouraudnormals,\
            int **rettriangleindex, int **retquadindex,\
            int *quadcount, int *trianglecount){
  float *vertices, *gouraudnormals;
  int *triangleindex, *quadindex;
  float *normals, *verttext;
  int *trianglenormals, *quadnormals;

  clock_t startTime = clock();
  int fileSize = 0;
  int n, i, j;
  printf("Opening file: %s\n", loc);

  FILE *pFile = fopen(loc, "r");
  if(pFile == NULL){
      dbgError("fopen()");
      exit(1);
  }

  fseek(pFile, 0, SEEK_END);
  fileSize = ftell(pFile);
  rewind(pFile);

  char *data = (char*) calloc(sizeof(char), fileSize + 1);

  fread(data, 1, fileSize, pFile);
  if(ferror(pFile)){
      dbgError("fread()");
      exit(1);
  }

  fclose(pFile);

  printf("Done reading, parsing file now.\n");
  TIMEELAPSED

  printf("Removing #IND if there...");
  char *pIND = data;
  n = 0;
  while(1){
    pIND = strstr(pIND, "#IND");
    if(pIND != NULL){ …
Clockowl 56 Posting Whiz

"cannot convert from" is a C++ (and in general, OOP) only error afaik.

Clockowl 56 Posting Whiz

You're getting C++ errors. C++ is a lot stricter. Try using a C compiler. ;)

Clockowl 56 Posting Whiz

Erm.. well now I created them right before they are used, and undefined them right after that.. That's neat I think? They are placed where they are used. That way you don't have to scroll up to view it's implementation.

Agreed nonetheless that the code is mess and it could be cleaned up more. But I don't think the macros are that disturbing.

On a sidenote: How do I get gprof to work with C++ using GLUT and threading? Hahaha.. it doesn't display times now even when I run from the console.. :( I'm downloading VTune as we speak, but I'd like gprof to work, being free and all. :)

Clockowl 56 Posting Whiz

Strange, when I run Gprof from the command line, seconds do show up, but it doesn't seem to be compatible with winmain instead of main. :(

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 91.30      0.63     0.63        1   630.00   670.00  loadObj
  5.80      0.67     0.04   297473     0.00     0.00  countSpaces
  1.45      0.68     0.01                             isspace
  1.45      0.69     0.01                             malloc
  0.00      0.69     0.00     2093     0.00     0.00  RenderScene
  0.00      0.69     0.00        1     0.00     0.00  ChangeSize
  0.00      0.69     0.00        1     0.00     0.00  MySetPixelFormat
  0.00      0.69     0.00        1     0.00     0.00  WinMain@16
  0.00      0.69     0.00        1     0.00   670.00  initGL

Well, I was rewriting it to GLUT anyway. Thanks for the trouble. Suggestions on how to improve the above code are still welcome of course...

Clockowl 56 Posting Whiz

Gmon.out doesn't contain any useful info, all the times are zero. :S I'm using it from Code::Blocks on my Windows XP x64 machine.

Like this btw:

Flat profile:

Each sample counts as 0.01 seconds.
 no time accumulated

  %   cumulative   self              self     total           
 time   seconds   seconds    calls  Ts/call  Ts/call  name    
  0.00      0.00     0.00     1926     0.00     0.00  _RenderScene
  0.00      0.00     0.00        1     0.00     0.00  _WinMain@16
  0.00      0.00     0.00        1     0.00     0.00  _initGL
  0.00      0.00     0.00        1     0.00     0.00  _loadObj
Clockowl 56 Posting Whiz

Is there any difference between those function declarations in C++? Since in C the first states "take any and as much arguments as you like", and the latter means take none...

Thanks in Advance,
Nick

Clockowl 56 Posting Whiz

EDIT for moderators:
Yes that "one might think that swapbuffer is slow" was me. Heh. :D Could someone change the topicname to "Optimizing OpenGL"? Thanks.

Hey guys,

I'm trying to optimize this OpenGL program, so the problem isn't C, but the program is.

The program loads a vanilla WaveFront .obj file, stores all it's data in an array, creates a display list, uses glDrawElements to put it in the display list and then calls the display list as often as it can. For my test file, this "how often as it can" gives an FPS of about 37. While this is acceptable, another program that does the same manages to do it at 60 FPS.

How do I achieve that performance in this program? The bottleneck appears to be the RenderScene function. It only shows when using glFinish(), else one might think SwapBuffer() takes that amount of time (SwapBuffer waits, of course, for the videocard to finish its rendering). Anyway, from beginning RenderScene to the return of SwapBuffer takes too much time. Too much CPU time that is! My Intel blah blah dual core has once core fully eaten up by this code, and I have no clue why.

Here is the output from the sourcecode below:

WM_TIMER took:  Time elapsed: 31
WM_TIMER took:  Time elapsed: 16
WM_TIMER took:  Time elapsed: 31
WM_TIMER took:  Time elapsed: 31
WM_TIMER took:  Time elapsed: 31
WM_TIMER took:  Time elapsed: 16
WM_TIMER took:  Time elapsed: 31
WM_TIMER …
Clockowl 56 Posting Whiz

Not to be an asshole, but:

click here! :D

Too bad that doesn't work, but you can figure it out. Examples are abundant on the web.

Clockowl 56 Posting Whiz

I apparently need to instantiate them somewhere.. but not in the constructor. :/

Nor in main because they are private...

It makes sense that I can't initialize them from the constructor, but not completely since I thought they were initalized to zero by default. However, how can I initialize private non-const static member variables then? Should I create a static-set function for those?

Thanks in Advance,
Nick

Clockowl 56 Posting Whiz

Hi guys,

I'm having this weird error with undefined references to static variables, and was wondering what I'm doing wrong.

Here's the header:
World.h

#ifndef WORLDH
#define WORLDH
#include <vector>
using std::vector;

#include "Breeture.h"
class World{
    friend class Breeture;

    public:
    World(vector<Breeture*> *initialBreetures);
    World(unsigned int mutChance, unsigned int breetures);

    void NewBreeture(const Breeture *const baby);
    void BaiBreeture(const Breeture *const deceased);

    /*This function ages all living breetures*/
    void AgeBreetures();

    /*Does a death-check. World makes Breetures die.*/
    void DeathCheck();

    /*World also makes breetures mate.*/
    void BirthCheck();

    void outputAllData();

    unsigned int getWorldPopulation(){
        return worldPopulation;
    }

    unsigned int getTotalBreetures(){
        return totalBreetures;
    }

    bool verboseMode;

    //int StoreFamilyTree(string *location);

    private:
    static unsigned int worldPopulation;
    static unsigned int totalBreetures;

    /*This number is the limiting factor, resembling the lack of a certain resource (food, space) for Breetures*/
    unsigned int maxBreetures;

    Breeture *oldest;
    Breeture *mostChildren;

    /*Holds a vector of living creatures, for speedy aging*/
    vector<Breeture*> livingBreetures;

    /*Holds a tree of vector describing parent/child relationships*/
    vector<Breeture*> familyTree;
};
#endif

World.cpp

#include <vector>
using std::vector;

#include "Breeture.h"
#include "World.h"

World::World(vector<Breeture*> *initialBreetures) {
    livingBreetures = *initialBreetures;
    worldPopulation = livingBreetures.size();
    return;
}

World::World(unsigned int mutChance, unsigned int breetures) {
    Breeture::mutationChance = mutChance;

    //reserve memory to save reallocating x times
    livingBreetures.reserve(breetures);

    worldPopulation = totalBreetures = breetures;

    //create breetures breetures
    for (unsigned int i = 0; i < breetures; i++) {
        livingBreetures[i] = new Breeture();
    }

    return;
}

void World::AgeBreetures() {
    for (unsigned int i = worldPopulation; i >= 0; i--) {
        livingBreetures[i]->Age();
    }
    return;
}

void World::DeathCheck() {
    unsigned int DeathChance; …
Clockowl 56 Posting Whiz

There are plenty of C features considering time. Read up on them.

The linked list approach seems efficient enough for this task.

Clockowl 56 Posting Whiz

That was really stupid. Thanks.

Clockowl 56 Posting Whiz

Yes, thanks. You are off in the first part, but the second was right. :)

However, now I'm having problems trying to create a vector of pointers to the Breeture class. Compiler complains that *Breeture isn't a type. How would I do this?

Thanks in advance,

Clockowl 56 Posting Whiz

New problem arose:

Almost the same code as before:

Breeture.h

#ifndef BREETUREH
#define BREETUREH

#include <vector>
class Breeture{
    friend class World;

    public:
    //Creates the breeture
    Breeture();

    //Pwns the breeture.
    void Die();
    ~Breeture();

    void Age();

    void outputDNA();
    void outputAge();

    void outputData();

    private:
    bool alive;
    unsigned int number;

    unsigned int age;
    unsigned int DNA[2];
    unsigned int causeofdeath;

    unsigned int kids;

    unsigned int deathChance;

    vector<*Breeture> parents;
    vector<*Breeture> children;
    vector<*Breeture> partners;
};
#endif

Main.cpp

#include <cstdio>
#include "Breeture.h"

int main(){
    printf("Sizeofbreeture: %d", sizeof(Breeture));
    return 0;
}

Errors while compiling:

C:\Code\Rapture\Breeture.h|35|error: ISO C++ forbids declaration of `vector' with no type|
C:\Code\Rapture\Breeture.h|35|error: expected `;' before '<' token|
C:\Code\Rapture\Breeture.h|36|error: ISO C++ forbids declaration of `vector' with no type|
C:\Code\Rapture\Breeture.h|36|error: expected `;' before '<' token|
C:\Code\Rapture\Breeture.h|37|error: ISO C++ forbids declaration of `vector' with no type|
C:\Code\Rapture\Breeture.h|37|error: expected `;' before '<' token|
||=== Build finished: 6 errors, 0 warnings ===|
Clockowl 56 Posting Whiz

Hmz, this seemed to be the problem:

For being a class's friend, the class that has the friend statement does not need the header file for the friend class/function, apparently.

Thanks.

Clockowl 56 Posting Whiz

Breeture.h or cpp doesn't have a instance of the world class in it, or you didn't mean to say that? Breeture needs to include the header file of world because it it's his friend, but it doesn't create an instance of world itself.

Breeture.h includes world.h
world.h includes Breeture.h
and so on....

And that won't happen with the #ifndef "protection", if I'm right.

Clockowl 56 Posting Whiz

Hey guys,

I come over from C, wanting to learn C++. I have a nice little book but figured I could use a project to get me going.

So I magicly crafted code, and ran into this problem: C:\Code\Rapture\World.h|7|error: ISO C++ forbids declaration of `Breeture' with no type| With this code:

Breeture.h:

#ifndef BREETUREH
#define BREETUREH

#include <vector>
#include "World.h"
class Breeture{
    friend class World;

    public:
    //Creates the breeture
    Breeture();

    //Pwns the breeture.
    void Die();
    ~Breeture();

    void Age();

    void outputDNA();
    void outputAge();

    void outputData();

    private:
    bool alive;
    unsigned int number;

    unsigned int age;
    unsigned int DNA[2];
    unsigned int causeofdeath;

    unsigned int kids;

    unsigned int deathChance;

    vector<*Breeture> parents;
    vector<*Breeture> children;
    vector<*Breeture> partners;
};
#endif

World.h:

#ifndef WORLDH
#define WORLDH
#include <vector>
#include "Breeture.h"
class World{
    public:
    void NewBreeture(const Breeture *const baby);
    void BaiBreeture(const Breeture *const deceased);

    /*This function ages all living breetures*/
    void AgeBreetures();

    /*Does a death-check. World makes Breetures die.*/
    void DeathCheck();

    /*World also makes breetures mate.*/
    void BirthCheck();

    //int StoreFamilyTree(string *location);

    private:
    unsigned int worldPopulation;
    unsigned int totalBreetures;


    /* And...
       The oldest breeture
       The breeture with the most direct-offspring*/
    Breeture oldest;
    Breeture mostChildren;

    /*Holds a vector of living creatures, for speedy aging*/
    vector<*Breeture> livingBreetures;

    /*Holds a tree of vector describing parent/child relationships*/
    vector<*Breeture> familyTree;
    */
};
#endif

Why doesn't World.h know about the breeture class?

Thanks in advance,
Nick

Clockowl 56 Posting Whiz

Integer division will always be zero as "C" floors it.

Odd number: 5

5 / 2 = 2
2 / 2 = 1
1 / 2 = 0

Even number: 4

4 / 2 = 2
2 / 2 = 1
1 / 2 = 0

As you can see with this small (non legal C) program:

int main(){
  unsigned int x;
  scanf("%u", &x);

  while(x){
    printf("x = %d\n", x);
    x = x / 2;
  }
  
  printf("x = %d\n", x);
  
  return 0;
}

With output:

C:\Code>TMP
5
x = 5
x = 2
x = 1
x = 0

C:\Code>TMP
4
x = 4
x = 2
x = 1
x = 0
Clockowl 56 Posting Whiz

I figured that nobody would learn from this error. I mixed a variable name with another.

Clockowl 56 Posting Whiz

Solved!

Clockowl 56 Posting Whiz

Heh, that's not what I meant I'm afraid.

You see, I want to make an iterative function. The only advantage that has over this recursive function, that it doesn't call "itself". So, it's in essence the same function WITHOUT "call solveit()". To see if writing an iterative function is worth the trouble, I first want to know how much that command (and that command only) takes. (Calling a function also takes time).

A profiler "examines" your code while it runs. Some hold counters of function calls, others also display time spend in each function, etc. You should check it out on wikipedia/google if you're interested, they can greatly help you find bottlenecks in a program.

Clockowl 56 Posting Whiz

I can't see how I could place the calls to clock in such a way I can only measure the time spent calling. If you do, please post some example code so I can learn from it.

I think a profiler should be more convenient for this, but I don't have any experience with them. Can anyone recommend me a good profiler?

Clockowl 56 Posting Whiz

That's a C++ program btw, not C.

To make it C:

#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <stdio.h>
#include <math.h>

int main()
{
    HWND console = GetConsoleWindow();
    HDC dc = GetDC(console);
    int pixel = 0;
    unsigned int loopcounter = 0;
    unsigned int loopmax = 126;
    COLORREF C1= RGB(255,0,0); //red
    double i = 0;

    for (loopcounter = 0; loopcounter < loopmax; loopcounter++)
    {
        SetPixel(dc,pixel,(int)(100+50*sin(i)),C1);
        pixel++;
        i += 0.05;
    }
    ReleaseDC(console, dc);
    getchar();
    return 0;
}

And link it with gdi32.

Nick Evan commented: Thanks for the heads up! +6
Clockowl 56 Posting Whiz

Shouldn't matter in what language your DLL is made, I think you need to figure out how to thread in RealBasic and call the functions from your realbasic program.

Clockowl 56 Posting Whiz

Are you working on Windows or Unix? I know that windows has some functions in the Win32 API for setting pixels in the console screen.

Clockowl 56 Posting Whiz

Hey,

I made a bit of a change to my program, it runs a bit faster now.

Can anyone else come up with more ways to speed up this specific algorithm? So no other ones?

Does anyone know a good way to measure how much time is spend ONLY calling? So not the function itself, purely the call?

As to why: I figured the iterative implementation of the function will only delete *that* overhead. Nothing more. So if little time is spend on the call itself, I wouldn't bother writing an iterative function.

Here's the code, enjoy:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

#define NODEBUG

#define TIMEELAPSED {printf("\tTime elapsed: %lu\n", GetTickCount() - startTime);}

static unsigned int startTime;

void printBoard(const unsigned char *board){
  unsigned int i, j;

  for(i = 0; i < 8; i++){
    for(j = 0; j < 8; j++){
      printf("%02u ", board[i*8+j]);
    }
    putchar('\n');
  }
  putchar('\n');

  return;
}

__attribute ((fastcall)) static int solveit(const unsigned int knightPosx, const unsigned int knightPosy, const unsigned int steps){
  __attribute((aligned(16))) static const int horizontal[8] = {2, 1, -1, -2, -2, -1, 1, 2};
  __attribute((aligned(16))) static const int vertical[8] = {-1, -2, -2, -1, 1, 2, 2, 1};

  static unsigned int boardsSolved = 0;
  __attribute((aligned(16))) static unsigned char board[8*8] = {1};

  if(steps == 64){
    printf("Board (%u) solved:\n", ++boardsSolved);
    printBoard(board);
    TIMEELAPSED
    return 0;
  }

  //i is used for selecting the positions.
  register unsigned int i;
  register unsigned int curPosx;
  register unsigned int curPosy;

  /*Algo:
    calc xpos
    if xpos …
Clockowl 56 Posting Whiz

And another surprise struck me! I had this code:

if(curPos[0] > 7){
      continue;
    }
    else{
      curPos[1] = knightPos[1] + vertical[i];
      if(curPos[1] > 7){
        continue;
      }
      else{

And figured I could change it to this:

curPos[0] = knightPos[0] + horizontal[i];
    if(curPos[0] < 8){
      curPos[1] = knightPos[1] + vertical[i];
      if(curPos[1] < 8){

Lesson learned? The top one is about 30% faster when compiled with GCC. Is this a bad of C, or a bad of GCC? Bad branch prediction by the CPU? I'd really like to know.

Clockowl 56 Posting Whiz

I am stunned.

Here are two algorithms for you, they are cut down to their differences.

I'll give you that the above algorithm will loop less. A lot less. When the second one loops 8 times, the top one may loop 2, 3, 4, 6 or 8 times.

Algorithm 1:

for(moves = 0; moves < maxMoves; moves++){
    curMove = board[curX + curY*8].availableMoves[moves];

    curPos[0] = curX + horizontal[curMove];
    curPos[1] = curY + vertical[curMove];
  }

Algorithm 2:

for(i = 0; i < 8; i++){
    curPos[0] = knightPos[0] + horizontal[i];
    if(curPos[0] < 7){
      curPos[1] = knightPos[1] + vertical[i];
      if(curPos[1] < 7){
      }
    }
  }

To my surprise, the second one executed a lot faster than the first. I'll try and undo the structuring of my code, that seems to be killing the first one, don't you think?

Clockowl 56 Posting Whiz

No way, THAT much? Well... erm..

Maybe a minute per position then? hahahaha.. Okay, it won't be a minute, but erm.. Well fast. Really fast.

Testing the improvement.

Clockowl 56 Posting Whiz

Okay.

I'm doing this for fun and training myself, I wanted to create an algorithm that finds every possible Knight's Tour from any given position in a reasonable amount of time. I'd like it to be in a minute, but I'm not sure if that's possible.

I'm working on an improvement, so hang on. I'm curious how much faster it'll run, but it will run faster.

Clockowl 56 Posting Whiz

Sorry if that sounded hostile, I was honestly wondering why it mattered.

Are you saying that for any given position you find *all* the solutions in 15ms? Warnsdorff only finds a set, no? If so, please post your implementation so I can study it. Thank you.

Clockowl 56 Posting Whiz

Why does it matter what speeds I'm getting? I want it to be faster. You can't meassure this speed very well since it will "hang" on the same solution for quite a long time and then sometimes spawn 500 solutions in 2 seconds. It gets to 3498th solution in about 24 minutes on my system.

Open solutions are acceptable.

There's a good benchmark at solution nr. 823. It'll get there in about 70 seconds here and then hang for some time.

Clockowl 56 Posting Whiz

It's doesn't matter how long it takes to run, I want it to run faster. Improving this algorithm.

And relax, I was only saying you made a mistake in your previous post and explained it.

I'm using GCC with the -o3 and -Wall flag. That's all.

Clockowl 56 Posting Whiz

That's not entirely correct I'm afraid.

I only display the board when it is solved, that's also when I calculate the difference in time.

Notice the #ifdef DEBUG in front of the "print the board after every move" line. That line only gets compiled when DEBUG is defined, which it isn't. It was there for, naturally, debugging purposes.

Clockowl 56 Posting Whiz

Hiya fellas,

I just made this Knight's Tour program, and wish to speed it up without making it non-brute force. So it shouldn't have any intelligence.

I did most I could, and was wondering if you guys know more ways to speed this program up. First thing I thought about is changing the recursive "solveit" to an iterative function, but will this really speed the program up, since it's maximum "call depth" is 64?

The code is attached as well as below. Any other comments are welcome as well.

Thanks in Advance,
Nick

PS:
Code is attached and below:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

#define NODEBUG

#define TIMEELAPSED {printf("\tTime elapsed: %lu\n", GetTickCount() - startTime);}

const int horizontal[8] = {2, 1, -1, -2, -2, -1, 1, 2};
const int vertical[8] = {-1, -2, -2, -1, 1, 2, 2, 1};

unsigned int boardsSolved = 0;
unsigned char board[8*8] = {1};
unsigned int startTime;

void printBoard(const unsigned char *board){
  unsigned int i, j;

  for(i = 0; i < 8; i++){
    for(j = 0; j < 8; j++){
      printf("%02u ", board[i*8+j]);
    }
    putchar('\n');
  }
  putchar('\n');

  return;
}

int solveit(const unsigned int *knightPos, const unsigned int steps){
  if(steps == 64){
    printf("Board (%u) solved:\n", ++boardsSolved);
    printBoard(board);
    TIMEELAPSED
    return 0;
  }

  /*Algo:
    calc xpos
    if xpos is valid:
      calc ypos
      if ypos is valid:
      if board[x][y] is not stepped on
        set board[x][y] to steps
        call self with updated position and board
  */

  unsigned int i;
  unsigned …
Clockowl 56 Posting Whiz

So basically you're saying that even when the sizes are constant, I can't memset the whole 2D array like this:

char buf[20][10];
memset(buf, 0, sizeof(char) * 20 * 10);

?

Clockowl 56 Posting Whiz

Hey,

When quick googling didn't really clarify, I'd like to ask here.

When declaring an N-dimensional array, 2D in this case, how to set them all to zero? For 1D arrays it should work with

type name[n] = {0};

Is the same approach also guaranteed to work for N-Dimensional arrays and does it matter if they are with non-constant values or with them? (i.e. char buf[20][n] <-> char buf[20][10]; )

And if they can't be made completely zero with that, how do you suggest making them zero? Are 2D arrays with constant sizes always "behind" each other? (in one continuous block of memory?)

Thanks in advance,
Nick

Clockowl 56 Posting Whiz

WndProc is a callback function. I don't call it.

Clockowl 56 Posting Whiz

What's wrong about it? Okay, it's fixed length only, but that's like... obvious. I've parsed text in C. Never something like changing a string though, but I don't see why this method wouldn't work given it's a fixed length string/word.

Clockowl 56 Posting Whiz

I don't get why you use fgets. If it's an ASCII file, and it should be for the thing you're trying to do, all you need to do is strstr(buff, find) and then memcpy. Not strcpy, in an ASCII file aren't any NULL bytes. Well, not that I know of. I've never encountered NULL bytes in an ASCII file.

So it'd be more like this:

//read in the whole file
char *ptr = strstr(buf, find);
memcpy(ptr, find, sizeof(char) * strlen(find));

Something like that.

Clockowl 56 Posting Whiz

So, declare a static struct in WndProc and pass a pointer... That makes sense. Thanks.

Clockowl 56 Posting Whiz

I'm writing this windows app and I can't figure out how to let the user manipulate data (in a function called by WndProc) without using globals. Do you think it's better to use one global array/struct than lots of tiny globals? That'd make sense.