code-golfreversi

Code Golf: Reversi


OK, here's a rather elaborate code golf challenge: Implement a game of Reversi (Othello).

Do this in as few characters as possible.

A session should look something like this:

 abcdefgh
1        
2        
3        
4   wb   
5   bw   
6        
7        
8        
b>d3
 abcdefgh
1        
2        
3   b    
4   bb   
5   bw   
6        
7        
8        

Solution

  • Perl, 408 char

    This is Perl, now down to 408 characters. Could chop another 25 characters with a more minimal approach to declaring the winner (like saying "B" instead of "Winner: Black\n"). First two newlines are significant; the others are included for readability.

    sub O{2&$B[$q+=$_]*$%}sub A{grep{$q=$=;$"=''while&O;$B[$q]*O$q=$=}$B[$=]?():@d}
    sub F{$B[$q]=$%;O&&&F}sub D{print'
     ',a..h,$/,(map{($e="@B[$_*9+1..$_*9+8]
    ")=~y/012/ bw/;$_,$e}1..8),@_}
    @d=map{$_,-$_}1,8..10;@B=(@z=(0)x40,$%=2,1,(0)x7,1,2,@z);
    for$!(%!){$%^=3;for$=(9..80){$=%9*A&&do{{D$%-2?b:w,"> ";
    $_=<>;$==(/./g)[1]*9-96+ord;A||redo}F$q=$=for A;last}}}
    $X+=/1/-/2/for@B;D"Winner: ",$X<0?White:$X?Black:None,$/
    

    @B holds the game board. $B[$i*9+$j] refers to row $i (1..8) and column $j (1..8)

    @d is the list of 8 valid directions

    O is a convenience method. It increments $q by $_ (the current direction) and returns non-zero if the piece at $B[$q] belongs to the current player's opponent

    F handles flipping pieces in the current direction $_

    A checks if the current player can make a legal move at $B[$=] and returns the set of directions that pieces can be flipped in

    D(@_) draws the board and prints @_

    The main loop toggles $% (the current player) and iterates through the positions on the board to find a legal move for that player. If any legal move is found, read a move from standard input (repeating until a valid move is entered) and update the board.