Java (JDK), 61 bytes
(a,b)->b<0||b>29||a>b+2&&a>21||a>30?0:a>20&&(a>29||a>b+1)?2:1
Returns 0
for invalid games, 1
for valid ongoing games, 2
for valid finished games. Takes the score ordered, with the higher score first.
##Ungolfed
(a,b) ->
b < 0 // Invalid if either number is negative
|| b > 29 // Invalid if b over 29
|| a > b + 2
&& a > 21 // Invalid if a should've already won
|| a > 30 // Invalid if a over 30
? 0 // Return 0 if invalid
: a > 20 // Can only be a win if a has at least 20 pts
&& ( a > 29 // If a is 30, a has won
|| a > b + 1 // Otherwise a needs a 2 pt lead
)
? 2 // Return 2 for a win
: 1 // Return 1 otherwise