Wednesday, July 16, 2008

Designing A Hockey Power-Play System

In hockey (using NHL as my reference here), there is something called a "power-play", or alternatively referred to as a "man advantage". In hockey each team has 5 players on the ice at 1 time: 3 forwards, 2 defense men, and 1 goalie. Teams are allowed to pull their goalie out and add an extra skilled player (usually a forward) in order to increase their chances of scoring, but that's not important here. When a team commits a penalty (more accurately, when a player commits a penalty), that player must sit in the penalty box for a duration of time, either 2, 4, 5, or 10 minutes (depending on severity). During this time, the opposing team is said to have a "power-play" and a 5 man to 4 man advantage. Naturally, if the team on a power-play commits a penalty while they have a man-advantage, they will lose that player to the penalty box, and the teams will be in a 4 on 4 situation.

Additionally, if a team commits another penalty while they are already at a disadvantage, they can be reduced another man, and then they are on a 5 man to 3 man disadvantage. In the event a third penalty is committed by the same team prior to any of the previous two offenders being released from the box, that player will be substituted out of the game for a backup, and he too will go to the penalty box. Teams must always have at least 3 men on the ice, and no more than 3 in the penalty box. To make things even more troubling to deal with, power-plays carry over between periods. That is to say, if there is 1:30 left in the 2nd period and a team commits a 2:00 penalty, then that player will have to remain in the penalty box for the first :30 of the 3rd period.

So, what does this have to do with game programming? Quite a lot if you're making a hockey game! So, what are we left with? A very complex problem that needs solving! Being a huge hockey fan and clearly a game developer, I wanted to see what I could come up with solve this tricky issue. Sure, it's been done before, but not by me, so what good does that do me?

My rough general overview of how to deal with this goes something like this:
  • When a penalty occurs, remove the player from the ice and start a timer for the appropriate duration
  • If another penalty occurs by the same team during that time, we'll need to save the time remaining in the first power play. Then, set the 5 on 3 timer to the Remaining Duration Of The 1st Penalty
  • When the 5 on 3 timer expires, set the 5 on 4 timer to the remaining duration of the 1st penalty that we saved earlier.
  • When the 5 on 4 timer expires, place the offender of the 2nd penalty back on the ice and return as normal
Now, as you have probably already noticed, this is only accounting for that particular situation, when in fact any number of terrible combinations could happen, most of which involve the team on the power-play committing a penalty, or some awful back and forth situation of which I don't even want to think about...

Anyhow, the way I'm working on tackling this is by using a tier system. The way it would work is that you could easily move up/down the penalty tier, sort of like Linux runlevels. For instance, if the teams are at equal strength and then team 1 commits a penalty, you move that team to penalty tier 1, which is a 4 on 5 disadvantage. If they commit yet another penalty, you move them to penalty tier 2, which is a 3 on 5 disadvantage. You handle the timers the same way as stated above, as all of that behavior would be encapsulated in the tier system. Then, when the first penalty expires, you move team 1 down from penalty tier 2 to penalty tier 1 (4 on 5 disadvantage), and etc...

If designed properly, any sort of flip-flopping with the team on the power-play committing a penalty should just work because the system would simply adjust the penalty tier of both teams, or something similar.

The details aren't clear yet as I'm just starting this, but I'll update this with what I've come up with as time goes on, but I'm very excited to find a decent solution!

No comments: