Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
ping
Aug 15, 2001

by Lowtax
Written by my students, Computer Scientists at the end of their second year at a top 3 institution. Code for collision detection in a Pac Man clone.

code:
	public void checkWallCollision() {
		
		
		if (((playerx1[0] == 20  && (p1moveleft) ||
				
				((playerx1[0] == 80 || playerx1[0] == 500) && 
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 260 && playery1[0] != 280 && playery1[0] != 500 && playery1[0] != 520) 
             && (p1moveleft)) ||
             
				(((playerx1[0] == 140 || playerx1[0] == 440)&&
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 80 && playery1[0] != 100 && playery1[0] != 180 && playery1[0] != 200  
&& playery1[0] != 340 && playery1[0] != 360 && playery1[0] != 440 && playery1[0] != 460 && playery1[0] != 500 && playery1[0] != 520) 
          && (p1moveleft)) ||
          
          (((playerx1[0] == 200 || playerx1[0] == 380) &&
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 80 && playery1[0] != 100 && playery1[0] != 140 && playery1[0] != 160  
&& playery1[0] != 260 && playery1[0] != 280 && playery1[0] != 380 && playery1[0] != 400 
&& playery1[0] != 440 && playery1[0] != 460 && playery1[0] != 500 && playery1[0] != 520) 
          && (p1moveleft)) ||
          
          (((playerx1[0] == 260 || playerx1[0] == 320) &&
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 80 && playery1[0] != 100 && playery1[0] != 140 && playery1[0] != 160  
&& playery1[0] != 200 && playery1[0] != 340 && playery1[0] != 380 && playery1[0] != 400 &&  playery1[0] != 440 
&& playery1[0] != 460 && playery1[0] != 500 && playery1[0] != 520) 
          && (p1moveleft)) ||
          
          ((playerx1[0] == 160 || playerx1[0] == 360) && playery1[0] == 120 || playery1[0] == 420) 
        		                       && (p1moveleft))
          
          
          || ( (ghostx1[0]==20 && (ghostmoveleft)) 
			|| (ghostx1[0]==80 && 
 ghosty1[0]!=20 && ghosty1[0]!=40 && ghosty1[0] != 260 && ghosty1[0] != 280 && ghosty1[0] != 500 && ghosty1[0] != 520) 
 && (ghostmoveleft))  ||
 
	(((ghostx1[0] == 140 || ghostx1[0] == 440)&&
ghosty1[0] != 20 && ghosty1[0] != 40 && ghosty1[0] != 80 && ghosty1[0] != 100 && ghosty1[0] != 180 && ghosty1[0] != 200  
&& ghosty1[0] != 340 && ghosty1[0] != 360 && ghosty1[0] != 440 && ghosty1[0] != 460 && ghosty1[0] != 500 && ghosty1[0] != 520) 
&& (ghostmoveleft)) ||

(((ghostx1[0] == 200 || ghostx1[0] == 380) &&
ghosty1[0] != 20 && ghosty1[0] != 40 && ghosty1[0] != 80 && ghosty1[0] != 100 && ghosty1[0] != 140 && ghosty1[0] != 160  
&& ghosty1[0] != 260 && ghosty1[0] != 280 && ghosty1[0] != 380 && ghosty1[0] != 400 
&& ghosty1[0] != 440 && ghosty1[0] != 460 && ghosty1[0] != 500 && ghosty1[0] != 520) 
&& (ghostmoveleft)) ||

(((ghostx1[0] == 260 || ghostx1[0] == 320) &&
ghosty1[0] != 20 && ghosty1[0] != 40 && ghosty1[0] != 80 && ghosty1[0] != 100 && ghosty1[0] != 140 && ghosty1[0] != 160  
&& ghosty1[0] != 200 && ghosty1[0] != 340 && ghosty1[0] != 380 && ghosty1[0] != 400 &&  ghosty1[0] != 440 
&& ghosty1[0] != 460 && ghosty1[0] != 500 && ghosty1[0] != 520) 
&& (ghostmoveleft))
|| ((ghostx1[0] == 160 || ghostx1[0] == 360) && ghosty1[0] == 120 || ghosty1[0] == 420) 
&& (ghostmoveleft)){
			
			p1moveup = false;
			p1movedown = false;
			p1moveleft = false;
			p1moveright = false;
			
			 ghostmoveup = false;
			 ghostmovedown = false;
			 ghostmoveleft = false;
			 ghostmoveright = false;
		} 
		
		if ( ((playery1[0] == 20) && (p1moveup)) ||
				(((playery1[0] == 80 || playery1[0] == 500) && 
playerx1[0] != 20 && playerx1[0] != 40 && playerx1[0] != 260 && playerx1[0] != 280 && playerx1[0] != 500 && playerx1[0] != 520) 
             && (p1moveup)) ||
             
				(((playery1[0] == 140 || playery1[0] == 440) &&
playerx1[0] != 20 && playerx1[0] != 40 && playerx1[0] != 80 && playerx1[0] != 100 && playerx1[0] != 160 && playerx1[0] != 180  
&& playerx1[0] != 360 && playerx1[0] != 380 && playerx1[0] != 440 && playerx1[0] != 460 && playerx1[0] != 500 && playerx1[0] != 520) 
          && (p1moveup)) ||
          
          (((playery1[0] == 200 || playery1[0] == 380) &&
playerx1[0] != 20 && playerx1[0] != 40 && playerx1[0] != 80 && playerx1[0] != 100 && playerx1[0] != 120 && playerx1[0] != 140  
&& playerx1[0] != 160 && playerx1[0] != 260 && playerx1[0] != 280 && playerx1[0] != 380 && playerx1[0] != 400 
&& playerx1[0] != 420 && playerx1[0] != 440 && playerx1[0] != 460 && playerx1[0] != 500 && playerx1[0] != 520) 
          && (p1moveup)) ||
          
          (((playery1[0] == 340) && (playerx1[0] == 120 || playerx1[0] == 240 || playerx1[0] == 300 || playerx1[0] == 420)) 
        		  && (p1moveup)) 
          ||
          (((playery1[0] == 260) && (playerx1[0] == 60 || playerx1[0] == 180  || playerx1[0] == 360 || playerx1[0] == 480)) 
        		  && (p1moveup))
          || (((playery1[0] == 180) && (playerx1[0] == 120 || playerx1[0] == 420) ) && (p1moveup))
          
          
          || 
          ((ghosty1[0] == 20) && (ghostmoveup)) ||
			(((ghosty1[0] == 80 || ghosty1[0] == 500) && 
ghostx1[0] != 20 && ghostx1[0] != 40 && ghostx1[0] != 260 && ghostx1[0] != 280 && ghostx1[0] != 500 && ghostx1[0] != 520) 
       && (ghostmoveup)) ||
       
			(((ghosty1[0] == 140 || ghosty1[0] == 440) &&
ghostx1[0] != 20 && ghostx1[0] != 40 && ghostx1[0] != 80 && ghostx1[0] != 100 && ghostx1[0] != 160 && ghostx1[0] != 180  
&& ghostx1[0] != 360 && ghostx1[0] != 380 && ghostx1[0] != 440 && ghostx1[0] != 460 && ghostx1[0] != 500 && ghostx1[0] != 520) 
    && (ghostmoveup)) ||
    
    (((ghosty1[0] == 200 || ghosty1[0] == 380) &&
ghostx1[0] != 20 && ghostx1[0] != 40 && ghostx1[0] != 80 && ghostx1[0] != 100 && ghostx1[0] != 120 && ghostx1[0] != 140  
&& ghostx1[0] != 160 && ghostx1[0] != 260 && ghostx1[0] != 280 && ghostx1[0] != 380 && ghostx1[0] != 400 
&& ghostx1[0] != 420 && ghostx1[0] != 440 && ghostx1[0] != 460 && ghostx1[0] != 500 && ghostx1[0] != 520) 
    && (ghostmoveup)) ||
    
    (((ghosty1[0] == 340) && (ghostx1[0] == 120 || ghostx1[0] == 240 || ghostx1[0] == 300 || ghostx1[0] == 420)) 
  		  && (ghostmoveup)) 
    ||
    
    (((ghosty1[0] == 260) && (ghostx1[0] == 60 || ghostx1[0] == 180  || ghostx1[0] == 360 || ghostx1[0] == 480))
    		 && (ghostmoveup))
    ||
    
    (((ghosty1[0] == 180) && (ghostx1[0] == 120 || ghostx1[0] == 420 )) && (ghostmoveup))) {
			
			p1moveup = false;
			p1movedown = false;
			p1moveleft = false;
			p1moveright = false;
			
			 ghostmoveup = false;
			 ghostmovedown = false;
			 ghostmoveleft = false;
			 ghostmoveright = false;
		}
		if (((playerx1[0] == 520  && (p1moveright) ||
				
				((playerx1[0] == 40 || playerx1[0] == 460) && 
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 260 && playery1[0] != 280 && playery1[0] != 500 && playery1[0] != 520) 
             && (p1moveright)) ||
             
				(((playerx1[0] == 100 || playerx1[0] == 400)&&
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 80 && playery1[0] != 100 && playery1[0] != 180 && playery1[0] != 200  
&& playery1[0] != 340 && playery1[0] != 360 && playery1[0] != 440 && playery1[0] != 460 && playery1[0] != 500 && playery1[0] != 520) 
          && (p1moveright)) ||
          
          (((playerx1[0] == 160 || playerx1[0] == 340) &&
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 80 && playery1[0] != 100 && playery1[0] != 140 && playery1[0] != 160  
&& playery1[0] != 260 && playery1[0] != 280 && playery1[0] != 380 && playery1[0] != 400 
&& playery1[0] != 440 && playery1[0] != 460 && playery1[0] != 500 && playery1[0] != 520) 
          && (p1moveright)) ||
          
          (((playerx1[0] == 220 || playerx1[0] == 280) &&
playery1[0] != 20 && playery1[0] != 40 && playery1[0] != 80 && playery1[0] != 100 && playery1[0] != 140 && playery1[0] != 160  
&& playery1[0] != 200 && playery1[0] != 340 && playery1[0] != 380 && playery1[0] != 400 &&  playery1[0] != 440 
&& playery1[0] != 460 && playery1[0] != 500 && playery1[0] != 520) 
          && (p1moveright)) )
          
          
          || ( (ghostx1[0]==520 && (ghostmoveright)) 
			|| ((ghostx1[0]==40  || ghostx1[0] == 460) &&
 ghosty1[0]!=20 && ghosty1[0]!=40 && ghosty1[0] != 260 && ghosty1[0] != 280 && ghosty1[0] != 500 && ghosty1[0] != 520) 
 && (ghostmoveright))  ||
 
	(((ghostx1[0] == 100 || ghostx1[0] == 400)&&
ghosty1[0] != 20 && ghosty1[0] != 40 && ghosty1[0] != 80 && ghosty1[0] != 100 && ghosty1[0] != 180 && ghosty1[0] != 200  
&& ghosty1[0] != 340 && ghosty1[0] != 360 && ghosty1[0] != 440 && ghosty1[0] != 460 && ghosty1[0] != 500 && ghosty1[0] != 520) 
&& (ghostmoveright)) ||

(((ghostx1[0] == 160 || ghostx1[0] == 340) &&
ghosty1[0] != 20 && ghosty1[0] != 40 && ghosty1[0] != 80 && ghosty1[0] != 100 && ghosty1[0] != 140 && ghosty1[0] != 160  
&& ghosty1[0] != 260 && ghosty1[0] != 280 && ghosty1[0] != 380 && ghosty1[0] != 400 
&& ghosty1[0] != 440 && ghosty1[0] != 460 && ghosty1[0] != 500 && ghosty1[0] != 520) 
&& (ghostmoveright)) ||

(((ghostx1[0] == 220 || ghostx1[0] == 280) &&
ghosty1[0] != 20 && ghosty1[0] != 40 && ghosty1[0] != 80 && ghosty1[0] != 100 && ghosty1[0] != 140 && ghosty1[0] != 160  
&& ghosty1[0] != 200 && ghosty1[0] != 340 && ghosty1[0] != 380 && ghosty1[0] != 400 &&  ghosty1[0] != 440 
&& ghosty1[0] != 460 && ghosty1[0] != 500 && ghosty1[0] != 520) 
&& (ghostmoveright))) {
			
			p1moveup = false;
			p1movedown = false;
			p1moveleft = false;
			p1moveright = false;
			
			 ghostmoveup = false;
			 ghostmovedown = false;
			 ghostmoveleft = false;
			 ghostmoveright = false;
		}
		if (  ((playery1[0] == 520) && (p1movedown)) ||
				(((playery1[0] == 40 || playery1[0] == 460) && 
playerx1[0] != 20 && playerx1[0] != 40 && playerx1[0] != 260 && playerx1[0] != 280 && playerx1[0] != 500 && playerx1[0] != 520) 
             && (p1movedown)) ||
             
				(((playery1[0] == 100 || playery1[0] == 400) &&
playerx1[0] != 20 && playerx1[0] != 40 && playerx1[0] != 80 && playerx1[0] != 100 && playerx1[0] != 160 && playerx1[0] != 180  
&& playerx1[0] != 360 && playerx1[0] != 380 && playerx1[0] != 440 && playerx1[0] != 460 && playerx1[0] != 500 && playerx1[0] != 520) 
          && (p1movedown)) ||
          
          (((playery1[0] == 160 || playery1[0] == 340) &&
playerx1[0] != 20 && playerx1[0] != 40 && playerx1[0] != 80 && playerx1[0] != 100 && playerx1[0] != 120 && playerx1[0] != 140  
&& playerx1[0] != 160 && playerx1[0] != 260 && playerx1[0] != 280 && playerx1[0] != 380 && playerx1[0] != 400 
&& playerx1[0] != 420 && playerx1[0] != 440 && playerx1[0] != 460 && playerx1[0] != 500 && playerx1[0] != 520) 
          && (p1movedown)) ||
          
          (((playery1[0] == 200) && (playerx1[0] == 120 || playerx1[0] == 240 || playerx1[0] == 300 || playerx1[0] == 420)) 
        		  && (p1movedown)) 
          ||
          (((playery1[0] == 280) && (playerx1[0] == 60 || playerx1[0] == 180  || playerx1[0] == 360 || playerx1[0] == 480)) 
        		  && (p1movedown))
          || (((playery1[0] == 360) && (playerx1[0] == 120 || playerx1[0] == 420) ) && (p1movedown))
          
          
          || 
          ((ghosty1[0] == 520) && (ghostmovedown)) ||
			(((ghosty1[0] == 40 || ghosty1[0] == 460) && 
ghostx1[0] != 20 && ghostx1[0] != 40 && ghostx1[0] != 260 && ghostx1[0] != 280 && ghostx1[0] != 500 && ghostx1[0] != 520) 
       && (ghostmovedown)) ||
       
			(((ghosty1[0] == 100 || ghosty1[0] == 400) &&
ghostx1[0] != 20 && ghostx1[0] != 40 && ghostx1[0] != 80 && ghostx1[0] != 100 && ghostx1[0] != 160 && ghostx1[0] != 180  
&& ghostx1[0] != 360 && ghostx1[0] != 380 && ghostx1[0] != 440 && ghostx1[0] != 460 && ghostx1[0] != 500 && ghostx1[0] != 520) 
    && (ghostmovedown)) ||
    
    (((ghosty1[0] == 160 || ghosty1[0] == 340) &&
ghostx1[0] != 20 && ghostx1[0] != 40 && ghostx1[0] != 80 && ghostx1[0] != 100 && ghostx1[0] != 120 && ghostx1[0] != 140  
&& ghostx1[0] != 160 && ghostx1[0] != 260 && ghostx1[0] != 280 && ghostx1[0] != 380 && ghostx1[0] != 400 
&& ghostx1[0] != 420 && ghostx1[0] != 440 && ghostx1[0] != 460 && ghostx1[0] != 500 && ghostx1[0] != 520) 
    && (ghostmovedown)) ||
    
    (((ghosty1[0] == 200) && (ghostx1[0] == 120 || ghostx1[0] == 240 || ghostx1[0] == 300 || ghostx1[0] == 420)) 
  		  && (ghostmovedown)) 
    ||
    
    (((ghosty1[0] == 280) && (ghostx1[0] == 60 || ghostx1[0] == 180  || ghostx1[0] == 360 || ghostx1[0] == 480))
    		 && (ghostmovedown))
    ||
    
    (((ghosty1[0] == 360) && (ghostx1[0] == 120 || ghostx1[0] == 420 )) && (ghostmovedown))) {
			
			p1moveup = false;
			p1movedown = false;
			p1moveleft = false;
			p1moveright = false;
			
			 ghostmoveup = false;
			 ghostmovedown = false;
			 ghostmoveleft = false;
			 ghostmoveright = false;
		}
	
			
			

}

