1. Originally Posted by Akkernight
No, I'm actually gonna disagree with you matsp xP no algorithm calculates randomness right.. It's impossible, so if you toss a coin in real life, you get the real randomness, if you do rand() in code, you get some algorithm of predictable numbers
That is true of all pseudorandom number generators, but what is your point? Using a PRNG multiple times does not suddenly turn it into a "real" random number generator. The reason I suggested that you just go for the straightforward implementation is because that way you can see more clearly why your more complicated implementation is actually bogus.

2. Ok, I've officially proven that the problem lies in move()
Code:
```void Cball::move(enum posNeg xDir){
while(inAir){
x = (x + speed) * xDir;
}
}```
EDIT: My point is! ... To act clever 8-)

3. Originally Posted by Akkernight
Ok, I've officially proven that the problem lies in move()
Well... yes, the loop either does not run or runs infinitely since inAir is never changed in the loop.

4. Yeah well... It'll turn false once the ball is off the screen, but I also deleted everything from move(), and it still crashes the application o.O could it be the enum?
or... I didn't delete the loop xP lemme check that
EDIT: And it was the loop xP but how can I then make it move using AI o.O? Hmm...

5. Well... maybe you would use an algorithm along the lines of:
Code:
```while the ball is not at its destination
move the ball towards the destination
draw the ball in its current position```
You might need to add a slight delay so that the user can actually see the ball moving.

6. Improving randomness by calling rand() multiple times doesn't seem to work:
Code:
```#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

class BaseRand
{
public:
virtual int random() = 0;
virtual string name() = 0;
};

class Rand1 : public BaseRand
{
public:
virtual int random(void)
{
return rand() % 2;
}
virtual string name() { return string("Simple"); }
};

class Rand2 : public BaseRand
{
public:
virtual int random(void)
{
int one = 0;
int zero = 0;
for(int i = 0; i < 20; i++)
{
if (rand() % 2)
one++;
else
zero++;
}
return static_cast<int>(zero >= one);
}
virtual string name() { return string("Complex"); };
};

void testIt(BaseRand *p)
{
const int iterations = 10000;
int longseq = 0;
int dub = 0;
int ones = 0;
int zeros = 0;
int curseq = 1;
int last = -1;
int sum = 0;

for(int i = 0; i < 10000; i++)
{
int r = p->random();
if (r == last)
{
curseq++;
dub++;
}
else
{
if (curseq > longseq)
{
longseq = curseq;
}
curseq = 1;
last = r;
}
ones += r;
zeros += !r;
sum += r;
}
cout << "Iterations: " << iterations << endl;
cout << "Zeros: " << zeros << " Ones: " << ones  << endl;
cout << "Longest sequence: " << longseq << endl;
cout << "Doubles: " << dub << endl;
cout << "Sum: " << sum << endl;
}

int main()
{
BaseRand *method;
srand(112341);
method = new Rand1;
testIt(method);
delete method;
srand(112341);
method = new Rand2;
testIt(method);
delete method;
return 0;
}```
The results are:
Code:
```Iterations: 10000
Zeros: 5018 Ones: 4982
Longest sequence: 13
Doubles: 4985
Sum: 4982
Iterations: 10000
Zeros: 4039 Ones: 5961
Longest sequence: 20
Doubles: 5227
Sum: 5961```
You get less randomness in your code than in the standard random - at least if we assume that the likelyhood of getting a zero or a one is higher -> less good randomness.

--
Mats

7. Well, I figured the AI out, and matsp, I hope I didn't get your mind of your work o.o?

8. Originally Posted by Akkernight
Well, I figured the AI out, and matsp, I hope I didn't get your mind of your work o.o?
No, I was waiting for a big compile to finish - and it's good to excercise a bit of small programming from time to time.

--
Mats

9. Sorry, but I need a pastebin in a hurry! :/

http://www.2shared.com/file/4729264/.../platform.html

http://www.2shared.com/file/4729268/9e6fccbc/Ball.html

