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
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.