ping fucked around with this message at 17:26 on Mar 31, 2014

Adbot
ADBOT LOVES YOU

Pythagoras a trois
Feb 19, 2004

I have a lot of points to make and I will make them later.

ping posted:

Written by my students, Computer Scientists at the end of their second year at a top 3 institution. Code for collision detection in a Pac Man clone.

I wrote something surprisingly similar in my early 20's. Of course, at the time I was a fresh Chemistry graduate and my only coding experience was copy/pasting other people's code while waiting for experiments to finish at my first job.

Goat Bastard
Oct 20, 2004

Sagacity posted:

you could also, you know, have methods that accept a DateTime as input instead of having to inject some kind of nonsensical DateTimeProvider.

Because the only time you ever need the value of now is at the time a function is entered?

Cancelbot
Nov 22, 2006

Canceling spam since 1928

Further to the C# dart throwing I do (snipped type names);

code:
private Dictionary<long, Dictionary<DateTime, AllSnipBLL.RSnipImage>> _playerSnipStatuses;
As part of "optimisation" work. Guess what code imploded when we changed daylight savings time today? I won't even discuss the nested generics or the brain damage required to think this was a good idea.

:gonk:

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
ping: God. I see stuff like that every time I sit down to grade an assignment, even in classes which are mostly seniors. Most of the time I don't even know what to say to these kids. Are they lazy? Frustrated? Hopelessly confused? Trying to be funny?

…and why are your students writing a pacman clone in PHP of all things?

Zombywuf
Mar 29, 2008

Internet Janitor posted:

ping: God. I see stuff like that every time I sit down to grade an assignment, even in classes which are mostly seniors. Most of the time I don't even know what to say to these kids. Are they lazy? Frustrated? Hopelessly confused? Trying to be funny?

…and why are your students writing a pacman clone in PHP of all things?

It's probably because they were taught Object Orientation before, well, coding.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Zombywuf posted:

It's probably because they were taught Object Orientation before, well, coding.

Not a lot of object orientation on display in that code!

kitten smoothie
Dec 29, 2001

Internet Janitor posted:

ping: God. I see stuff like that every time I sit down to grade an assignment, even in classes which are mostly seniors. Most of the time I don't even know what to say to these kids. Are they lazy? Frustrated? Hopelessly confused? Trying to be funny?

This looks like the work product of a student who started in at 9pm the night before the due date and maybe even intended to do it "right." By 4am, they just said fuckit and every time it crashed or didn't do the right thing, rather than figure out the root cause they just taped on more copypasta code because that was all they had time to do.

Zombywuf
Mar 29, 2008

Subjunctive posted:

Not a lot of object orientation on display in that code!

Not a lot of anything on display in that code, except everything being a special case due to a lack of understanding.

down with slavery
Dec 23, 2013
STOP QUOTING MY POSTS SO PEOPLE THAT AREN'T IDIOTS DON'T HAVE TO READ MY FUCKING TERRIBLE OPINIONS THANKS

ping posted:

Written by my students, Computer Scientists at the end of their second year at a top 3 institution. Code for collision detection in a Pac Man clone.

Does it work?

ping
Aug 15, 2001

by Lowtax

I wanted to find out, but the rest of it is so broken it didn't even compile (it's Java BTW, I just used the php tag because I like the syntax highlighting), I think it's got a bunch of random libraries added to it that aren't even used in the project or included in the submission. For some reason the JavaMail API is included though. Not sure what that has to do with pac man.

They haven't really been taught much OO over the past two years beyond the basics. This is the first time where they've had to do something that didn't just involve copying verbatim off a oracle tutorial, or trivially modifying (hacking) something that's on the lecture slides.

Another horror is:
In the game, they have collectable coins. There are 20 coins in total. Each coin is defined in terms of it's X and Y position.

So far so good.

Those positions are defined like this:
code:
	coinx1[0] = 380;
	coiny1[0] = 40;

	coinx2[0] = 180;
	coiny2[0] = 80;
	...
	coinx20[0] = 520;
	coiny20[0] = 120;

JawnV6
Jul 4, 2004

So hot ...

Sagacity posted:

A better option would be what Ithaqua mentioned (pass in a Func) but you could also, you know, have methods that accept a DateTime as input instead of having to inject some kind of nonsensical DateTimeProvider.

And if it checks .Now() twice to monitor some time-consuming method, we'll just modify the function to take two DateTimes! Now our function under test is heavily modified and the values it pulls are completely fed by the environment. So we're testing fake code in a fake environment judged by fake input. Wow, why do people frown on unit testing again!?!?

shrughes
Oct 11, 2008

(call/cc call/cc)

Cancelbot posted:

Further to the C# dart throwing I do (snipped type names);

code:
private Dictionary<long, Dictionary<DateTime, AllSnipBLL.RSnipImage>> _playerSnipStatuses;
As part of "optimisation" work. Guess what code imploded when we changed daylight savings time today? I won't even discuss the nested generics or the brain damage required to think this was a good idea.

:gonk:

I'm confused. What is the horror here?

astr0man
Feb 21, 2007

hollyeo deuroga

ping posted:

