scratchfoundation / scratch-flash

Open source version of the Scratch 2.0 project editor. This is the basis for the online and offline versions of Scratch found on the website.
https://scratch.mit.edu
GNU General Public License v2.0
1.33k stars 512 forks source link

Strange behavior on evaluation by multiple agents #588

Closed cslaviero closed 9 years ago

cslaviero commented 9 years ago

Hello there,

I'm trying to build a simple version of the Dining Philosophers, which is available at http://scratch.mit.edu/projects/40307764/ . Each of the agents evaluates if there is a fork available in both it's "left" and "right" sides. If it sees both forks, then the "philosopher" takes them by hiding the sprites (using a message that only its left and right forks can listen).

The behavior I expected was that only two philosophers would be able to get both forks, since there is not enough forks available to all of them. However, what happens is that all of the philosophers get forks, which in my perspective is not correct. When I run the code manually (by clicking in each philosophers' code to make it run), this behavior happens.

What I'd like to know is whether this behavior is somehow correct, since from what I could read, Scratch has a sequential behavior when running a program. In my programming I could not find any mistake that could be related to this non expected behavior.

Thanks.

TheLogFather commented 9 years ago

I think I see the problem...

Are you expecting a broadcast to be received and executed immediately, before any other scripts get a chance to run? That's not the case...

What's happening is that the broadcasts get sent, but the Green Flag scripts all run before the receive scripts get started up.

It's only once all GF scripts have finished (and all costumes switched) that the receive scripts get a look in.

The way the Scratch execution engine works is that it executes each script of particular type of event (e.g. GreenFlag) to the end, or until it hits the end of a loop that contains a screen update (e.g. move, switch costume, etc.). It then moves on to the next one of the same event. Once there are no scripts left to start for that type of event then it moves on to the next type of event (or it starts the next loop through scripts that haven't finished, but yielded because they reached the end of a loop with a screen update).

Does that make sense...?

cslaviero commented 9 years ago

Yes it makes sense @TheLogFather :) So it's not a bug, it's a feature, that's good to know :) I've changed the evaluation to global variables representing the forks instead of checking if they are touching the philosopher sprites and it worked as I would expect. However I'm still wondering if this is the only way of doing it. Will this only be possible by using this kind of abstraction (variables representing the state of each fork)?

TheLogFather commented 9 years ago

I'd suggest you use broadcasts to control the sequence of execution more precisely.

In other words, have the Nth "philosopher" start its check when it receives "Check N" (where N goes from 1 to 5), and each one ends by broadcasting to start the next (and GreenFlag broadcasts to start the first one).

Or you could have a GreenFlag script that does "broadcast [Check 1] and wait / broadcast [Check 2] and wait / etc...", so it's getting each to check in turn, all sequentially.

(At this point I think we're really into what the "Help with Scripts" forum is for, rather than here...)

2jour commented 9 years ago

@TheLogFather, thank you for your help.

I looked at the Dining Philosophers project, @cslaviero. @TheLogFather is right. His suggestions will help you control the flow for checking if a philosopher has a fork.

It looks like the issue is closed . @cslaviero, if you think that there is still an issue please reopen :)