Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 322 323 [324] 325 326 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 907612 times)

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #4845 on: August 27, 2013, 03:36:56 pm »

I think I just accomplished a scarily nice looking way to do composite Assertions in natural language for my C++ Unit Testing library.

Code: [Select]
AssertThat(12, Is::LessThan(15) && Is::GreaterThan(13));
AssertThat(28, Is::LessThan(13) || Is::GreaterThan(19));
AssertThat(15, !(Is::LessThan(13) || Is::GreaterThan(19)));
AssertThat(15, Is::Not::LessThan(13) && Is::Not::GreaterThan(19));

So much template wizardry have I learned, but at least the Macro wizardry is limited to like 5 functions at the highest level only that don't read too horribly...C++11, you so awesome :)
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4846 on: August 27, 2013, 03:46:56 pm »

I think I just accomplished a scarily nice looking way to do composite Assertions in natural language for my C++ Unit Testing library.

Code: [Select]
AssertThat(12, Is::LessThan(15) && Is::GreaterThan(13));
AssertThat(28, Is::LessThan(13) || Is::GreaterThan(19));
AssertThat(15, !(Is::LessThan(13) || Is::GreaterThan(19)));
AssertThat(15, Is::Not::LessThan(13) && Is::Not::GreaterThan(19));

So much template wizardry have I learned, but at least the Macro wizardry is limited to like 5 functions at the highest level only that don't read too horribly...C++11, you so awesome :)

I believe I almost see what you did and it's clever. How did you handle the boolean operators? Snazzy overloads?

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #4847 on: August 27, 2013, 04:08:29 pm »

Snazzy overloads and template metaprogramming to put them onto a CRTP base class. There are generic AndOperand, OrOperand and NotOperand functions that combine the "natural language assertion" constraints appropriately, with overloaded operators on the base class to call them. Also means brackets and such still work for operator precedence.

Kinda surprised it works, to be honest. But both VS2013 and GCC compile it. Overloading the boolean && and || operators does remove short-circuiting, but in the use cases here that's not really a concern. It's something I'd never do in "production" code, naturally, but for a testing library? Yes, I believe this is an acceptable allowance.

Basically the whole library is 90% template metaprogramming and 10% the actual fixture logic.

A basic test fixture looks like this: https://gist.github.com/MorleyDev/5362664
The functions needed to describe tests taking lambdas mean I don't need to do the macro hacks to setup a test like older unit testing libraries, such as CPPUnit, UnitTest++ and Google Test. The whole point of the library was more or less to prove C++11's capabilities for cleaner, less macro-heavy code and that proper testing is perfectly possible in C++.

And of course the tests for the library are examples of how to do more complex tests since they're all written using the library :)
« Last Edit: August 27, 2013, 04:34:56 pm by MorleyDev »
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4848 on: August 27, 2013, 04:35:59 pm »

Snazzy overloads and template metaprogramming to put them onto a CRTP base class. There are generic AndOperand, OrOperand and NotOperand functions that combine the "natural language assertion" constraints appropriately, with overloaded operators on the base class to call them. Also means brackets and such still work for operator precedence.

Kinda surprised it works, to be honest. But both VS2013 and GCC compile it. Overloading the boolean && and || operators does remove short-circuiting, but in the use cases here that's not really a concern. It's something I'd never do in "production" code, naturally, but for a testing library? Yes, I believe this is an acceptable allowance.

Basically the whole library is 90% template metaprogramming and 10% the actual fixture logic.

A basic test fixture looks like this: https://gist.github.com/MorleyDev/5362664
The functions needed to describe tests taking lambdas mean I don't need to do the macro hacks to setup a test like older unit testing libraries, such as CPPUnit, UnitTest++ and Google Test. The whole point of the library was more or less to prove C++11's capabilities for cleaner, less macro-heavy code and that proper testing is perfectly possible in C++.

And of course the tests for the library are examples of how to do more complex tests since they're all written using the library :)

That is an extremely clever use of CRTP. Kudos to you, good sir.

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #4849 on: August 27, 2013, 05:07:22 pm »

The main debate I'm having right now is whether or not to provide a xor overload. C++ doesn't have a logical xor, just bitwise ^. But the reason for that appears to be that x != y is the same as x xor y for booleans, and that ^ can't be short-circuited.

But since & and | can't be short-circuited, should I instead be providing Constraint & Constraint instead of Constraint && Constraint? Except I *do* have limited short-circuiting at the moment, since Constraint && Constraint will only call the first constraint if it fails, at least until it tries to figure out the error message to print. But Constraint && !Constraint will still not the latter constraint before producing the AndOperand...
Logged

dreadmullet

  • Bay Watcher
  • Inadequate Comedian
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4850 on: August 28, 2013, 09:34:51 am »

I have discovered a case where floats are more accurate than doubles:

Code: (C++) [Select]
#include <iostream>

int main(int numArgs , char** args){
   
   int testInt1 = ((0.1d + 0.7d) * 10);
   int testInt2 = ((0.1f + 0.7f) * 10);
   
   std::cout << "testInt1 = " << testInt1 << '\n';
   std::cout << "testInt2 = " << testInt2 << '\n';
   
   return 0;
   
}

Code: (Output) [Select]
testInt1 = 7
testInt2 = 8
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #4851 on: August 28, 2013, 09:50:40 am »

Very interesting.

For my edited code (to facilitate debugging)

Code: [Select]
#include <iostream>

using namespace std;

int main()
{
double d1 = 0.1;
double d2 = 0.7;
float f1 = 0.1f;
float f2 = 0.7f;
double doubleMiddle = ((d1 + d2) * 10);
float floatMiddle = ((f1 + f2) * 10);
int result1 = doubleMiddle;
int result2 = floatMiddle;

cout << "Doubles: " << result1 << endl;
cout << "Float: " << result2 << endl;
cin.get();
}

Peering into the locals with MSVS tells me that...

Code: [Select]
d1 0.10000000000000001 double
d2 0.69999999999999996 double
f1 0.10000000 float
f2 0.69999999 float
doubleMiddle 7.9999999999999991 double
floatMiddle 8.0000000 float

So yeah, the extra precision granted is actually hurting the overall precision. The added value is just shy of 8, so the int value is 7.

(incidentally, I think this is why you aren't supposed to compare floats directly. xD)
« Last Edit: August 28, 2013, 10:01:20 am by Skyrunner »
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Soadreqm

  • Bay Watcher
  • I'm okay with this. I'm okay with a lot of things.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4852 on: August 28, 2013, 02:46:00 pm »

Because the numbers are all stored in base two, you can only accurately represent powers of two.
0.12 = 2-110 = 0.510
0.001012 = 2-310 + 2-510 = 0.1562510
0.110 = 0.00011001100110011...2

So, yeah. Never directly compare floats. If the language you're working in doesn't come with one, code your own is-this-number-within-a-certain-range-of-this-other-number function and use that instead. And if you really need flawless precision, use integers for everything. It doesn't come up in most applications, but if the number represents someone's bank account balance or something, it's sometimes better to play it safe.
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #4853 on: August 29, 2013, 09:14:41 am »

N-body sim

I just made some quick changes to it.

The main problems I have are two.

(1) The cluster kinda floats off-screen, as you can see between 69 and 205 steps, and I can't think of a way to make it scroll easily and painlessly. x3

(2) It runs at 2 fps at 3000 particles. I want more particles. MOAR
Currently it's only single-threaded, so I might be able to multithread it for a cheap and easy x4 speedup. Still only'd be 12000 8000 particles...
« Last Edit: August 29, 2013, 09:37:45 am by Skyrunner »
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

alway

  • Bay Watcher
  • 🏳️‍⚧️
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4854 on: August 29, 2013, 09:29:02 am »

For 1, add in an offset for the camera/display. Have the offset be based on the average position of the points, to keep the average position in the center. So offset = avgPos - viewDimensions/2. And then simply something like:
Code: [Select]
GetRenderPoint(pos)
{
   return pos - offset;
}
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #4855 on: August 29, 2013, 09:35:19 am »

I actually made the offset be manually controlled by the person viewing it, but the main problem is that (because how Allegro handles key events) if the FPS can't be kept up because it takes to long to sim, it becomes unresponsive.

Here's a crude video I took of 1000 objects. :D Funnily, it doesn't look like one thousand. Maybe it's because like half of them fly off within 50 steps.
edit: video of 4000 objects. It's suddenly a lot slower (n^2 complexity killed the cat), but it also looks a lot more interesting. Darnit :<

One problem with the average offset I can think of is that if the entire cluster spreads in more than one direction, you'll be staring at a blank space.

edit2: I just realized I was listening to music while taking that video :P It's kinda appropriate, though. To life, to life! I'll bring them back to life!
« Last Edit: August 29, 2013, 09:39:48 am by Skyrunner »
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Rose

  • Bay Watcher
  • Resident Elf
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4856 on: August 29, 2013, 09:42:04 am »

Well, multi-threading the physics processing will instantly let you scroll around without the physics slowing down the graphical FPS
Logged

Dutchling

  • Bay Watcher
  • Ridin' with Biden
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4857 on: August 29, 2013, 07:47:31 pm »

Err, does anyone know what this means/is?
Code: [Select]
>>> 0x1
1
>>> 0x2
2
>>> 0x100
256
>>> 0x200
512
>>> 0x3
3
>>> 0x4
4
>>> 0x4
4
>>> 0x34
52
>>> 0x700
1792
>>> 0x43
67
>>> 0x654
1620
Logged

Rose

  • Bay Watcher
  • Resident Elf
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4858 on: August 29, 2013, 07:49:54 pm »

looks like a hex to decimal converter.
Logged

ECrownofFire

  • Bay Watcher
  • Resident Dragoness
    • View Profile
    • ECrownofFire
Re: if self.isCoder(): post() #Programming Thread
« Reply #4859 on: August 29, 2013, 07:50:31 pm »

I actually made the offset be manually controlled by the person viewing it, but the main problem is that (because how Allegro handles key events) if the FPS can't be kept up because it takes to long to sim, it becomes unresponsive.

http://gafferongames.com/game-physics/fix-your-timestep/

Err, does anyone know what this means/is?
-snip-

That's a CLI for some scripting language (Python?).
« Last Edit: August 29, 2013, 07:52:34 pm by ECrownofFire »
Logged
Pages: 1 ... 322 323 [324] 325 326 ... 796