main.cpp
Code:
```#include "objects.h"

#include "hge.h"
#include "hgeresource.h"
#include "hgesprite.h"

HGE *hge = 0;

//resource managers
hgeResourceManager* myRes;

//sprites
hgeSprite* ballSprite;
hgeSprite* platformP1;
hgeSprite* platformP2;

//My classes
player1 P1;
player2 P2;
Cball ball;

bool FrameFunc(){

float dt = hge->Timer_GetDelta();

if(ball.moving){
ball.x += ball.speed * dt;
}

if(hge->Input_GetKeyState(HGEK_ESCAPE)) return true;
if(hge->Input_GetKey() == HGEK_SPACE) ball.moving = true;
//movement controls
//Player 1
if(hge->Input_GetKeyState(HGEK_W)) P1.y -= P1.speed*dt;
if(hge->Input_GetKeyState(HGEK_S)) P1.y += P1.speed*dt;
//player 2
if(hge->Input_GetKeyState(HGEK_UP)) P2.y -= P2.speed*dt;
if(hge->Input_GetKeyState(HGEK_DOWN)) P2.y += P2.speed*dt;

P1.wallCollide();
P2.wallCollide();

return false;
}

bool RenderFunc(){

hge->Gfx_BeginScene();
hge->Gfx_Clear(0);
ballSprite->RenderStretch(ball.x, ball.y, ball.x + 16, ball.y + 16);
//Render platformP1
platformP1->SetColor(0xFF0000FF);
platformP1->RenderStretch(P1.x, P1.y, P1.x + 10, P1.y + 64);
//Render platformP2
platformP2->SetColor(0xFFFF0000);
platformP2->RenderStretch(P2.x, P2.y, P2.x + 10, P2.y + 64);

hge->Gfx_EndScene();

return false;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){

hge = hgeCreate(HGE_VERSION);

hge->System_SetState(HGE_LOGFILE, "LOGFILE.log");
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
hge->System_SetState(HGE_TITLE, "HGE application");
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_SCREENWIDTH, 800);
hge->System_SetState(HGE_SCREENHEIGHT, 600);
hge->System_SetState(HGE_SCREENBPP, 32);

if(hge->System_Initiate()){

myRes = new hgeResourceManager("resource.res");
ballSprite = myRes->GetSprite("ballSprite");
platformP1 = myRes->GetSprite("platformSprite");
platformP2 = myRes->GetSprite("platformSprite");

hge->System_Start();

delete myRes;
}
else{
MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
}

hge->System_Shutdown();
hge->Release();

return 0;
}```
platformP1.cpp
Code:
```#include "objects.h"

player1::player1(){
y = 236;
speed = 500;
}

player1::~player1(){
}

void player1::wallCollide(){
if(y>600 - 65) {y = 600 - 65;}
if(y<1) {y = 1;}

}```
objects.h
Code:
```#ifndef OBJECTS_H
#define OBJECTS_H

class player1
{
public:
player1();
~player1();

static const int x = 20;
float y;
float speed;

void wallCollide();

protected:

};

class player2
{
public:
player2();
~player2();

static const int x = 800 - 30;
float y;
float speed;

void wallCollide();

protected:

};

class Cball
{

public:
Cball();
~Cball();

float x, y;
float speed;
bool moving;

int sendDir();
};
#endif```
platformP2.cpp
Code:
```#include "objects.h"

player2::player2(){
y = 236;
speed = 500;
}

player2::~player2(){
}

void player2::wallCollide(){
if(y>600 - 65) {y = 600 - 65;}
if(y<1) {y = 1;}

}```
ball.cpp
Code:
```#include "objects.h"

Cball::Cball(){
x = 400;
y = 300;
speed = 250;
moving = false;
}

Cball::~Cball(){
}```

10. and matsp, try using srand() and ctime(), and post on here, I got told that made it more random xP
If you've got the time that is!

11. Originally Posted by Akkernight
and matsp, try using srand() and ctime(), and post on here, I got told that made it more random xP
If you've got the time that is!
I intentionally used THE SAME srand() seed so that it can be reproducable [ok, so we're calling rand a differnet number of times, but the point is that any value you pass into srand() simply gives you a starting point. Eventually you get back the same sequence anyways - it's just a matter of time. So starting from the same place is a good thing in this case.

Note that other random number generators will give different results. But I think it's clear that repeating rand is not better...

--
Mats

12. Originally Posted by Akkernight
and matsp, try using srand() and ctime(), and post on here, I got told that made it more random xP
If you've got the time that is!
I think you mean std::time() from <ctime>, which is a common way to seed with srand(). It would not make the PRNG "more random". What it would do is provide a convenient way to generate a seed at random.

Originally Posted by matsp
I intentionally used THE SAME srand() seed so that it can be reproducable [ok, so we're calling rand a differnet number of times, but the point is that any value you pass into srand() simply gives you a starting point. Eventually you get back the same sequence anyways - it's just a matter of time. So starting from the same place is a good thing in this case.
Of course, just because you generate a seed at random does not mean you cannot reuse it by saving it into a variable

13. Originally Posted by laserlight
Of course, just because you generate a seed at random does not mean you cannot reuse it by saving it into a variable
Of course not. I meant that if someone else wants to try the same thing, it will (assuming the same C library) give the same result - not just my machined doing what it does. I doubt it makes much difference - it is fairly clear in the results I got that rand isn't terribly bad at "tossing a coin" type stuff.

Also tried "Mersenne Twister":
http://www.bedaux.net/mtrand/

It gives slightly better results than rand (with code changed to do 100000 iterations):
Code:
```Iterations: 100000
Zeros: 50043 Ones: 49957
Longest sequence: 16
Doubles: 49839
Sum: 49957```
--
Mats