(it's Java BTW, I just used the php tag because I like the syntax highlighting)

You can do:
pre:
[code="java"]
to get actual syntax highlighting!

Cancelbot
Nov 22, 2006

Canceling spam since 1928

shrughes posted:

I'm confused. What is the horror here?

Should have given more background;

Dictionaries are populated from the database, the DateTime key comes from a column using a UTC Date & Time. UI applies a filter over the dictionary using local date & time, this meant that once DST began today all the keys were off from the local time by one hour, throwing hundreds of exceptions when the accesses occurred by the DateTime key. The solution is to simply adjust the UTC date by the local times offset from UTC but that level of precision wasn't required anyway so the fix was to use DateTime.Date.

The real horror is DST. And if you're strict with .NET styling rules; nested generics are also an unnecessary complication.

Cancelbot fucked around with this message at 18:12 on Mar 31, 2014

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

JawnV6 posted:

And if it checks .Now() twice to monitor some time-consuming method, we'll just modify the function to take two DateTimes!

No, that's ridiculous. First of all, the caller wouldn't know the second time to pass because it doesn't know how long the operation took. Second, the values of startTimer and endTimer aren't interesting, just the relationship. (Unless you're testing the effects of time dilation on the code, I suppose.)

The point of passing in DateTime is that the semantics are "perform this operation with these inputs". Now() as the "when" input is one choice, and passing it in makes the function pure(r), which is almost always a virtue—cacheable, easier to reason about and test and refactor. State is the enemy, keep it small and contained. Passing a time generator in (explicitly or via DI) is more involved/ugly, but has roughly the same effect.

My issue with DI is the amount of boilerplate overhead in the source and at runtime. I've worked on projects that had to resort to preprocessing the DI code to be direct allocations in order to improve startup time, but that doesn't help the (usually pretty gross) source impact.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Subjunctive posted:

No, that's ridiculous.

:thejoke:

Subjunctive
Sep 12, 2006

✨sparkle and shine✨


Heh. No, I mean it's ridiculous to extrapolate from the use of now as related to behavior-as-of-when to use-of-timestamps-for-timing. But maybe that, too, is the joke.

Fellatio del Toro
Mar 21, 2009

ping posted:

Written by my students, Computer Scientists at the end of their second year at a top 3 institution. Code for collision detection in a Pac Man clone.

You're giving me flashbacks of Visual Basic class back in high school. Back when I had no concept of fancy "arrays" or "data structures" and tried to make a Space Invaders style game by explicitly coding each individual object. I programmed a few enemies, three different projectiles, then had to write code to check collision between each of them and every enemy. I made it to like 4 enemies before deciding there was no way my code should be growing exponentially with every object I added.

Instead I went back to pasting screenshots into a fake Windows program with dumb error messages that popped up when you clicked on different programs, and leaving that running when I left class.

No Safe Word
Feb 26, 2005

Cancelbot posted:

The real horror is DST.
Having done a fair amount of development work in the energy trading industry where it's very important to know what time things are, yeah. It's the loving worst.

return0
Apr 11, 2007

Sagacity posted:

It's a horror because what previously could've been a simple call to DateTime.Now (or .UtcNow am I right?) now becomes an service/interface "look I have StructureMap" monstrosity.

A better option would be what Ithaqua mentioned (pass in a Func) but you could also, you know, have methods that accept a DateTime as input instead of having to inject some kind of nonsensical DateTimeProvider.

Hmm guess we'll just have to agree to disagree then :)

JawnV6
Jul 4, 2004

So hot ...

Subjunctive posted:

No, that's ridiculous.
Ahem. ur ridiceuolus.

Subjunctive posted:

My issue with DI is the amount of boilerplate overhead in the source and at runtime. I've worked on projects that had to resort to preprocessing the DI code to be direct allocations in order to improve startup time, but that doesn't help the (usually pretty gross) source impact.
This is the stupidest reason to be for/against anything. Rather than have gosh, what is it, 5 freakin lines of code, you'd rather completely change the interface to the function under test. Surely duplicating every goddamn function we're using, somehow correlating our mucked-up versions with our actual production code, and having someone maintain this standard level of muckedupedness... naw, there's no way that takes up more than 5 lines of boilerplate.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

ping posted:

Written by my students, Computer Scientists at the end of their second year at a top 3 institution. Code for collision detection in a Pac Man clone.

Python code:
# Matthew N. Brown copyright 2007

# Here is an example program in wich
# balls hit walls and other balls:
#
# This program draws circles using:   pygame.draw.circle
#
# You can copy this program on to
# your own computer and run it.
#

import os, sys

 ## INIT STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################
def HE_HE_init():
    global screen, big_black_rect, APPLICATION_w_size, APPLICATION_z_size
    global WOW_pi_divided_by_180, WOW_180_divided_by_pi
    pygame.init()
    random.seed()
    APPLICATION_w_size = 700
    APPLICATION_z_size = 500
    ##### To close window while in fullscreen, press Esc while holding shift. #######
    screen = pygame.display.set_mode((APPLICATION_w_size, APPLICATION_z_size))
    #screen = pygame.display.set_mode((APPLICATION_w_size, APPLICATION_z_size), FULLSCREEN)
    pygame.display.set_caption("They bwounce off bwalls? Matthew N. Brown copyright 2007")
    pygame.mouse.set_visible(1)
    big_black_rect = pygame.Surface(screen.get_size())
    big_black_rect = big_black_rect.convert()
    big_black_rect.fill((0, 0, 0))
    screen.blit(big_black_rect, (0, 0))
    #fonty = pygame.font.Font(None, 36)
    fonty = pygame.font.SysFont("Times New Roman", 25)
    fonty.set_bold(0)
    IMAGEE = fonty.render('Loading . . .', 1, (0, 250, 10))
    screen.blit(IMAGEE, (100, 200)); del IMAGEE
    pygame.display.flip()
    pygame.mixer.init(22050, -16, True, 1024)
    WOW_pi_divided_by_180 = math.pi / 180.0
    WOW_180_divided_by_pi = 180.0 / math.pi
    set_up_key_variables()
    Lets_ROLL()
 ## INIT STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################

 ## SAVE LEVEL?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################
def write_to_file_WEEE_STRANGE(file_namey, data):
    noq = '\n'
    filey = open(file_namey, 'w')
    for d in data:
     filey.write(   str(d) + noq)
 ## SAVE LEVEL?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################

 ## SMALL FUNCTIONS STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################
     ### some functions: ###
def distance_2D (w1, z1, w2, z2):
    return math.sqrt(math.pow(float(w1) - float(w2), 2) + math.pow(float(z1) - float(z2), 2))
def rect_touching_rect(w1, z1, wol1, zol1, w2, z2, wol2, zol2):
    w2 -= w1
    z2 -= z1
    ww1 = -wol2
    zz1 = -zol2
    return (w2 > ww1 and w2 < wol1 and z2 > zz1 and z2 < zol1)
def rect_touching_rect2(w1, z1, wol1, zol1, w2, z2, wol2, zol2):
    w2 -= w1
    z2 -= z1
    ww1 = -wol2
    zz1 = -zol2
    return (w2 >= ww1 and w2 <= wol1 and z2 >= zz1 and z2 <= zol1)
def positive(n):
    if n < 0: n = -n; return n
def int_randy(range, add):
    return int((random.random() * range) + add)
def randy(range, add):
    return (random.random() * range) + add
def freaky_rect_switcharoo_2D(pw, pz, pwol, pzol, buffy_the_fat):
    buffy_the_fat2 = buffy_the_fat * 2
    if pwol > 0:
     gw = pw; gwol = pwol
    else:
     gw = pwol + pw; gwol = pw - gw
    if pzol > 0:
     gz = pz; gzol = pzol
    else:
     gz = pzol + pz; gzol = pz - gz
    return [gw - buffy_the_fat, gz - buffy_the_fat, gwol + buffy_the_fat2, gzol + buffy_the_fat2]
def points_rotated_by_angle_2D(points_wz, axis_w, axis_z, angle):
    rotated_points_wz = []
    angle = -angle -90
    angle_times_WOW_pi_divided_by_180 = angle * WOW_pi_divided_by_180
    c1 = math.cos(angle_times_WOW_pi_divided_by_180)
    s1 = math.sin(angle_times_WOW_pi_divided_by_180)
    for pointy in points_wz:
     xt = pointy[0] - axis_w
     yt = pointy[1] - axis_z
     rotated_points_wz += [(-xt * s1) + (yt * c1) + axis_w, (-xt * c1) - (yt * s1) + axis_z]
    return rotated_points_wz
def point_rotated_by_angle_2D(point_w, point_z, axis_w, axis_z, angle):
    angle = -angle -90
    angle_times_WOW_pi_divided_by_180 = angle * WOW_pi_divided_by_180
    c1 = math.cos(angle_times_WOW_pi_divided_by_180)
    s1 = math.sin(angle_times_WOW_pi_divided_by_180)
    xt = point_w - axis_w
    yt = point_z - axis_z
    return (-xt * s1) + (yt * c1) + axis_w, (-xt * c1) - (yt * s1) + axis_z
def arc_tangent_2D(point_w, point_z):
    return math.atan2(point_w, point_z) * WOW_180_divided_by_pi + 180
def arc_tangent_2D_2(point_w, point_z):
    return -math.atan2(point_w, point_z) * WOW_180_divided_by_pi + 180
def ball_to_ball_wzkol_bounce(V1, m1, V2, m2, ball1_is_to_the_left):
    if (ball1_is_to_the_left and V1 >= V2) or (not ball1_is_to_the_left and V1 <= V2):
     Rv1 = V1 - V2
     Rv2 = 0 #V2 - V2
     NewV1 = ((m1 - m2) / float(m1 + m2)) * float(Rv1) + V2
     NewV2 = (( 2 * m1) / float(m1 + m2)) * float(Rv1) + V2
     return NewV1, NewV2
    else:
     return V1, V2
def Find_where_ball_stops_on_line_w(ball_w, ball_z, ball_wol, ball_zol, ball_rad, line_w, line_rad):
    did_collide = False
    totally = ball_rad + line_rad
    b1 = line_w + totally
    b2 = line_w - totally
    New_ball_w = ball_w + ball_wol
    New_ball_z = ball_z + ball_zol
    if   ball_w >= b1 and ball_wol < 0 and New_ball_w < b1: New_ball_w = b1; did_collide = True
    elif ball_w <= b2 and ball_wol > 0 and New_ball_w > b2: New_ball_w = b2; did_collide = True
    else:
     if ball_w > b2 and ball_w < b1:
      if   ball_w > line_w and ball_wol < 0:
       New_ball_w = ball_w; New_ball_z = ball_z
       did_collide = True
      elif ball_w < line_w and ball_wol > 0:
       New_ball_w = ball_w; New_ball_z = ball_z
       did_collide = True
     return New_ball_w, New_ball_z, did_collide
    New_ball_z = (float(ball_zol) / float(ball_wol) * float(New_ball_w - ball_w)) + float(ball_z)
    return New_ball_w, New_ball_z, did_collide
def find_where_ball_collides_on_a_wall(
                                       ball_w, ball_z,
                                       ball_wol, ball_zol,
                                       ball_rad,
                                       wall_type,
                                       wall_w1, wall_z1,
                                       wall_w2, wall_z2,
                                       wall_rad):
    toetoadly = ball_rad + wall_rad
    did_collide = False
    New_ball_w = ball_w + ball_wol
    New_ball_z = ball_z + ball_zol
    angle_hit_at = None
    Relate_ball_w = ball_w - wall_w1
    Relate_ball_z = ball_z - wall_z1
    Relate_wall_w2 = wall_w2 - wall_w1
    Relate_wall_z2 = wall_z2 - wall_z1
    arc_tangeriney = arc_tangent_2D(Relate_wall_w2, Relate_wall_z2)
    Rotate_Relate_ball_w, Rotate_Relate_ball_z, Rotate_Relate_wall_w2, Rotate_Relate_wall_z2 = points_rotated_by_angle_2D(((Relate_ball_w, Relate_ball_z), (Relate_wall_w2, Relate_wall_z2)), 0, 0, arc_tangeriney)
    Rotate_ball_wol, Rotate_ball_zol = point_rotated_by_angle_2D(ball_wol, ball_zol, 0, 0, arc_tangeriney)
    Rotate_Relate_ball_collide_w, Rotate_Relate_ball_collide_z, did_hit_weird_line = Find_where_ball_stops_on_line_w(Rotate_Relate_ball_w, Rotate_Relate_ball_z, Rotate_ball_wol, Rotate_ball_zol, ball_rad, 0, wall_rad)
    if Rotate_Relate_ball_w > -toetoadly and Rotate_Relate_ball_w < toetoadly:
     HE_HE_strange_popper_z = Rotate_Relate_ball_z
    else:
     HE_HE_strange_popper_z = Rotate_Relate_ball_collide_z
    Rotate_angle_hit_at = None
    if   HE_HE_strange_popper_z < Rotate_Relate_wall_z2:
       if ball_is_going_towards_point(Rotate_Relate_ball_w, Rotate_Relate_ball_z, Rotate_ball_wol, Rotate_ball_zol, 0, Rotate_Relate_wall_z2):
        p1_touched, p1_collide_w, p1_collide_z, p1_angle_hit_at = find_where_ball_collides_on_another_ball(Rotate_Relate_ball_w, Rotate_Relate_ball_z, Rotate_ball_wol, Rotate_ball_zol, ball_rad, 0, Rotate_Relate_wall_z2, wall_rad)
        if p1_touched:
         Rotate_Relate_ball_collide_w = p1_collide_w
         Rotate_Relate_ball_collide_z = p1_collide_z
         Rotate_angle_hit_at = p1_angle_hit_at
         did_collide = True
    elif HE_HE_strange_popper_z > 0:
       if ball_is_going_towards_point(Rotate_Relate_ball_w, Rotate_Relate_ball_z, Rotate_ball_wol, Rotate_ball_zol, 0, 0):
        p2_touched, p2_collide_w, p2_collide_z, p2_angle_hit_at = find_where_ball_collides_on_another_ball(Rotate_Relate_ball_w, Rotate_Relate_ball_z, Rotate_ball_wol, Rotate_ball_zol, ball_rad, 0, 0, wall_rad)
        if p2_touched:
         Rotate_Relate_ball_collide_w = p2_collide_w
         Rotate_Relate_ball_collide_z = p2_collide_z
         Rotate_angle_hit_at = p2_angle_hit_at
         did_collide = True
    else:
       if did_hit_weird_line:
        did_collide = True
        if Rotate_Relate_ball_collide_w < 0: Rotate_angle_hit_at = 90
        else: Rotate_angle_hit_at = 270
    if did_collide:
     arc_tangeriney_2 = -arc_tangeriney
     angle_hit_at = Rotate_angle_hit_at + arc_tangeriney
     New_ball_w, New_ball_z = point_rotated_by_angle_2D(Rotate_Relate_ball_collide_w, Rotate_Relate_ball_collide_z, 0, 0, arc_tangeriney_2)
     New_ball_w += wall_w1
     New_ball_z += wall_z1
    return did_collide, New_ball_w, New_ball_z, angle_hit_at  #, is_moving_towards
def zol_at_angle(wol, zol, angle):
    rotated_wol, rotated_zol = point_rotated_by_angle_2D(wol, zol, 0, 0, angle)
    return rotated_zol
def wzol_bounce_at_angle(wol, zol, angle, multi):
    rotated_wol, rotated_zol = point_rotated_by_angle_2D(wol, zol, 0, 0, angle)
    if rotated_zol > 0: rotated_zol = -rotated_zol * multi
    return point_rotated_by_angle_2D(rotated_wol, rotated_zol, 0, 0, -angle)
def ball_is_going_towards_point(ball_w, ball_z, ball_wol, ball_zol, point_w, point_z):
    angley = arc_tangent_2D(ball_w - point_w, ball_z - point_z)
    rotated_wol, rotated_zol = point_rotated_by_angle_2D(ball_wol, ball_zol, 0, 0, angley)
    return rotated_zol > 0
def find_where_ball_collides_on_another_ball (
                                               ball1_w, ball1_z,
                                               ball1_wol, ball1_zol,
                                               ball1_rad,
                                               ball2_w, ball2_z,
                                               ball2_rad
                                             ):
    totally = ball1_rad + ball2_rad
    dis_from_each_other = math.sqrt(math.pow(float(ball1_w) - float(ball2_w), 2) + math.pow(float(ball1_z) - float(ball2_z), 2))
    if dis_from_each_other < totally:
     angley = arc_tangent_2D(ball1_w - ball2_w, ball1_z - ball2_z)
     return True, ball1_w, ball1_z, angley
    else:
        they_did_touch = False
        New_ball1_w = ball1_w + ball1_wol
        New_ball1_z = ball1_z + ball1_zol
        angle_hit_at = None
        Relate_ball1_w = ball1_w - ball2_w
        Relate_ball1_z = ball1_z - ball2_z
        Relate_ball2_w = 0
        Relate_ball2_z = 0
        arcy_tangeriney = arc_tangent_2D(ball1_wol, ball1_zol)
        Rotated_Relate_ball1_w, Rotated_Relate_ball1_z, Rotated_ball1_wol, Rotated_ball1_zol = points_rotated_by_angle_2D(((Relate_ball1_w, Relate_ball1_z), (ball1_wol, ball1_zol)), 0, 0, arcy_tangeriney)
        did_collidey = False
        if Rotated_Relate_ball1_z > 0 and (Rotated_Relate_ball1_w > -totally and Rotated_Relate_ball1_w < totally):
         Rotated_Relate_ball1_collide_w = Rotated_Relate_ball1_w # + Rotated_ball1_wol
         HE_HE = math.pow(Rotated_Relate_ball1_w, 2) - math.pow(totally, 2)
         if HE_HE < 0: HE_HE = -HE_HE
         Rotated_Relate_ball1_collide_z = math.sqrt(HE_HE)
         Rotated_Relate_ball1_z__PLUS__Rotated_ball1_zol = Rotated_Relate_ball1_z + Rotated_ball1_zol
         if Rotated_Relate_ball1_collide_z < Rotated_Relate_ball1_z__PLUS__Rotated_ball1_zol:
          collision_wol = Rotated_ball1_wol
          collision_zol = Rotated_ball1_zol
          Rotated_Relate_ball1_collide_z = Rotated_Relate_ball1_z__PLUS__Rotated_ball1_zol
          angley_to_hit = None
         else:
          did_collidey = True
          they_did_touch = True
          angley_to_hit = arc_tangent_2D(Rotated_Relate_ball1_collide_w, Rotated_Relate_ball1_collide_z)
        else:
         angley_to_hit = None
         collision_wol = Rotated_ball1_wol
         collision_zol = Rotated_ball1_zol
         Rotated_Relate_ball1_collide_w = Rotated_Relate_ball1_w + Rotated_ball1_wol
         Rotated_Relate_ball1_collide_z = Rotated_Relate_ball1_z + Rotated_ball1_zol
        if did_collidey:
         arcy_tangeriney_2 = -arcy_tangeriney
         angle_hit_at = angley_to_hit + arcy_tangeriney
         New_ball1_w, New_ball1_z = point_rotated_by_angle_2D(Rotated_Relate_ball1_collide_w, Rotated_Relate_ball1_collide_z, 0, 0, arcy_tangeriney_2)
         New_ball1_w += ball2_w
         New_ball1_z += ball2_z
    return they_did_touch, New_ball1_w, New_ball1_z, angle_hit_at  #, New_ball1_wol, New_ball1_zol
     ### some functions: ###

 ## GRAPHICS STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################
def chilly_font(size):
    fonti = pygame.font.SysFont("Times New Roman", size)
    return fonti
def chilly_font_Italicy(size):
    fonti = pygame.font.SysFont("Times New Roman", size)
    fonti.set_italic(1)
    return fonti
def draw_loading_messagey(stringy): # Draw loading message
    pygame.mouse.set_visible(1)
    fonty = chilly_font(26)
    IMAGEE = fonty.render(stringy, 0, (0, 255, 0), (0, 0, 0))
    screen.blit(IMAGEE, (200, 250))
    del IMAGEE
    pygame.display.flip()
           ## GRAPHICS STUFF: ##
#########################################################################################

 ## KEYS AND MOUSE STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################
def set_up_key_variables():
     global ky_held, ky_first_held, ky_time_last_pressed
     global mowse_w, mowse_z, mowse_inn
     global mowse_left_pressed, mowse_right_pressed, mowse_left_held, mowse_right_held
     mowse_left_held = False
     mowse_right_held = False
     mowse_left_pressed = False
     mowse_right_pressed = False
     mowse_w = 0
     mowse_z = 0
     mowse_inn = 0
     ky_held = []
     ky_first_held = []
     ky_time_last_pressed = []
     m = -1
     while m < 500:
      m += 1
      ky_held              += [0]
      ky_first_held        += [0]
      ky_time_last_pressed += [0]
def clear_all_kys():
    global mowse_left_pressed, mowse_right_pressed, mowse_left_held, mowse_right_held
    mowse_left_held = False
    mowse_right_held = False
    mowse_left_pressed = False
    mowse_right_pressed = False
    m = -1
    while (m < 500):
     m += 1; ky_held[m] = 0; ky_first_held[m] = 0; ky_time_last_pressed[m] = 0
def clear_these_ky_first_held(list_keys_numbers):
    for k in list_keys_numbers:
     ky_first_held[k] = 0
def clear_first_held_kys():
    m = -1
    while (m < 500):
     m += 1; ky_first_held[m] = 0
def old_style_ky(n):
    return (ky_first_held_CEV(n) or (ky_held[n] and ky_time_last_pressed[n] < time.time() - .3))
def ky_first_held_CEV(n):
    if (ky_first_held[n]):
     ky_first_held[n] = 0; return 1
    else:
     return 0
def mowse_in_rect (w, z, wol, zol):
    return (mowse_w >= w and mowse_z >= z and mowse_w <= w + wol and mowse_z <= z + zol)
def mowse_in_circle (w, z, rad):
    dia = rad * 2
    if mowse_in_rect(w - rad, z - rad, w + dia, z + dia):
     return (distance_2D(mowse_w, mowse_z, w, z) < rad)
    else:
     return 0
    ## CHECK FOR: KEYBOARD, MOUSE, JOYSTICK, AND OTHERY INPUTY: ##
def check_for_keys():
        global mowse_w, mowse_z, mowse_inn, mowse_left_pressed, mowse_right_pressed, mowse_left_held, mowse_right_held, APPLICATION_w_size, APPLICATION_z_size
        global loopy
        global unicodey
        mowse_left_pressed = False
        mowse_right_pressed = False
        unicodey = ''
        for e in pygame.event.get():
          if e.type == QUIT:
            loopy = 0
          elif e.type == ACTIVEEVENT:
            mowse_inn = (e.gain and (e.state == 1 or e.state == 6))
          elif e.type == KEYDOWN:
            ky_held[e.key] = 1
            ky_first_held[e.key] = 1
            ky_time_last_pressed[e.key] = time.time()
            unicodey = e.unicode
          elif e.type == KEYUP:
            ky_held[e.key] = 0
          elif e.type == MOUSEMOTION:
            mowse_w = e.pos[0]
            mowse_z = e.pos[1]
            if mowse_w >= 0 and mowse_w <= APPLICATION_w_size and mowse_z >= 0 and mowse_z <= APPLICATION_z_size:
             mowse_inn = 1
            else:
             mowse_inn = 0
          elif e.type == MOUSEBUTTONUP:
            if e.button == 1: mowse_left_held = 0
            if e.button == 3: mowse_right_held = 0
          elif e.type == MOUSEBUTTONDOWN:
            mowse_left_pressed  = (e.button == 1)
            mowse_right_pressed = (e.button == 3)
            mowse_left_held =  mowse_left_held or e.button == 1
            mowse_right_held = mowse_right_held or e.button == 3
          elif e.type == JOYAXISMOTION:
            pass
          elif e.type == JOYBALLMOTION:
            pass
          elif e.type == JOYHATMOTION:
            pass
          elif e.type == JOYBUTTONUP:
            pass
          elif e.type == JOYBUTTONDOWN:
            pass
          elif e.type == VIDEORESIZE:
            print e
            print "What happened!?"
            #global big_black_rect, screen
            #APPLICATION_w_size = e.size[0]
            #APPLICATION_z_size = e.size[1]
            #screen = pygame.display.set_mode((APPLICATION_w_size, APPLICATION_z_size))#, RESIZABLE)
            #big_black_rect = pygame.Surface(screen.get_size())
            #big_black_rect = big_black_rect.convert()
            #big_black_rect.fill((0, 100, 200))
          elif e.type == VIDEOEXPOSE:
            pass
          elif e.type == USEREVENT:
            pass
        if ky_held[27] and (ky_held[303] or ky_held[304]): loopy = 0
    ## CHECK FOR: KEYBOARD, MOUSE, JOYSTICK, AND OTHERY INPUTY: ##
 ## KEYS AND MOUSE STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################

#######################################################################################
#######################################################################################
#######################################################################################
#######################################################################################
#######################################################################################


 ## MAIN LOOPY STUFF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#########################################################################################
def ball_is_going_towards_ball(Bn1, Bn2):
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_mass, ball_RECT
    arc_tangerine = arc_tangent_2D(ball_w[Bn1] - ball_w[Bn2], ball_z[Bn1] - ball_z[Bn2])
    woly1, zoly1 = point_rotated_by_angle_2D(ball_wol[Bn1], ball_zol[Bn1], 0, 0, arc_tangerine)
    return zoly1 > 0
def ball_is_relatively_going_towards_ball(Bn1, Bn2):
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_mass, ball_RECT
    arc_tangerine = arc_tangent_2D(ball_w[Bn1] - ball_w[Bn2], ball_z[Bn1] - ball_z[Bn2])
    woly1, zoly1, woly2, zoly2 = points_rotated_by_angle_2D(((ball_wol[Bn1], ball_zol[Bn1]), (ball_wol[Bn2], ball_zol[Bn2])), 0, 0, arc_tangerine)
    return zoly1 > 0 and zoly1 > zoly2  # zoly2 < zoly1 or zoly2 > zoly1 # zoly1 + zoly2 > 0
    #return zoly1 > 0 or zoly1 > zoly2
def Make_two_balls_hit_at_angle(Bn1, Bn2, angle):
    global bounce_friction
    #print angle
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_mass, ball_RECT
    woly1, zoly1, woly2, zoly2 = points_rotated_by_angle_2D(((ball_wol[Bn1], ball_zol[Bn1]), (ball_wol[Bn2], ball_zol[Bn2])), 0, 0, angle)
    V1 = zoly1 * bounce_friction
    V2 = zoly2 * bounce_friction
    zoly1, zoly2 = ball_to_ball_wzkol_bounce(V1, ball_mass[Bn1], V2, ball_mass[Bn2], True)
    ball_wol[Bn1], ball_zol[Bn1], ball_wol[Bn2], ball_zol[Bn2] = points_rotated_by_angle_2D(((woly1, zoly1), (woly2, zoly2)), 0, 0, -angle)
    updatey_ball_quick_rect(Bn1)
    updatey_ball_quick_rect(Bn2)
def updatey_ball_quick_rect(B):
    dia = ball_rad[B] * 2 + 4
    ball_squar[B] = [ball_w[B] - ball_rad[B] - 2, ball_z[B] - ball_rad[B] - 2, dia, dia]
    ball_RECT[B] = freaky_rect_switcharoo_2D(ball_w[B], ball_z[B], ball_wol[B], ball_zol[B], ball_rad[B] + 4)
def minus_ball_thing(n):
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_angle, ball_angleol, ball_squar, ball_mass, ball_RECT
    if ball_max >= 0:
     del ball_w      [n]
     del ball_z      [n]
     del ball_wol    [n]
     del ball_zol    [n]
     del ball_rad    [n]
     del ball_color  [n]
     del ball_squar  [n]
     del ball_angle  [n]
     del ball_angleol[n]
     del ball_mass   [n]
     del ball_RECT   [n]
     ball_max -= 1
def add_ball_thing(w, z, wol, zol, rad, color, angle, angleol, mass_thing, rect_thing):
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_squar, ball_angle, ball_angleol, ball_mass, ball_RECT
    ball_max += 1
    ball_w       += [w]
    ball_z       += [z]
    ball_wol     += [wol]
    ball_zol     += [zol]
    ball_rad     += [rad]
    ball_color   += [color]
    ball_angle   += [angle]
    ball_angleol += [angleol]
    dia = rad * 2
    ball_squar += [[w - rad, z - rad, dia, dia]]
    if mass_thing == True:
     ball_mass += [4 / 3 * math.pi * rad * rad * rad]
    else:
     ball_mass += [mass_thing]
    if rect_thing == True:
     ball_RECT += [None]
     updatey_ball_quick_rect(ball_max)
     #ball_RECT += [freaky_rect_switcharoo_2D(w, z, wol, zol, rad)]
    else:
     ball_RECT += [rect_thing]
def minus_wall_thing(WAL):
    global wall_max, wall_type, wall_w1, wall_z1, wall_w2, wall_z2, wall_rad, wall_color, wall_RECT
    if wall_max >= 0:
     del wall_type   [WAL]
     del wall_w1     [WAL]
     del wall_z1     [WAL]
     del wall_w2     [WAL]
     del wall_z2     [WAL]
     del wall_rad    [WAL]
     del wall_color  [WAL]
     del wall_RECT   [WAL]
     wall_max        -= 1
def add_wall_thing(type, w1, z1, w2, z2, rad, color_thing, rect_thing):
    global wall_max, wall_type, wall_w1, wall_z1, wall_w2, wall_z2, wall_rad, wall_color, wall_RECT
    wall_max    += 1
    wall_type   += [type]
    wall_w1     += [w1]
    wall_z1     += [z1]
    wall_w2     += [w2]
    wall_z2     += [z2]
    wall_rad    += [rad]
    if color_thing == True:
     if   type == 1: color_thing = (220, 220, 220)
     elif type == 2: color_thing = (240, 140, 130)
     elif type == 3: color_thing = (100, 255, 100)
     elif type == 4: color_thing = (255, 100, 100)
     elif type == 5: color_thing = (100, 100, 255)
    wall_color  += [color_thing]
    if rect_thing == True:
     wall_RECT   += [freaky_rect_switcharoo_2D(w1 - 2, z1 - 2, w2 - w1 + 4, z2 - z1 + 4, rad)]
    else:
     wall_RECT   += [rect_thing]
def reset_stuff():
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_angle, ball_angleol, ball_squar, ball_mass, ball_RECT
    global wall_max, wall_type, wall_w1, wall_z1, wall_w2, wall_z2, wall_rad, wall_color, wall_RECT
    global levely
    if levely == 1:
     ball_max     = -1
     ball_w       = []
     ball_z       = []
     ball_wol     = []
     ball_zol     = []
     ball_rad     = []
     ball_color   = []
     ball_angle   = []
     ball_angleol = []
     ball_squar   = []
     ball_mass    = []
     ball_RECT    = []
     #add_ball_thing(350, 300, 0, 0, 18, (230, 230, 250), 0, 0, True, True)
     #add_ball_thing(150, 400, 0, 0, 40, (220, 210, 255), 0, 0, True, True)
     #add_ball_thing(300, 150, 0, 0, 62, (110, 106, 255), 0, 0, True, True)
     add_ball_thing(220, 200, 0, 0, 50, (180, 226, 255), 180, 0, True, True)
     wall_max    = -1
     wall_type   = []
     wall_w1     = []
     wall_z1     = []
     wall_w2     = []
     wall_z2     = []
     wall_rad    = []
     wall_color  = []
     wall_RECT   = []
     add_wall_thing(1, 160, 250, 300, 270,  1, True, True)
     add_wall_thing(1, 500, 270, 600, 310,  1, True, True)
     add_wall_thing(1, 200, 450, 600, 450, 10, True, True)
     add_wall_thing(1, 300, 350, 400, 370,  5, True, True)
     add_wall_thing(1, 300, 100, 400, 100, 20, True, True)
     add_wall_thing(1, 650, 140, 700, 200,  6, True, True)
     add_wall_thing(1, 650, 140, 600,  40,  6, True, True)
     add_wall_thing(1, 150, 340, 150, 340, 30, True, True)
     add_wall_thing(1,  40, 200,  40, 200, 30, True, True)
     add_wall_thing(1,  30, 30,  30, 30, 10, True, True)
     add_wall_thing(1,  30, 30,  30, 30, 10, True, True)
     add_wall_thing(1,  30, 30,  30, 30, 10, True, True)
     add_wall_thing(1,  30, 30,  30, 30, 10, True, True)
     add_wall_thing(1,  30, 30,  30, 30, 10, True, True)
     add_wall_thing(1,  0, 0, APPLICATION_w_size, 0, 5, True, True)
     add_wall_thing(1,  0, 0, 0, APPLICATION_z_size, 5, True, True)
     add_wall_thing(1,  0, APPLICATION_z_size, APPLICATION_w_size, APPLICATION_z_size, 5, True, True)
     add_wall_thing(1,  APPLICATION_w_size, 0, APPLICATION_w_size, APPLICATION_z_size, 5, True, True)
    elif levely == 2:
     ball_max = 1
     ball_w = [323.62638473709342, 384.72135876760257]
     ball_z = [298.67896746658624, 109.24043981044279]
     ball_wol = [-0.27396932987421913, 7.133321987715842]
     ball_zol = [-0.38420912894762504, 1.6564147490246901]
     ball_rad = [15, 28]
     ball_color = [(137, 244, 234), (138, 221, 217)]
     ball_angle = [51.908780125668613, 294.77431504891717]
     ball_angleol = [-1.2400074168431123, 17.698615258690229]
     ball_squar = [[306.62638473709342, 281.67896746658624, 34, 34], [354.72135876760257, 79.240439810442794, 60, 60]]
     ball_mass = [10602.875205865552, 68964.24193160313]
     ball_RECT = [[304.35241540721921, 279.2947583376386, 38.273969329874205, 38.384209128947646], [352.72135876760257, 77.240439810442794, 71.133321987715846, 65.656414749024691]]
     wall_max = 17
     wall_type = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
     wall_w1 = [189, 290, 166, 14, 697, 562, 643, 3, 0, 223, 117, 695, 497, 497, 0, 0, 0, 700]
     wall_z1 = [284, 316, 436, 499, 446, 0, 128, 225, 106, 310, 155, 210, 159, 159, 0, 0, 500, 0]
     wall_w2 = [222, 446, 697, 157, 377, 681, 679, 49, 383, 287, 5, 448, 376, 546, 700, 0, 700, 700]
     wall_z2 = [301, 314, 478, 432, 487, 99, 98, 416, 171, 324, 225, 323, 147, 179, 0, 500, 500, 500]
     wall_rad = [1, 1, 10, 5, 20, 6, 6, 30, 30, 10, 10, 10, 10, 10, 5, 5, 5, 5]
     wall_color = [(220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220)]
     wall_RECT = [[186, 281, 39, 23], [287, 313, 162, 4], [154, 424, 555, 66], [7, 429, 157, 73], [359, 424, 356, 85], [554, -8, 135, 115], [635, 94, 52, 38], [-29, 193, 110, 255], [-32, 74, 447, 129], [211, 298, 88, 38], [-3, 143, 128, 94], [440, 198, 263, 137], [368, 139, 137, 28], [485, 147, 73, 44], [-7, -7, 714, 14], [-7, -7, 14, 514], [-7, 493, 714, 14], [693, -7, 14, 514]]
    elif levely == 3:
     ball_max = 2
     ball_w = [425.0, 492.31837629165733, 98.512856261065167]
     ball_z = [126.0, 422.24553778829392, 430.4902396760661]
     ball_wol = [-12.0, 2.6816237083426699, 6.487143738934833]
     ball_zol = [-3.0, -1.245537788293916, -21.490239676066096]
     ball_rad = [15, 28, 21]
     ball_color = [(137, 244, 234), (138, 221, 217), (136, 235, 236)]
     ball_angle = [93.833857527468922, 75.681742520058592, 323.2915629772819]
     ball_angleol = [-0.87655530207419896, 0.30220691772972269, 1.1825329351046094]
     ball_squar = [[408.0, 109.0, 34, 34], [462.31837629165733, 392.24553778829392, 60, 60], [75.512856261065167, 407.4902396760661, 46, 46]]
     ball_mass = [10602.875205865552, 68964.24193160313, 29094.28956489508]
     ball_RECT = [[394.0, 104.0, 50.0, 41.0], [460.31837629165733, 389.0, 66.68162370834267, 65.245537788293916], [73.512856261065167, 384.0, 56.487143738934833, 71.490239676066096]]
     wall_max = 17
     wall_type = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
     wall_w1 = [189, 290, 166, 14, 697, 562, 643, 3, 0, 223, 117, 695, 497, 497, 0, 0, 0, 700]
     wall_z1 = [284, 316, 436, 499, 446, 0, 128, 225, 106, 310, 155, 210, 159, 159, 0, 0, 500, 0]
     wall_w2 = [222, 446, 697, 157, 377, 681, 679, 49, 383, 287, 5, 480, 376, 546, 700, 0, 700, 700]
     wall_z2 = [301, 314, 478, 432, 487, 99, 98, 416, 171, 324, 225, 325, 147, 179, 0, 500, 500, 500]
     wall_rad = [1, 1, 10, 5, 20, 6, 6, 30, 30, 10, 10, 10, 10, 10, 5, 5, 5, 5]
     wall_color = [(220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220), (220, 220, 220)]
     wall_RECT = [[186, 281, 39, 23], [287, 313, 162, 4], [154, 424, 555, 66], [7, 429, 157, 73], [359, 424, 356, 85], [554, -8, 135, 115], [635, 94, 52, 38], [-29, 193, 110, 255], [-32, 74, 447, 129], [211, 298, 88, 38], [-3, 143, 128, 94], [472, 198, 231, 139], [368, 139, 137, 28], [485, 147, 73, 44], [-7, -7, 714, 14], [-7, -7, 14, 514], [-7, 493, 714, 14], [693, -7, 14, 514]]
def draw_walls_on_big_black_rect():
    global wall_max, wall_type, wall_w1, wall_z1, wall_w2, wall_z2, wall_rad, wall_color, wall_RECT
    global big_black_rect
    global LIN_selected, CLICKER, CLICKER2
    if CLICKER:
     if LIN_selected != -1:
      nnn = LIN_selected[0]
      if LIN_selected[1] == 1:
       wall_w1[nnn] = mowse_w
       wall_z1[nnn] = mowse_z
      else:
       wall_w2[nnn] = mowse_w
       wall_z2[nnn] = mowse_z
      w1 = wall_w1[nnn]
      z1 = wall_z1[nnn]
      w2 = wall_w2[nnn]
      z2 = wall_z2[nnn]
      rad = wall_rad[nnn]
      wall_RECT[nnn] = freaky_rect_switcharoo_2D(w1 - 2, z1 - 2, w2 - w1 + 4, z2 - z1 + 4, rad)
    wl = -1
    while wl < wall_max:
     wl += 1
     w1 = wall_w1[wl]
     z1 = wall_z1[wl]
     w2 = wall_w2[wl]
     z2 = wall_z2[wl]
     rad = wall_rad[wl]
     collyu = wall_color[wl]
     pygame.draw.line(big_black_rect, collyu, (w1, z1), (w2, z2), rad * 2)
     pygame.draw.circle(big_black_rect, collyu, (w1, z1), rad)
     pygame.draw.circle(big_black_rect, collyu, (w2, z2), rad)
     #pygame.draw.rect(big_black_rect, (200, 200, 200), wall_RECT[wl], 1)
     if CLICKER2:
      if mowse_in_rect(wall_RECT[wl][0], wall_RECT[wl][1], wall_RECT[wl][2], wall_RECT[wl][3]):
       if   mowse_in_circle(w1, z1, rad+3): selected = -1; LIN_selected = [wl, 1]
       elif mowse_in_circle(w2, z2, rad+3): selected = -1; LIN_selected = [wl, 2]
def Lets_ROLL():
    global loopy
    global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_angle, ball_angleol, ball_squar, ball_mass, ball_RECT
    global wall_max, wall_type, wall_w1, wall_z1, wall_w2, wall_z2, wall_rad, wall_color, wall_RECT
    global bounce_friction, air_friction, gravity, rock_and_ROLLY
    global LIN_selected, CLICKER, CLICKER2
    global levely
    levely = 3
    bounce_friction = 0.8
    #bounce_friction = 1.0
    air_friction = 0.999
    #air_friction = 1.0
    gravity = 0.5
    rock_and_ROLLY = math.pi / 8 * 180 #24
    reset_stuff()
    fontyyy = chilly_font_Italicy(24)
    PRESS_SPACE_BAR_TO_MOVE_immy = fontyyy.render('Press SPACE BAR to start motion.', 0, (100, 200, 100))
    PRESS_SPACE_BAR_TO_STOP_immy = fontyyy.render('Press SPACE BAR to stop motion.', 0, (200, 100, 100))
    PRESS_ENTER_TO_RESET_immy    = fontyyy.render('Press ENTER to reset.', 0, (150, 150, 150))
    PRESS_MINUS_TO_MINUS_immy    = fontyyy.render('Press - to delete a ball.', 0, (150, 150, 150))
    PRESS_ADD_TO_ADD_immy        = fontyyy.render('Press + to add a ball.', 0, (150, 150, 150))
    LEFT_CLICK_TO_immy           = fontyyy.render('Left click on a "ghost ball" to change its speed.', 0, (150, 150, 150))
    RIGHT_CLICK_TO_immy          = fontyyy.render('Right click on a ball to stop its motion.', 0, (150, 150, 150))
    PRESS_S_TO_immy              = fontyyy.render('Press S to stop all balls.', 0, (150, 150, 150))
    PRESS_PAGE_UP_TO_immy        = fontyyy.render('Press Page Up to change the level.', 0, (150, 150, 150))
    #message_1_immy
    del fontyyy
    #calculate_for_sure = True
    selected = -1
    LIN_selected = -1
    move_stuff = True
    t = time.time() + .01
    CLICKER = False
    CLICKER2 = False
    loopy = 1
    while loopy:
          big_black_rect.fill((0, 0, 0))
          draw_walls_on_big_black_rect()
          screen.blit(big_black_rect, (0, 0))
          check_for_keys()
          CLICKER    = mowse_left_held
          CLICKER2   = mowse_left_pressed
          CLICKER_2  = mowse_right_held
          CLICKER2_2 = mowse_right_pressed
          if ky_first_held_CEV(32): move_stuff = not move_stuff
          if ky_first_held_CEV(13): reset_stuff()
          if ky_first_held_CEV(280):
           levely += 1
           if levely > 5: levely = 1
           reset_stuff()
          if ky_first_held_CEV(115): # S
            M = -1
            while M < ball_max:
             M += 1
             ball_wol[M] = 0
             ball_zol[M] = 0
             updatey_ball_quick_rect(M)
          if ky_first_held_CEV(45) or ky_first_held_CEV(269): # -
           minus_ball_thing(0)
          if ky_first_held_CEV(61) or ky_first_held_CEV(270): # +
           add_ball_thing(350 + randy(40, -20), 400 + randy(40, -20), randy(40, -20), randy(40, -20), int_randy(20, 10), (int_randy(10, 130), int_randy(80, 170), int_randy(50, 200)), 0, 0, True, True)
          if ky_first_held_CEV(49):
           listy  = ['Level_save']
           listy += ['ball_max = ' + str(ball_max)]
           listy += ['ball_w = ' + str(ball_w)]
           listy += ['ball_z = ' + str(ball_z)]
           listy += ['ball_wol = ' + str(ball_wol)]
           listy += ['ball_zol = ' + str(ball_zol)]
           listy += ['ball_rad = ' + str(ball_rad)]
           listy += ['ball_color = ' + str(ball_color)]
           listy += ['ball_angle = ' + str(ball_angle)]
           listy += ['ball_angleol = ' + str(ball_angleol)]
           listy += ['ball_squar = ' + str(ball_squar)]
           listy += ['ball_mass = ' + str(ball_mass)]
           listy += ['ball_RECT = ' + str(ball_RECT)]
           listy += ['wall_max = ' + str(wall_max)]
           listy += ['wall_type = ' + str(wall_type)]
           listy += ['wall_w1 = ' + str(wall_w1)]
           listy += ['wall_z1 = ' + str(wall_z1)]
           listy += ['wall_w2 = ' + str(wall_w2)]
           listy += ['wall_z2 = ' + str(wall_z2)]
           listy += ['wall_rad = ' + str(wall_rad)]
           listy += ['wall_color = ' + str(wall_color)]
           listy += ['wall_RECT = ' + str(wall_RECT)]
           ##write_to_file_WEEE_STRANGE("Level_Save.dat", listy)
           del listy
          if CLICKER2:
           allow_selectey_thing = True
          else:
           allow_selectey_thing = False
           if not CLICKER:
            selected = -1
            LIN_selected = -1
          to_be_selected = selected
          M = -1
          while M < ball_max:
           M += 1
           if move_stuff:
            move_ball(M)
           wwol = int(ball_w[M] + ball_wol[M])
           zzol = int(ball_z[M] + ball_zol[M])
           pygame.draw.circle(screen, ball_color[M], (int(ball_w[M]), int(ball_z[M])), ball_rad[M])
           blpw, blpz = point_rotated_by_angle_2D(0, -ball_rad[M], 0, 0, ball_angle[M])
           pygame.draw.line(screen, (100, 100, 100), (int(ball_w[M] + blpw), int(ball_z[M] + blpz)), (int(ball_w[M]), int(ball_z[M])))
           if not move_stuff:
            pygame.draw.circle(screen, (100, 100, 250), (wwol, zzol), ball_rad[M], 1)
            pygame.draw.circle(screen, (100, 100, 150), (wwol, zzol), int(ball_rad[M] * 1.0), 1)
            pygame.draw.circle(screen, (150, 150, 200), (wwol, zzol), int(ball_rad[M] * 0.8), 1)
            pygame.draw.circle(screen, (200, 200, 250), (wwol, zzol), int(ball_rad[M] * 0.5), 1)
            pygame.draw.line(screen, (100, 160, 250), (int(ball_w[M]), int(ball_z[M])), (wwol, zzol))
            pygame.draw.rect(screen, (130, 130, 130), ball_RECT[M], 1)
            pygame.draw.rect(screen, (140, 140, 140), ball_squar[M], 1)
           if allow_selectey_thing:
            if mowse_in_rect(ball_RECT[M][0], ball_RECT[M][1], ball_RECT[M][2], ball_RECT[M][3]):
             if mowse_in_circle(wwol, zzol, ball_rad[M]):
              to_be_selected = M
              LIN_selected = -1
           if CLICKER_2:
            if mowse_in_rect(ball_squar[M][0], ball_squar[M][1], ball_squar[M][2], ball_squar[M][3]):
             if mowse_in_circle(ball_w[M], ball_z[M], ball_rad[M]):
              ball_wol[M] = 0
              ball_zol[M] = 0
              ball_angleol[M] = 0
              updatey_ball_quick_rect(M)
           if CLICKER:
            if selected == M:
             if move_stuff:
              mowseyy_w = mowse_w
              mowseyy_z = mowse_z
              bw1 = ball_rad[M]
              bz1 = ball_rad[M]
              bw2 = APPLICATION_w_size - ball_rad[M]
              bz2 = APPLICATION_z_size - ball_rad[M]
              if mowseyy_w < bw1: mowseyy_w = bw1
              if mowseyy_w > bw2: mowseyy_w = bw2
              if mowseyy_z < bz1: mowseyy_z = bz1
              if mowseyy_z > bz2: mowseyy_z = bz2
              ww = mowseyy_w - ball_w[M]
              zz = mowseyy_z - ball_z[M]
              #dissy = distance_2D(0, 0, ww, zz)
              ball_wol[M] = ww # / 2.0 # / dissy
              ball_zol[M] = zz # / 2.0 # / dissy
             else:
              ball_wol[M] = mowse_w - ball_w[M]
              ball_zol[M] = mowse_z - ball_z[M]
             updatey_ball_quick_rect(M)
          selected = to_be_selected
          if not move_stuff:
           screen.blit(PRESS_SPACE_BAR_TO_MOVE_immy, (10, 10))
          else:
           screen.blit(PRESS_SPACE_BAR_TO_STOP_immy, (10, 10))
          screen.blit(PRESS_MINUS_TO_MINUS_immy, (10, 30))
          screen.blit(PRESS_ADD_TO_ADD_immy, (10, 50))
          screen.blit(PRESS_ENTER_TO_RESET_immy, (10, 70))
          screen.blit(LEFT_CLICK_TO_immy, (10, 90))
          screen.blit(RIGHT_CLICK_TO_immy, (10, 110))
          screen.blit(PRESS_S_TO_immy, (10, 130))
          screen.blit(PRESS_PAGE_UP_TO_immy, (10, 150))
          pygame.display.flip()
          while t > time.time(): pass
          t = time.time() + .01
 # Try_Again_HE_HE Is weird!! maybe It should be deleted!!
def move_ball(M):
            ball_angle[M] += ball_angleol[M]
            if   ball_angle[M] > 359: ball_angle[M] -= 360
            elif ball_angle[M] <   0: ball_angle[M] += 361
            #movey_bally_speciality(M, ball_wol[M], ball_zol[M], 10)
            movey_bally_speciality(M, ball_wol[M], ball_zol[M], 10)
            ball_zol[M] += gravity
            updatey_ball_quick_rect(M)
def movey_bally_speciality(M, wol_special, zol_special, Try_Again_HE_HE):
            global loopy
            global ball_max, ball_w, ball_z, ball_wol, ball_zol, ball_rad, ball_color, ball_angle, ball_angleol, ball_squar, ball_mass, ball_RECT
            global wall_max, wall_type, wall_w1, wall_z1, wall_w2, wall_z2, wall_rad, wall_color, wall_RECT
            global bounce_friction, air_friction, gravity, rock_and_ROLLY
            distance_is_supposed_to_be_at = distance_2D(0, 0, wol_special, zol_special)
            wa = ball_w[M]
            za = ball_z[M]
            #will_be_w = wa + ball_wol[M]
            #will_be_z = za + ball_zol[M]
            will_be_w = wa + wol_special
            will_be_z = za + zol_special
            LIN_collide_max = -1
            LIN_collide_w    = []
            LIN_collide_z     = []
            LIN_collide_ang    = []
            LIN_collide_dis     = []
            LL = -1
            while LL < wall_max:
              LL += 1
              if rect_touching_rect2(ball_RECT[M][0], ball_RECT[M][1], ball_RECT[M][2], ball_RECT[M][3], wall_RECT[LL][0], wall_RECT[LL][1], wall_RECT[LL][2], wall_RECT[LL][3]):
                  #print 'weee'
                  did_collide, New_ball_w, New_ball_z, angle_hit_at = find_where_ball_collides_on_a_wall(wa, za, wol_special, zol_special, ball_rad[M], wall_type[LL], wall_w1[LL], wall_z1[LL], wall_w2[LL], wall_z2[LL], wall_rad[LL])
                  if did_collide:
                   #print 'collide'
                   #print str(New_ball_w), str(New_ball_z)
                   LIN_collide_max += 1
                   LIN_collide_w    += [New_ball_w]
                   LIN_collide_z     += [New_ball_z]
                   LIN_collide_ang    += [angle_hit_at]
                   LIN_collide_dis     += [distance_2D(wa, za, New_ball_w, New_ball_z)]
            HEH_collide_max = -1
            HEH_collide_w    = []
            HEH_collide_z     = []
            HEH_collide_ang    = []
            HEH_collide_dis     = []
            HEH_collide_ball_hit = []
            M2 = -1
            while M2 < ball_max:
             M2 += 1
             if M2 != M:
              if rect_touching_rect2(ball_RECT[M][0], ball_RECT[M][1], ball_RECT[M][2], ball_RECT[M][3], ball_squar[M2][0], ball_squar[M2][1], ball_squar[M2][2], ball_squar[M2][3]):
                  #they_did_touch, New_ball1_w, New_ball1_z, angle_hit_at = find_where_ball_collides_on_another_ball(wa, za, ball_wol[M], ball_zol[M], ball_rad[M], ball_w[M2], ball_z[M2], ball_rad[M2])
                  they_did_touch, New_ball1_w, New_ball1_z, angle_hit_at = find_where_ball_collides_on_another_ball(wa, za, wol_special, zol_special, ball_rad[M], ball_w[M2], ball_z[M2], ball_rad[M2])
                  if they_did_touch:
                   HEH_collide_max += 1
                   HEH_collide_w    += [New_ball1_w]
                   HEH_collide_z     += [New_ball1_z]
                   HEH_collide_ang    += [angle_hit_at]
                   HEH_collide_dis     += [distance_2D(wa, za, New_ball1_w, New_ball1_z)]
                   HEH_collide_ball_hit += [M2]
            current_dis = distance_is_supposed_to_be_at
            Wall_to_hit_at_angley = None
            Grr = -1
            while Grr < LIN_collide_max:
             Grr += 1
             #print LIN_collide_dis[Grr], current_dis
             if LIN_collide_dis[Grr] < current_dis:
               #print 'weee!'
               Wall_to_hit_at_angley = LIN_collide_ang[Grr]
               current_dis = LIN_collide_dis[Grr]
               will_be_w = LIN_collide_w[Grr]
               will_be_z = LIN_collide_z[Grr]
            Ball_to_hit = None
            Ball_to_hit_at_angley = None
            Heh = -1
            while Heh < HEH_collide_max:
             Heh += 1
             if HEH_collide_dis[Heh] < current_dis:
              if ball_is_going_towards_ball(M, HEH_collide_ball_hit[Heh]):
               if ball_is_relatively_going_towards_ball(M, HEH_collide_ball_hit[Heh]):
                Ball_to_hit = HEH_collide_ball_hit[Heh]
                Ball_to_hit_at_angley = HEH_collide_ang[Heh]
               else:
                Ball_to_hit = None
                Ball_to_hit_at_angley = None
               current_dis = HEH_collide_dis[Heh]
               will_be_w = HEH_collide_w[Heh]
               will_be_z = HEH_collide_z[Heh]
            if Ball_to_hit != None:
             Make_two_balls_hit_at_angle(M, Ball_to_hit, Ball_to_hit_at_angley)
            else:
             #if   bouncey == 1: ball_wol[M] = -ball_wol[M] * bounce_friction
             #elif bouncey == 2: ball_zol[M] = -ball_zol[M] * bounce_friction
             if Wall_to_hit_at_angley != None:
              ball_wol[M], ball_zol[M] = wzol_bounce_at_angle(ball_wol[M], ball_zol[M], Wall_to_hit_at_angley, bounce_friction)
              ball_angleol[M] = zol_at_angle(ball_wol[M], ball_zol[M], Wall_to_hit_at_angley + 90) / ball_rad[M] * rock_and_ROLLY
            ball_w[M] = will_be_w
            ball_z[M] = will_be_z
            if ball_w[M] < 0 or ball_w[M] > APPLICATION_w_size or ball_z[M] < 0 or ball_z[M] > APPLICATION_z_size:
             #print str(M) + "   ", str(wa), str(za)
             print str(M) + "   ", str(ball_w[M]), str(ball_z[M]), str(ball_rad[M])
            ball_wol[M] *= air_friction
            ball_zol[M] *= air_friction
            updatey_ball_quick_rect(M)
            if current_dis < distance_is_supposed_to_be_at:
             if Try_Again_HE_HE > 0:
              distance_to_travel_next = distance_is_supposed_to_be_at - current_dis
              disy_HE_HE = distance_2D(0, 0, ball_wol[M], ball_zol[M])
              next_wol = ball_wol[M]
              next_zol = ball_zol[M]
              movey_bally_speciality(M, next_wol, next_zol, Try_Again_HE_HE - 1)

           ## Woah... Finally! Were near the end of the program! ##
if __name__ == '__main__':
  import math
  import pygame
  import random
  import time
  import gc
  import copy
  from   pygame.locals import *
  if not pygame.font: print 'Warning, fonts disabled?'
  if not pygame.mixer: print 'Warning, sound disabled?'
  HE_HE_init()
           ## THE END! ##

M31
Jun 12, 2012
Please tell me you punched that guy in the face

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Source: Matthew N. Brown from the pygame.draw.circle doc comments. I had to cut out a few levels of data because it was over the posting limit.

He makes some interesting posts on the pygame mailing list. Whole thread's gold.

canis minor
May 4, 2011


I feel stupider and I just scrolled past the code, glimpsing at bits and pieces.

vOv
Feb 8, 2014

Suspicious Dish posted:

Source: Matthew N. Brown from the pygame.draw.circle doc comments. I had to cut out a few levels of data because it was over the posting limit.

He makes some interesting posts on the pygame mailing list. Whole thread's gold.

quote:

Haven't I just given you one of the most profound statements of
efficient game programming?
Shouldn't you be grateful? Thank you for all your replies everyone I
guess I'm not wanted here.

You weren't kidding.

Don Mega
Nov 26, 2005
:vince:

Damiya
Jul 3, 2012
So Node has a library called image-min that a bunch of libraries depend on and wrap around.

image-min (in older versions) relied on a project in the node package system called cache-file.

NPM allows you to outright remove packages from the repo which was done to cache-file at some point today.

Anyone depending on that package somewhere in their dependency chain is no longer able to install their packages.

https://github.com/sindresorhus/gulp-imagemin/issues/18

lol

shrughes
Oct 11, 2008

(call/cc call/cc)

Cancelbot posted:

And if you're strict with .NET styling rules; nested generics are also an unnecessary complication.

Really? How would you propose omitting the nested generics in a way that's less complicated?

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.

JawnV6 posted:

Rather than have gosh, what is it, 5 freakin lines of code, you'd rather completely change the interface to the function under test.
I think that genuinely is better than creating an IDateProvider abstraction to pretty much do the same thing. This doesn't mean I think DI is a useless concept, but there are lots of codebases where any time someone needed a fallback there's this whole interface-class-mock layer which makes the codebase (and the tests themselves) harder to maintain.

It's still no PHP or Node, thankfully :)

JawnV6
Jul 4, 2004

So hot ...

Sagacity posted:

I think that genuinely is better than creating an IDateProvider abstraction to pretty much do the same thing. This doesn't mean I think DI is a useless concept, but there are lots of codebases where any time someone needed a fallback there's this whole interface-class-mock layer which makes the codebase (and the tests themselves) harder to maintain.

No. It's not "pretty much do the same thing." You're advocating forking the production code base, hiding all these changes from your tools, then pretending that testing this not-production code has any meaning. Who's in charge of making sure the fake code base and the production code base are in sync?

DI is forcing you to inform the tools of the changes you're making. And have the tools manage those changed dependencies. Not this one-off ad hoc bullshit. You're like Spolsky rejecting tooled type systems in favor of "programmer gut checks" and it's just as abhorrent.

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.

JawnV6 posted:

No. It's not "pretty much do the same thing." You're advocating forking the production code base, hiding all these changes from your tools, then pretending that testing this not-production code has any meaning. Who's in charge of making sure the fake code base and the production code base are in sync?
How is this different than using a mock implementation of DateProvider in your unit tests? Just because you've wrapped it up in an interface doesn't change that, nor the fact that you're using an IoC mechanism to inject your constructor parameters instead of just passing in a parameter manually.

If anything, you now have additional constructor parameters that you need to fill just because one of the methods in your class may need that dependency. If you're testing another method (that does NOT do anything with datetime) you still need to provide a DateTimeProvder just to be able to construct your class. In this case it may be a simple DateTimeProvider but this doesn't scale too well (MVC controllers that have 14 dependencies to IFooRepository, ISendMailService, etc).

All of this can be fixed by only working with sane, smart people that know when to stop adding dependencies and start refactoring. Rebuttal: this thread.

JawnV6 posted:

You're like Spolsky rejecting tooled type systems in favor of "programmer gut checks" and it's just as abhorrent.
Am I falling victim to a variant of Godwin's Law here?

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


I have been nursing a mild addiction to one of those sites with user-submitted code challenges. You get a description of the problem, and your code is run against some number of test cases.

Here's a javascript one I liked:

quote:

Given string representations of two integers, return the string representation of the sum of those integers.

For example:
code:
sumStrings('1','2') // => '3'
A string representation of an integer will contain no characters besides the ten numerals "0" to "9".

My javascript style won't win any prizes for terseness (or anything else), so my solution was around 45loc.

But then the fun really starts: once you have a passing solution, you can see everyone else's passing solutions, perhaps discovering new language features and opportunities for refactoring!

Hmm, let's see wha:stare:
code:
function sumStrings(a,b) {
  var a = new BigNumber(a),
      b = new BigNumber(b);
  return a.add(b).toString();
}

BigNumber = function(n, p, r){
    var o = this, i;
    if(n instanceof BigNumber){
        for(i in {precision: 0, roundType: 0, _s: 0, _f: 0}) o[i] = n[i];
        o._d = n._d.slice();
        return;
    }
    o.precision = isNaN(p = Math.abs(p)) ? BigNumber.defaultPrecision : p;
    o.roundType = isNaN(r = Math.abs(r)) ? BigNumber.defaultRoundType : r;
    o._s = (n += "").charAt(0) == "-";
    o._f = ((n = n.replace(/[^\d.]/g, "").split(".", 2))[0] = n[0].replace(/^0+/, "") || "0").length;
    for(i = (n = o._d = (n.join("") || "0").split("")).length; i; n[--i] = +n[i]);
    o.round();
};
with({$: BigNumber, o: BigNumber.prototype}){
    $.ROUND_HALF_EVEN = ($.ROUND_HALF_DOWN = ($.ROUND_HALF_UP = ($.ROUND_FLOOR = ($.ROUND_CEIL = ($.ROUND_DOWN = ($.ROUND_UP = 0) + 1) + 1) + 1) + 1) + 1) + 1;
    $.defaultPrecision = 40;
    $.defaultRoundType = $.ROUND_HALF_UP;
    o.add = function(n){
        if(this._s != (n = new BigNumber(n))._s)
            return n._s ^= 1, this.subtract(n);
        var o = new BigNumber(this), a = o._d, b = n._d, la = o._f,
        lb = n._f, n = Math.max(la, lb), i, r;
        la != lb && ((lb = la - lb) > 0 ? o._zeroes(b, lb, 1) : o._zeroes(a, -lb, 1));
        i = (la = a.length) == (lb = b.length) ? a.length : ((lb = la - lb) > 0 ? o._zeroes(b, lb) : o._zeroes(a, -lb)).length;
        for(r = 0; i; r = (a[--i] = a[i] + b[i] + r) / 10 >>> 0, a[i] %= 10);
        return r && ++n && a.unshift(r), o._f = n, o.round();
    };
    o.subtract = function(n){
        if(this._s != (n = new BigNumber(n))._s)
            return n._s ^= 1, this.add(n);
        var o = new BigNumber(this), c = o.abs().compare(n.abs()) + 1, a = c ? o : n, b = c ? n : o, la = a._f, lb = b._f, d = la, i, j;
        a = a._d, b = b._d, la != lb && ((lb = la - lb) > 0 ? o._zeroes(b, lb, 1) : o._zeroes(a, -lb, 1));
        for(i = (la = a.length) == (lb = b.length) ? a.length : ((lb = la - lb) > 0 ? o._zeroes(b, lb) : o._zeroes(a, -lb)).length; i;){
            if(a[--i] < b[i]){
                for(j = i; j && !a[--j]; a[j] = 9);
                --a[j], a[i] += 10;
            }
            b[i] = a[i] - b[i];
        }
        return c || (o._s ^= 1), o._f = d, o._d = b, o.round();
    };
    o.multiply = function(n){
        var o = new BigNumber(this), r = o._d.length >= (n = new BigNumber(n))._d.length, a = (r ? o : n)._d,
        b = (r ? n : o)._d, la = a.length, lb = b.length, x = new BigNumber, i, j, s;
        for(i = lb; i; r && s.unshift(r), x.set(x.add(new BigNumber(s.join("")))))
            for(s = (new Array(lb - --i)).join("0").split(""), r = 0, j = la; j; r += a[--j] * b[i], s.unshift(r % 10), r = (r / 10) >>> 0);
        return o._s = o._s != n._s, o._f = ((r = la + lb - o._f - n._f) >= (j = (o._d = x._d).length) ? this._zeroes(o._d, r - j + 1, 1).length : j) - r, o.round();
    };
    o.divide = function(n){
        if((n = new BigNumber(n)) == "0")
            throw new Error("Division by 0");
        else if(this == "0")
            return new BigNumber;
        var o = new BigNumber(this), a = o._d, b = n._d, la = a.length - o._f,
        lb = b.length - n._f, r = new BigNumber, i = 0, j, s, l, f = 1, c = 0, e = 0;
        r._s = o._s != n._s, r.precision = Math.max(o.precision, n.precision),
        r._f = +r._d.pop(), la != lb && o._zeroes(la > lb ? b : a, Math.abs(la - lb));
        n._f = b.length, b = n, b._s = false, b = b.round();
        for(n = new BigNumber; a[0] == "0"; a.shift());
        out:
        do{
            for(l = c = 0, n == "0" && (n._d = [], n._f = 0); i < a.length && n.compare(b) == -1; ++i){
                (l = i + 1 == a.length, (!f && ++c > 1 || (e = l && n == "0" && a[i] == "0")))
                && (r._f == r._d.length && ++r._f, r._d.push(0));
                (a[i] == "0" && n == "0") || (n._d.push(a[i]), ++n._f);
                if(e)
                    break out;
                if((l && n.compare(b) == -1 && (r._f == r._d.length && ++r._f, 1)) || (l = 0))
                    while(r._d.push(0), n._d.push(0), ++n._f, n.compare(b) == -1);
            }
            if(f = 0, n.compare(b) == -1 && !(l = 0))
                while(l ? r._d.push(0) : l = 1, n._d.push(0), ++n._f, n.compare(b) == -1);
            for(s = new BigNumber, j = 0; n.compare(y = s.add(b)) + 1 && ++j; s.set(y));
            n.set(n.subtract(s)), !l && r._f == r._d.length && ++r._f, r._d.push(j);
        }
        while((i < a.length || n != "0") && (r._d.length - r._f) <= r.precision);
        return r.round();
    };
    o.mod = function(n){
        return this.subtract(this.divide(n).intPart().multiply(n));
    };
    o.pow = function(n){
        var o = new BigNumber(this), i;
        if((n = (new BigNumber(n)).intPart()) == 0) return o.set(1);
        for(i = Math.abs(n); --i; o.set(o.multiply(this)));
        return n < 0 ? o.set((new BigNumber(1)).divide(o)) : o;
    };
    o.set = function(n){
        return this.constructor(n), this;
    };
    o.compare = function(n){
        var a = this, la = this._f, b = new BigNumber(n), lb = b._f, r = [-1, 1], i, l;
        if(a._s != b._s)
            return a._s ? -1 : 1;
        if(la != lb)
            return r[(la > lb) ^ a._s];
        for(la = (a = a._d).length, lb = (b = b._d).length, i = -1, l = Math.min(la, lb); ++i < l;)
            if(a[i] != b[i])
                return r[(a[i] > b[i]) ^ a._s];
        return la != lb ? r[(la > lb) ^ a._s] : 0;
    };
    o.negate = function(){
        var n = new BigNumber(this); return n._s ^= 1, n;
    };
    o.abs = function(){
        var n = new BigNumber(this); return n._s = 0, n;
    };
    o.intPart = function(){
        return new BigNumber((this._s ? "-" : "") + (this._d.slice(0, this._f).join("") || "0"));
    };
    o.valueOf = o.toString = function(){
        var o = this;
        return (o._s ? "-" : "") + (o._d.slice(0, o._f).join("") || "0") + (o._f != o._d.length ? "." + o._d.slice(o._f).join("") : "");
    };
    o._zeroes = function(n, l, t){
        var s = ["push", "unshift"][t || 0];
        for(++l; --l;  n[s](0));
        return n;
    };
    o.round = function(){
        if("_rounding" in this) return this;
        var $ = BigNumber, r = this.roundType, b = this._d, d, p, n, x;
        for(this._rounding = true; this._f > 1 && !b[0]; --this._f, b.shift());
        for(d = this._f, p = this.precision + d, n = b[p]; b.length > d && !b[b.length -1]; b.pop());
        x = (this._s ? "-" : "") + (p - d ? "0." + this._zeroes([], p - d - 1).join("") : "") + 1;
        if(b.length > p){
            n && (r == $.DOWN ? false : r == $.UP ? true : r == $.CEIL ? !this._s
            : r == $.FLOOR ? this._s : r == $.HALF_UP ? n >= 5 : r == $.HALF_DOWN ? n > 5
            : r == $.HALF_EVEN ? n >= 5 && b[p - 1] & 1 : false) && this.add(x);
            b.splice(p, b.length - p);
        }
        return delete this._rounding, this;
    };
}

Doc Hawkins fucked around with this message at 22:13 on Mar 31, 2014

EAT THE EGGS RICOLA
May 29, 2008

Doc Hawkins posted:


Hmm, let's see wha:stare:
This is the work of an artiste

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


I mean, I assume they just googled "bigint in js".

JawnV6
Jul 4, 2004

So hot ...

Sagacity posted:

All of this can be fixed by only working with sane, smart people that know when to stop adding dependencies and start refactoring. Rebuttal: this thread.

Sane, smart people who don't test their production code? Sane, smart people who completely rewrite the code base to be easier to test? That seems to be our working definition here.

Cancelbot
Nov 22, 2006

Canceling spam since 1928

shrughes posted:

Really? How would you propose omitting the nested generics in a way that's less complicated?

Wrapping the nested type within a class is the recommended practice, here's a dumb example which achieves the same thing, typed up without any checking:
code:
IDictionary<long, MyCustomType> _superDictionary;

class MyCustomType
{
    IDictionary<DateTime, InnerType> _inner;

    public this[DateTime index]
    {
        return _inner[index];
    }
}
But like I said if you're strict, and listening to FxCop. Or have complex behaviours which are usually indicated by using a double-dictionary in the first place. So that should be unit tested in as small as a unit as possible, rather than creating the whole dictionary-upon-dictionary to test the innermost collection.

But if you're writing a Func<IEnumerable<int>> then It's different; context, context, context.

Cancelbot fucked around with this message at 22:39 on Mar 31, 2014

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Doc Hawkins posted:

I have been nursing a mild addiction to one of those sites with user-submitted code challenges. You get a description of the problem, and your code is run against some number of test cases.

...

But then the fun really starts: once you have a passing solution, you can see everyone else's passing solutions, perhaps discovering new language features and opportunities for refactoring!

Link?

Adbot
ADBOT LOVES YOU

seiken
Feb 7, 2005

hah ha ha

Cancelbot posted:

code:
IDictionary<long, MyCustomType> _superDictionary;

class MyCustomType
{
    IDictionary<DateTime, InnerType> _inner;

    public this[DateTime index]
    {
        return _inner[index];
    }
}

That's bizarre and I don't know why you'd bother. Now you have to add wrapper methods for each Dictionary method you want to use.

A nested dictionary like Dictionary<K1, Dictionary<K2, V>> is equivalent to Dictionary<K, V> where K is a struct with two elements K1 and K2 though, which is a much more useful way to avoid nested generics if you really dislike them for some reason.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply