Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 204 205 [206] 207 208 ... 796

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

mendonca

  • Bay Watcher
  • [CLIVE]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3075 on: October 11, 2012, 06:26:34 am »

I don't know, it sounds more like just the system failing to check variables in this case or that rather than race conditions to me ...

I'm slightly ignorant about the proper terminology, but this sounds about right.

The code seems to be finding ways to execute actions I don't think it should be acting, and due to the way the code is set up, I find it difficult to properly understand why.

It's not to suggest that I can't find out why (I'm sure I can) but rather I want to be in a position whereby I don't need to constantly check why, in every relevant function. This might solve my problem, but if I can implement a more robust method it means that future actions / functions can afford to be general and not risk e.g. dead people acting on non-existent dungeons.

This is pretty much what I have:



I think I'm struggling with residual motives when Heroes get kicked out of dead dungeons ... Hmm.
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #3076 on: October 11, 2012, 06:31:27 am »

Hmm... not sure if this will help or work, but you could have an "action" function be in the hero class/whatever the structure is, and make a list of all the heroes then step through them one by one. If a hero dies, his function isn't in the list anymore, so nothing happens...

You're at least not using an if-then function, and having an method that assures heroes are alive. But I'm not sure if the way you made your game works like that.

As always, there's the "may be better methods" disclaimer.
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

GalenEvil

  • Bay Watcher
    • View Profile
    • Mac-Man Games
Re: if self.isCoder(): post() #Programming Thread
« Reply #3077 on: October 11, 2012, 11:34:44 pm »

Depending on the language and how you set things up the 'does not exist anymore' fail mitigation has different implementations. A basic way of getting it done would be have the actor and target sent into a method pertaining to the action required, and first checking to see if both actor and target are valid (non-null) and failing in a safe way if either of them are null.

In C# you can do a quick if(target == null || actor == null){ ... do action stuff}else{.. fail out}

That is one way to do it and it's localized to the target and actor specifically. You could probably have the return type as an integer with return values: 0 = all went okay, 1 = actor is null, 2 = target is null, ..., n = some other failure type :P

Hope that helps
Logged
Fun is Fun......Done is Done... or is that Done is !!FUN!!?
Quote from: Mr Frog
Digging's a lot like surgery, see -- you grab the sharp thing and then drive the sharp end of the sharp thing in as hard as you can and then stuff goes flying and then stuff falls out and then there's a big hole and you're done. I kinda wish there was more screaming, but rocks don't hurt so I guess it can't be helped.

TSTwizby

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3078 on: October 12, 2012, 01:37:16 am »

Quick python question:

I'm just starting out learning the language, but have some experience with C++, Actionscript, Assembly. Playing around with Pygame, trying to make a 'button' object which has a pair of images associated with it (pressed and released) and a function which is called when the button is pressed. I'd like to make that function customizable, so I can do something like:

button1 = Button(stuff)

def action(things):
   other stuff

button1.onpressed = action

and have action happen when button1 is pressed. I've tried a few things similar to what I wrote and none of them work. I've tried searching for help online, but all I can find are documentation or questions on the use of the button objects in various libraries.

If something like this is impossible, any suggestions as to an alternative would be appreciated.
Logged
I got a female and male dragon on my embark. I got cagetraps on the exits but im struggling to find a way to make them path into it.
Live bait.
3 dwarfs out of 7 dead so far

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3079 on: October 12, 2012, 07:43:54 am »

You can do the following:
Code: [Select]
class Button {
  Button(Action * action, Image pressedImage, Image releasedImage): actionOnPressed(action), imgPressed(pressedImage), imgReleased(releasedImage) {...}
  Action * actionOnPressed;
  Image imgPressed, imgReleased;
  boolean isPressed;
  void onPressed() { actionOnPressed->Execute(); isPressed = true;}
  void onRender(int x, int y);
  // more stuff
};
Code: [Select]
class Action {
  virtual void Execute() = null; // Abstract method!
};

class QuitAction: Action {
  QuitAction() {}
  void Execute() {Game::instance()->quit();}
};

class CheatAction: Action {
  CheatAction(int healing): amount(healing) {} //Note that the QuitAction and CheatAction constructors have different signatures
  int amount;
  void Execute() {Game::instance()->getProtagonist()->addToHealth(amount);}
};
Code: [Select]
class ScreenBuilder {
  //...
  void buildScreen {
    screenManager->addToDisplayObjects(new Button(new QuitAction(), quitButtonPressedImage, quitButtonReleasedImage), quitButtonCoordinates);
    screenManager->addToDisplayObjects(new Button(new CheatAction(50), cheatButtonPressedImage, cheatButtonReleasedImage), cheatButtonCoordinates);
                // You can have multiple cheat buttons with different healing values
  }
  //...
}
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3080 on: October 12, 2012, 08:45:01 am »

You can do the following:
Code: [Select]
class Button {
  Button(Action * action, Image pressedImage, Image releasedImage): actionOnPressed(action), imgPressed(pressedImage), imgReleased(releasedImage) {...}
  Action * actionOnPressed;
  Image imgPressed, imgReleased;
  boolean isPressed;
  void onPressed() { actionOnPressed->Execute(); isPressed = true;}
  void onRender(int x, int y);
  // more stuff
};
Code: [Select]
class Action {
  virtual void Execute() = null; // Abstract method!
};

class QuitAction: Action {
  QuitAction() {}
  void Execute() {Game::instance()->quit();}
};

class CheatAction: Action {
  CheatAction(int healing): amount(healing) {} //Note that the QuitAction and CheatAction constructors have different signatures
  int amount;
  void Execute() {Game::instance()->getProtagonist()->addToHealth(amount);}
};
Code: [Select]
class ScreenBuilder {
  //...
  void buildScreen {
    screenManager->addToDisplayObjects(new Button(new QuitAction(), quitButtonPressedImage, quitButtonReleasedImage), quitButtonCoordinates);
    screenManager->addToDisplayObjects(new Button(new CheatAction(50), cheatButtonPressedImage, cheatButtonReleasedImage), cheatButtonCoordinates);
                // You can have multiple cheat buttons with different healing values
  }
  //...
}

I... think you missed the point. He's trying to do that in Python.

TSTwizby, make a derived class, and __init__ that:

Code: [Select]
class DerivedButton(Button):
    def __init__(self, stuff):
        super(Button, self, stuff)
        self.onpressed = self.action
    def action(self, things):
        # do stuff to things

That should work a bit better.

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3081 on: October 12, 2012, 03:51:11 pm »

You can do the following:
Spoiler: Code (click to show/hide)

I... think you missed the point. He's trying to do that in Python.

TSTwizby, make a derived class, and __init__ that:

Code: [Select]
class DerivedButton(Button):
    def __init__(self, stuff):
        super(Button, self, stuff)
        self.onpressed = self.action
    def action(self, things):
        # do stuff to things

That should work a bit better.

Actually, my focus was on the model, not the implementation. Since I can't Python and he said that he has experience in C++, I just wrote the thing in C++ instead. In fact I started in pseudocode, but it already looked too similar to C++ so I just adjusted the rest.
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3082 on: October 12, 2012, 04:05:45 pm »

Actually, my focus was on the model, not the implementation. Since I can't Python and he said that he has experience in C++, I just wrote the thing in C++ instead. In fact I started in pseudocode, but it already looked too similar to C++ so I just adjusted the rest.

The implementation for the Button object is already there in Pygame. He just needed it to do something that the class couldn't do by itself, so making a subclass is the quickest fix.

TSTwizby

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3083 on: October 12, 2012, 07:24:56 pm »

I... think you missed the point. He's trying to do that in Python.

TSTwizby, make a derived class, and __init__ that:

Code: [Select]
class DerivedButton(Button):
    def __init__(self, stuff):
        super(Button, self, stuff)
        self.onpressed = self.action
    def action(self, things):
        # do stuff to things

That should work a bit better.

Thanks to both of you, but you are also kind of missing the point. I might be misunderstanding your code, but it looks like it would have me, whenever I want a new button, to make a new derived button class with information on what I want the button to do. What I'd like to do, if possible, is to have a single class, instances of which can have different 'onpressed' functions. (So if I want a button which opens the menu, a button that pauses the game, and a button which quits I don't need a 'menubutton' 'pausebutton' and 'quitbutton' class, but can instead just have a 'button' class with an 'onpressed' function which can be set to do whatever I want. I've actually found a workaround for my initial problem, but I'd still like to know how to do this (if it is possible) for future reference.
Logged
I got a female and male dragon on my embark. I got cagetraps on the exits but im struggling to find a way to make them path into it.
Live bait.
3 dwarfs out of 7 dead so far

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3084 on: October 12, 2012, 11:46:14 pm »

I... think you missed the point. He's trying to do that in Python.

TSTwizby, make a derived class, and __init__ that:

Code: [Select]
class DerivedButton(Button):
    def __init__(self, stuff):
        super(Button, self, stuff)
        self.onpressed = self.action
    def action(self, things):
        # do stuff to things

That should work a bit better.

Thanks to both of you, but you are also kind of missing the point. I might be misunderstanding your code, but it looks like it would have me, whenever I want a new button, to make a new derived button class with information on what I want the button to do. What I'd like to do, if possible, is to have a single class, instances of which can have different 'onpressed' functions. (So if I want a button which opens the menu, a button that pauses the game, and a button which quits I don't need a 'menubutton' 'pausebutton' and 'quitbutton' class, but can instead just have a 'button' class with an 'onpressed' function which can be set to do whatever I want. I've actually found a workaround for my initial problem, but I'd still like to know how to do this (if it is possible) for future reference.

Function pointers! Yay!

Code: [Select]
def do_something(obj, things):
# Do stuff

class DerivedButton(Button):
def __init__(self, action_fn, stuff):
self.action_fn = action_fn
self.stuff = stuff
def onpressed(self, things):
return self.action_fn(self, things)

but1 = DerivedButton(do_something, some_stuff)

TSTwizby

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3085 on: October 13, 2012, 12:11:54 am »

Yes! That's exactly what I wanted, thank you!
Logged
I got a female and male dragon on my embark. I got cagetraps on the exits but im struggling to find a way to make them path into it.
Live bait.
3 dwarfs out of 7 dead so far

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3086 on: October 13, 2012, 12:25:57 am »

Yes! That's exactly what I wanted, thank you!

You're welcome! Function pointers exist in Python, just like in C and C++. The only difference is, they're MUCH easier to use, since they look just like objects with the () operator defined. Not unlike the wrapper classes in <functional> in the C++ Standard Library.

MadocComadrin

  • Bay Watcher
  • A mysterious laboratory goblin!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3087 on: October 13, 2012, 12:45:39 am »

Aren't they exactly objects with the () operator defined? Or am I thinking of a different language?
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3088 on: October 13, 2012, 01:06:58 am »

Aren't they exactly objects with the () operator defined? Or am I thinking of a different language?

That sounds like Ruby, although it may be implemented that way in Python. The declaration is different, though, between functions and objects that act like functions.

da_nang

  • Bay Watcher
  • Argonian Overlord
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #3089 on: October 15, 2012, 09:15:35 am »

So I got into a friendly argument with the lecturer on data structures, regarding the time complexity of a heapsorting function. I hadn't previously seen a heapsort algorithm before but I was familiar with the structure of min and max heaps and the standard enqueue/dequeue functions, so I decided to take a stab at it. Now memory-wise, it's worse than Wikipedia's (O(n) extra memory required compared to O(1)), but I have assumed that memory isn't an issue and therefore I will only focus on the time complexity.

Pseudocode(ish) for some integer array with size N:
Code: [Select]
int[] toSort = new int[N];
MinHeap heap = new MinHeap(toSort.length);//Standard binary minimum heap

for(int i : toSort) {
  heap.enqueue(i);
}

for(int i = 0; i < toSort.length; i++) {
  toSort[i] = heap.dequeue();
}

The lecturer told me that this is still O(N*log2 N) time complexity, I would like to dispute that.

Now, let's start by looking at the enqueue-function. What's the worst case scenario? That would be O(log2 N) i.e. moving the element to the leaf level. From here, it's easy to see how one can say that the worst case time complexity for the entire function would be O(N*log2 N) as you can derive it from 2*O(N)*(log2 N) based on the standard operations with Big-O notation. However, since O(log2 N) is the worst case scenario i.e. the upper bound for enqueue (and dequeue), one can write the exact worst case time complexity as T(N) = a*log2(b*N) + T0(N), where a,b are positive non-zero constants and T0(N) is a collection of terms whose time complexity is less than O(log2 N). Note that for N=0, T(0) = 1, since enqueue on an empty heap is constant. It also avoids the singularity.

What I've done here is try to recreate the exact time function while at the same time accounting for information that is lost when using Big-O notation. Note that the dequeue function has an exact time function similar in structure to the one mentioned.

What is the exact worst case time complexity of the first for-loop? Let's call it T1(N).

T1(N) = T(0) + T(1) + T(2) + T(3) + ... T(N-2) + T(N-1)  (Note that there is no T(N)-term as we would have nothing more to add.)
This can be rewritten:
T1(N) = i=0ΣN-1 T(i) = 1 + i=1ΣN-1 T(i) = 1 + i=1ΣN-1 (a*log2(b*i) + T0(i))
= 1 + a*i=1ΣN-1 log2(b*i) + i=1ΣN-1T0(i)  (Using the logarithmic identity log(a*b) = log(a) + log(b), we get the following)
= 1 + a*log2(i=1N-1b*i) + i=1ΣN-1T0(i)
= 1 + a*log2(bN-1*i=1N-1i) + i=1ΣN-1T0(i)    (Identity: i=1nn = n!)
= 1 + a*log2(bN-1*(N-1)!) + i=1ΣN-1T0(i)   (Let T*(N) = i=1ΣN-1T0(i))
= 1 + a*log2(bN-1*(N-1)!) + T*(N)
= 1 + a*(log2(bN-1) + log2((N-1)!)) + T*(N)   (Identity: loga(b) = logc(d)/logc(a))
= 1 + a*(logb(bN-1)/logb(2) + log2((N-1)!)) + T*(N)    (Identity:  loga(ab) = b)
= 1 + a*((N-1)/logb(2) + log2((N-1)!)) + T*(N)
= 1 + a(N-1)/logb(2) + a*log2((N-1)!) + T*(N)

Now what happens to T1(N) when N grows large?
O(1 + a(N-1)/logb(2) + a*log2((N-1)!) + T*(N))   (constant terms are dropped due to relative size)
= O(a(N-1)/logb(2) + a*log2((N-1)!) + T*(N))
= O(a*N/logb(2) + a*log2(N!) + T*(N))    (constants coefficients are dropped as the order of magnitude is still the same)
= O(N + log2(N!) + T*(N))

Which of these last terms have the largest order of magnitude? We know that log2(N!) grows faster than N, so N is dropped. What about T*(N)? It has an upper bound of (N-1)*T0(N), and
T0(N) is the collection of terms with an order of magnitude smaller than log2(n) so it can be reasoned that log2(N!) has a larger order of magnitude.

Thus, O(log2 N!) is the time complexity for the first loop and, WLOG, second loop.

Worst case then, this sorting function has a time complexity of 2*O(log2 N!) = O(log2 N!), which is better than O(N*log2 N)

Now I'm no computer scientist nor am I a computer engineer (yet), so I ask you all: Am I onto something, or am I just narrowing the complexity to a more exact value? Or is there an error in my reasoning?
« Last Edit: October 15, 2012, 09:23:29 am by da_nang »
Logged
"Deliver yesterday, code today, think tomorrow."
Ceterum censeo Unionem Europaeam esse delendam.
Future supplanter of humanity.
Pages: 1 ... 204 205 [206] 207 208 ... 796