[Question]
  [
In light of the 2014 Australian Open in Melbourne, and the win by Stanislas Wawrinka against Novak Djokovic, I propose the following code golf challenge!
Wawrinka and Djokovic are at it again for the basis of this CGC. Your challenge is to take a string consisting of 1's and 2's and determine the tennis scores based on the tennis scoring system. A "1" indicates that Wawrinka has scored a point, whereas a "2" indicates that Djokovic has scored a point.
For the sake of example: `1211222122111122111` will generate a two-line output:
```
Wawrinka 1 - 40
Djokovic 1 - 30
```
The longer the string, the further into the game the score is.
Rules:
* Shortest code wins, pure and simple.
* The scores when displayed must be right aligned and also column
aligned; e.g.
* Sample alignment of output:
```
Wawrinka 7 5 3 -  0
Djokovic 6 7 4 - 15
```
* If a game is in progress, the score must be displayed after the set scores. Game scores must follow set scores with a space-dash-space separator. If this happens to be the first game, a 0-0 set score must be displayed.
```
Wawrinka 0 -  0
Djokovic 0 - 15
```
* A game will go in order of 0, 15, 30, 40, and game point. If a game reaches 40-40, a deuce is declared, and the score must display the deuce on the player row scoring the point:
```
Wawrinka 7 5 3 - 40
Djokovic 6 7 4 - 40 Deuce
```
* If a deuce is reached, the next point will be an advantage to the player scoring the point:
```
Wawrinka 7 5 3 - Ad
Djokovic 6 7 4 - 40
```
The point after that, if scored by the advantaged player, wins the game, else the game goes back to deuce.
* If more than one deuce is scored in between advantage points, the
number of the deuce will be indicated by a number in parentheses:
```
Wawrinka 7 5 3 - 40
Djokovic 6 7 4 - 40 Deuce (2)
```
* A set is won if a player reaches 6 games or more and with a two game
margin in lead, e.g. 7-5, 6-4... 9-7 (In the case of last night's
fifth set)
* Consecutive sets must be separated with a space.
* There are tie breaks in the Australian Open, therefore if a 6-6 set is reached, a tie-break is established by the first player reaching seven points with a two point margin lead. Display of tie breaks are shown within square brackets as follows:
```
Wawrinka 7 6 [6]
Djokovic 6 6 [4]
```
The winner of the tie-break is said to have won the previous set 7-6.
* If the fifth set reaches 6-6, play is continued without tie-break until a two game margin is reached with one player, that player being the winner of that set. There are NO tie-breaks in the fifth set.
* If a player has won three sets, a third line will be displayed saying
`Wawrinka wins` or `Djokovic wins` depending on who has won and the code then terminates.
```
Wawrinka 2 6 6 3 9
Djokovic 6 4 2 6 7
Wawrinka wins
```
* If the string ends such that the last point has won a game, set or
match, the game score is not displayed...
```
Wawrinka 7 5 3
Djokovic 6 7 4
```
* If the string goes beyond a match being won, the rest of the string
is ignored, the score displayed and the winner declared.
  
[Answer]
## Perl - 424 bytes
```
*1=a;*2=b;@1=(Wawrinka,0);@2=(Djokovic,0);
$$_++>${$o=S^$_}&&$$_>3and$1=$2=0,
$w=$w[$_]+=($$_[$.]++>$$o[$.]||(($t=$$_[$.]==$$o[$.])&&!$%&&$.<5))&&
$$_[$.]>5+$%&&!($1[$.]=$2[$.+=!$%]=$w<2&&0,$$_[$.-1]+=$%,$%=$t)for<>=~/./g;
@s=(' 0',15,30,(40)x($e=$$o<3||$$o-2),Ad);
$%and$_="[$_]"for@1[-1],@2[-1];$d[$&]=$1>2&&$1==$2&&' Deuce'.($1>3&&" ($e)");
print"@1",$w<3&&" - $s[$1]$d[1]","\n@2",$w<3&&" - $s[$2]$d[2]",$w>2&&"\n${$&}[0] wins"
```
*Newlines have been added for ~~readability~~ horizontal sanity.*
I believe this to be a complete solution, according to the scoring of the [Australian Open](http://www.ausopen.com/en_AU/event_guide/a_z_guide.html):
* Best of five sets (a.k.a. race to three).
* Sets 1-4 are played as a 6-6 tie-breaker.
* Set 5 is played as an advantage set.
### Test Cases
---
```
1211222122111122111
```
# 
```
Wawrinka 1 - 40
Djokovic 1 - 30
```
---
```
12112221221111221112
```
# 
```
Wawrinka 1 - 40
Djokovic 1 - 40 Deuce
```
---
```
121122212211112211122
```
# 
```
Wawrinka 1 - 40
Djokovic 1 - Ad
```
---
```
1211222122111122111221
```
# 
```
Wawrinka 1 - 40 Deuce (2)
Djokovic 1 - 40
```
---
```
22111111212122221122111212212112121221212211221121222222112112221121121122221122221211111222121222122211212122111212112211222121211212211212211122121211112222222212211121122
```
# 
```
Wawrinka 6 [5] - 30
Djokovic 6 [6] - 40
```
---
```
221111112121222211221112122121121212212122112211212222221121122211211211222211222212111112221212221222112121221112121122112221212112122112122111221212111122222222122111211222
```
# 
```
Wawrinka 6 0 -  0
Djokovic 7 0 -  0
```
---
```
1122222211121211121211111121111211221222212212112221211222211222112212211121122122212122212222122212212211221111121222111221211111211112222212122122112111212121221221212211112122212211111111112111212222221112212121122212121111122111222222111212221121221111222122122222111212111111221121122111122122111222222121122221112221221122221121211212111122111121212112112121222122
```
# 
```
Wawrinka 5 4 6 6 5 - 15
Djokovic 7 6 4 4 6 - 40
```
---
```
11222222111212111212111111211112112212222122121122212112222112221122122111211221222121222122221222122122112211111212221112212111112111122222121221221121112121212212212122111121222122111111111121112122222211122121211222121211111221112222221112122211212211112221221222221112121111112211211221111221221112222221211222211122212211222211212112121111221111212121121121212221222
```
# 
```
Wawrinka 5 4 6 6 5
Djokovic 7 6 4 4 7
Djokovic wins
```
---
```
222221112112212212222111222211111111121111121112211221221211212121122211222112111112122122212222211112122212221111121111121211212112112112221221121122121121112221221222122122211222212121212112112111221221121112222212122222221111112222222221221122211221121111221121222222111111122221122111211121222112112122212122221121222221222121212111121221221112111212212222122212212212112111112112112121112221111221221221121222122211221212211111111222222121221112221212
```
# 
```
Wawrinka 6 7 6 4 7 - 40
Djokovic 3 5 7 6 8 - Ad
```
---
```
2222211121122122122221112222111111111211111211122112212212112121211222112221121111121221222122222111121222122211111211111212112121121121122212211211221211211122212212221221222112222121212121121121112212211211122222121222222211111122222222212211222112211211112211212222221111111222211221112111212221121121222121222211212222212221212121111212212211121112122122221222122122121121111121121121211122211112212212211212221222112212122111111112222221212211122212122
```
# 
```
Wawrinka 6 7 6 4 7 
Djokovic 3 5 7 6 9 
Djokovic wins
```
All intermediate scores for the last test case can be seen here: <http://codepad.org/FzDIcf0W>
[Answer]
**ECMAScript 6 - 635 Characters**
```
f=(p,q,C)=>{B='';T=' ';L=(x)=>(B+x).length;M=(x,y)=>x>y?x:y;E=(a)=>{var x=L(a[0]),y=L(a[1]),q=M(x,y);for(;x++<q;)a[0]=T+a[0];for(;y++<q;)a[1]=T+a[1]};E(a=[p,q]);g=[m=n=o=i=t=z=0,0];s=[0,0];S=[0,0];w=2;O=(i)=>a[i]+(n+o>0?T+s[i]:B)+(o>0?(t?' ['+g[i]+']':' - '+[' 0',15,30,40,'Ad'][g[i]]+(z>0&&g[0]+g[1]==6&&i==w?' Deuce'+(z>1?' ('+z+')':B):B)):B)+'\n';while(W=C[i++]){w=--W;++o;if((d=++g[w])>M(t?6:3,(e=g[l=1-w])+1)){g=[o=z=0,0];j=++s[w];k=s[l];t=++n>11;if(j>M(5,m>4||k<6?k+1:6)){E(s);a[0]+=T+s[0];a[1]+=T+s[1];s=[n=0,0];++m;if(++S[w]>2)break}}else if(!t&&d+e>7){--g[w];--g[l];++z}}E(s);E(g);return O(0)+O(1)+(S[w]>2?(w?q:p)+' wins':B)}
```
**With comments:**
```
// Function f takes arguments:
//   p - Player 1 name
//   q - Player 2 name
//   C - String of 1s and 2s representing points won by players.
f=(p,q,C)=>{
    /* Empty String          */ B='';
    /* Space                 */ T=' ';
    /* String Length Func.   */ L=(x)=>(B+x).length;
    /* Max Function          */ M=(x,y)=>x>y?x:y;
    /* Equalize Length Func. */ E=(a)=>{var x=L(a[0]),y=L(a[1]),q=M(x,y);for(;x++<q;)a[0]=T+a[0];for(;y++<q;)a[1]=T+a[1]};
    /* No. of sets           */ m=0;
    /* No. games in set      */ n=0;
    /* No. points in game    */ o=0;
    /* Input Index           */ i=0;
    /* Output String         */ E(a=[p,q]);
    /* Current Game's Points */ g=[0,0];
    /* Current Set's Games   */ s=[0,0];
    /* No. sets won          */ S=[0,0];
    /* Is a tiebreaker       */ t=0;
    /* No. of deuces         */ z=0;
    /* Current match result  */ w=2;
    /* Output Fnctn  */ O=(i)=>a[i]+(n+o>0?T+s[i]:B)+(o>0?(t?' ['+g[i]+']':' - '+[' 0',15,30,40,'Ad'][g[i]]+(z>0&&g[0]+g[1]==6&&i==w?' Deuce'+(z>1?' ('+z+')':B):B)):B)+'\n';
    while(W=C[i++]){
        w=--W;
        // w - index of winner of current game
        // l - index of loser of current game
        // d - winner of current point's game score
        // e - loser of current point's game score
        ++o;
        if((d=++g[w])>M(t?6:3,(e=g[l=1-w])+1)){ 
            g=[0,0];  // Reset the game score.
            o=z=0;
            j=++s[w]; // j = Increment the winner's set score
            k=s[l];   // k = Loser's set score
            t=++n>11; // Is a tiebreak?
            if(j>M(5,m>4||k<6?k+1:6)){
                E(s);
                a[0]+=T+s[0]; // Add to output
                a[1]+=T+s[1]; // Add to output
                s=[n=0,0];  // Reset current set's no. of games & no. of deuces.
                ++m;        // Increment no. of sets.
                if(++S[w]>2)break;     // Increment winners no. sets won and check if match won.
            }
        }
        else if(!t&&d+e>7){--g[w];--g[l];++z}// Check if deuces increased.
    }
    E(s); // Format sets strings.
    E(g); // Format games strings.
    return O(0)+O(1)+(S[w]>2?(w?q:p)+' wins':B);
}
```
**Testing**
```
var tests=[
            '',
            '1',
            '2',
            '11',
            '222',
            '1111',
            '2222',
            '1112221',
            '11122212',
            '121212121',
            '1212121212',
            '1211222122111122111',
            '12112221221111221112',
            '121122212211112211122',
            '1211222122111122111221',
            '1111222211112222111122221111222211112222111122221212121212121212121',
            '11111111111111111111111111111111111111111111111111111111111111111111111',
            '111111111111111111111111111111111111111111111111111111111111111111111111',
            '1111111111111111111111111111111111111111111111111111111111111111111111111'
        ];
for(var ex in tests) console.log('Test '+ex+'\n'+tests[ex]+'\n'+f('Wawrinka','Djokovic',tests[ex]));
```
**Test Outputs**
```
Test 0
Wawrinka
Djokovic
Test 1
1
Wawrinka 0 - 15
Djokovic 0 -  0
Test 2
2
Wawrinka 0 -  0
Djokovic 0 - 15
Test 3
11
Wawrinka 0 - 30
Djokovic 0 -  0
Test 4
222
Wawrinka 0 -  0
Djokovic 0 - 40
Test 5
1111
Wawrinka 1
Djokovic 0
Test 6
2222
Wawrinka 0
Djokovic 1
Test 7
1112221
Wawrinka 0 - Ad
Djokovic 0 - 40
Test 8
11122212
Wawrinka 0 - 40
Djokovic 0 - 40 Deuce
Test 9
121212121
Wawrinka 0 - Ad
Djokovic 0 - 40
Test 10
1212121212
Wawrinka 0 - 40
Djokovic 0 - 40 Deuce (2)
Test 11
1211222122111122111
Wawrinka 1 - 40
Djokovic 1 - 30
Test 12
12112221221111221112
Wawrinka 1 - 40
Djokovic 1 - 40
Test 13
121122212211112211122
Wawrinka 1 - 40
Djokovic 1 - Ad
Test 14
1211222122111122111221
Wawrinka 1 - 40 Deuce
Djokovic 1 - 40
Test 15
1111222211112222111122221111222211112222111122221212121212121212121
Wawrinka 6 [10]
Djokovic 6 [ 9]
Test 16
11111111111111111111111111111111111111111111111111111111111111111111111
Wawrinka 6 6 5 - 40
Djokovic 0 0 0 -  0
Test 17
111111111111111111111111111111111111111111111111111111111111111111111111
Wawrinka 6 6 6
Djokovic 0 0 0
Wawrinka wins
Test 18
1111111111111111111111111111111111111111111111111111111111111111111111111
Wawrinka 6 6 6
Djokovic 0 0 0
Wawrinka wins
```
[Answer]
# Javascript - 743 bytes
```
var b=process.argv[2],c=[0,0],e=[],g=[0,0],h=[0,0],k=["0","15","30","40"],l=["Wawrinka","Djokovic"];function m(a){var d="",f;for(f in e)d+=e[f][a]+" ";3<=c[0]||3<=c[1]||(d+=g[a]+" - ",f=h[a],a=h[(a+1)%2],d=n()?d+("["+f+"]"):3>f||3>a?d+k[f]:f>a?d+"Ad":d+k[3]);return d}function n(){return 6<=g[0]&&6<=g[1]}function p(){var a=q;g[a]++;h=[0,0];7<=g[a]?(e.push(g),g=[0,0],c[a]++):6<=g[a]&&g[a]>g[(a+1)%2]+1&&(e.push(g),g=[0,0],c[a]++)} for(var r in b){var q=parseInt(b[r])-1,s=++h[q];n()?7<=s&&(4>e.length?p():s>h[(q+1)%2]+1&&p()):4<=s&&s>h[(q+1)%2]+1&&p()}console.log(l[0]," ",m(0));console.log(l[1]," ",m(1),n()?"":2<h[0]&&2<h[1]&&h[0]==h[1]?"Deuce"+(3<h[0]?" ("+(h[0]-2)+")":""):"");console.log(3<=c[0]||3<=c[1]?(3<=c[0]?l[0]:l[1])+" wins":"");
```
Without closure compiler:
```
var input = process.argv[2];
var score = [0,0];
var match = [];
var set = [0,0];
var game = [0,0];
var gameScore = [ '0', '15', '30', '40' ];
var names = ['Wawrinka', 'Djokovic'];
function printScores(who)
{
    var out = '';
    for (var i in match) {
        out += match[i][who] + ' ';
    }
    if (!isDone()) {
        out += set[who] + ' - ';
        var point = game[who], otherPoint = game[(who+1)%2];
        if (isTieBreaker()) { // Tie breaker
            out += '['+point+']';
        } else {
            if (point < 3 || otherPoint < 3) {
                out += gameScore[point];
            } else if (point > otherPoint) {
                out += 'Ad';
            } else {
                out+= gameScore[3];
            }
        }
    }
    return out;
}
function printDeuce()
{
    if (isTieBreaker()) {
        return '';
    } else {
        return (game[0] > 2 && game[1] > 2 && game[0] == game[1]) ? ('Deuce' + (game[0] > 3 ? ' (' + (game[0] - 2) + ')' : '')) : '';
    }
}
function isDone()
{
    return score[0] >= 3 || score[1] >= 3;
}
function isTieBreaker()
{
    return set[0] >= 6 && set[1] >= 6;
}
function getOther(who)
{
    return (who + 1) % 2;
}
function addPoint(who)
{
    var points = ++game[who];
    if (isTieBreaker()) {
        if (points >= 7) {
            if (match.length < 4) {
                addGame(who);
            } else if (points > (game[getOther(who)]+ 1)) {
                addGame(who);
            }
        }
    } else {
        if (points >= 4 && points > (game[getOther(who)] + 1)) {
            addGame(who);
        }
    }
}
function addGame(who)
{
    set[who]++;
    game = [0,0];
    if (set[who] >= 7) { // Won Tiebreaker
        addSet(who);
    } else if (set[who] >= 6 && set[who] > (set[getOther(who)] + 1)) {
        addSet(who);
    }
}
function addSet(who)
{
    match.push(set);
    set = [0,0];
    score[who]++;
}
// Play game
for(var i in input) {
    addPoint(parseInt(input[i]) - 1);
}
console.log(names[0], ' ', printScores(0));
console.log(names[1], ' ', printScores(1), printDeuce());
console.log(isDone() ? ((score[0] >= 3 ? names[0] : names[1]) + ' wins') : '');
```
]