Implement a reversi engine Your job, for this golf, is to write a program that will take moves of a game of reversi (othello) and display the result to the user.
Input
A string of numbers taken from the range [0-7]. Each pair of numbers represent first the X coordinate, then the Y coordinate. Any characters not in that range should be ignored.
Output
A visual representation of the result of the game, including who is leading when the input ends. This may be graphical or keystroke output, but it must be a visual grid of the game, with a distinct character/graphical symbol for black, white, and empty.
Additionally, your code should output an error message and stop when an illegal move is entered (the same square more than once, or a square that will not flip any tiles).
Skips should be handled gracefully. A skip occurs when one color has no legal move, their turn is skipped and the other player gets to play.
Black always goes first.
Examples
23
........
........
........
..bbb...
...bw...
........
........
........
b

232425140504032627
........
........
........
b.bbb...
bbbww...
b.b.....
..b.....
..b.....
b

2324322513
........
........
........
..bbb...
..www...
........
........
........
e

23242555
........
........
........
..bbb...
..bbw...
..b.....
........
........
e
Haskell - 1493 bytes

In this version, there are no detailed error messages and the output is much more basic. The major change was replacing Either String a with Maybe a and since they are both monads, this was acheived by simply swapping Right a with Just a and Left String with Nothing.

{-# LANGUAGE OverloadedStrings #-}
import Prelude hiding ((&gt;&gt;=),concatMap,filter,foldl,head,last,map,null,replicate)
import Control.Applicative hiding (empty)
import Control.Monad hiding (replicateM)
import Data.Vector hiding ((++),concat,foldM,reverse,zip)
main=getLine&gt;&gt;= \s-&gt;h$t&lt;$&gt;(zip$cycle[w,v])&lt;$&gt;b s&gt;&gt;= \m-&gt;u(\b(c,x)-&gt;case d b x c of r@(Just _)-&gt;r;Nothing-&gt;if not$null$findIndices(\y-&gt;e$d b y c)$t[(x,y)|x&lt;-[0..7],y&lt;-[0..7]];then é;else d b x$not c)k$n m
 where b(x:y:s)=(:)(read [x],read [y])&lt;$&gt;b s;b(_:_)=é;b[]=è[];d b z c=let d=join$m(f b z c)$m(\v-&gt;(head v,last v))$replicateM 2$t[-1,0,1];in if null d;then Nothing;else u(\b (x,y)-&gt;case b!?y of Just r-&gt;(case r!?x of Just _-&gt;è$b//[(y,r//[(x,è c)])];Nothing-&gt;é);Nothing-&gt;é)b$n$d`snoc`z;e(Nothing)=w;e(Just _)=v;f b(x,y)c z@(u,v)=let r=x+u;s=y+v;t=(r,s);in (case g b t of Just(Just d)-&gt;if d==c;then l;else (case g b (r+u,s+v) of Just(Just _)-&gt;t`cons`f b t c z;_-&gt;l);Just(Nothing)-&gt;l;Nothing-&gt;l);g b(x,y)=(case b!?y of Just col-&gt;col!?x;Nothing-&gt;é);h(Just b)=p$(o$n$m(\r-&gt;o(n$m(\c-&gt;case c of Just False-&gt;"B";Just True-&gt;"W";Nothing-&gt;".")r)++"\n")b)++i(q(\(w,b)(rw,rb)-&gt;(w+rw,b+rb))(0,0)$m(\r-&gt;q(\s@(w,b)c-&gt;case c of Just True-&gt;(w+1,b);Just False-&gt;(w,b+1);_-&gt;s)(0,0)r)b);h Nothing=p"e";i(w,b)|w&gt;b="W"++s w|b&gt;w="B"++s b|v="N"++s(w+b);j=r 8 é;k=r 8 j//[(3,j//[(3,è v),(4,è w)]),(4,j//[(3,è w),(4,è v)])];l=empty;m=map;n=toList;o=concat;p=putStrLn;q=foldl;r=replicate;s=show;t=fromList;u=foldM;v=True;w=False;é=Nothing;è=Just




$ printf "232425140504032627" | ./nano-rve 
........
........
........
B.BBB...
BBBWW...
B.B.....
..B.....
..B.....
B11


Original version - 4533 bytes

I will golf when there will be competition!
edit It has arrived

{-# LANGUAGE OverloadedStrings #-}
import Prelude hiding ((&gt;&gt;=),concatMap,filter,foldl,map,null,replicate)
import Control.Applicative hiding (empty)
import Control.Monad
import Data.Either
import Data.Vector hiding ((++),concat,foldM,reverse,zip)

type Case = Maybe Bool
type Board = Vector (Vector Case)
type Coord = (Int,Int)

-- fmap (toList) $ replicateM 2 [-1,0,1] -- minus (0,0)
directions :: Vector Coord
directions = fromList [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]

--  [(x,y) | x &lt;- [0..7], y &lt;- [0..7]]
allCoords :: Vector Coord
allCoords = fromList [(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(3,7),(4,0),(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(5,0),(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(6,0),(6,1),(6,2),(6,3),(6,4),(6,5),(6,6),(6,7),(7,0),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(7,7)]


initBoard :: Board
initBoard = vs // [(3,v1),(4,v2)]
    where va = replicate 8 Nothing
          v1 = va // [(3,Just True),(4,Just False)]
          v2 = va // [(3,Just False),(4,Just True)]
          vs = replicate 8 va

showBoard :: Board -&gt; String
showBoard b = (concat $ toList $ map (showRow) b) ++ (showScore b)
    where showCase :: Case -&gt; String
          showCase c = case c of 
              Just False -&gt; "░B"
              Just True -&gt; "▓W"
              Nothing -&gt; "██"
          showRow :: Vector Case -&gt; String
          showRow r = concat (toList $ map (showCase) r) ++ "\n"

showScore :: Board -&gt; String
showScore b = winner score ++ "\n"
    where scoreCase :: (Int,Int) -&gt; (Maybe Bool) -&gt; (Int,Int)
          scoreCase (w,b) (Just True) = (w+1,b)
          scoreCase (w,b) (Just False) = (w,b+1)
          scoreCase s _ = s
          scoreRow :: Vector Case -&gt; (Int,Int)
          scoreRow r = foldl (scoreCase) (0,0) r
          score :: (Int,Int)
          score = foldl (\(w,b) (rw,rb) -&gt; (w+rw,b+rb)) (0,0) $ map (scoreRow) b
          winner :: (Int,Int) -&gt; String
          winner (w,b) | w &gt; b = "White with " ++ show w ++ " against Black with " ++ show b ++ "."
                       | b &gt; w = "Black with " ++ show b ++ " against White with " ++ show w ++ "."
                       | otherwise = "Nobody with " ++ show (w+b) ++ "."

printBoard :: Board -&gt; IO ()
printBoard b = putStrLn $ showBoard b
pm :: Either String Board -&gt; IO ()
pm (Right b) = printBoard b
pm (Left s)  = putStrLn s

lookupBoard :: Board -&gt; Coord -&gt; Either String Case
lookupBoard b (x,y) = case b !? y of
    Just col -&gt; case col !? x of
        Just c -&gt; Right c
        Nothing -&gt; Left "x is out of bounds"
    Nothing -&gt; Left "y is out of bounds"

updateBoard :: Board -&gt; Coord -&gt; Bool -&gt; Either String Board
updateBoard b (x,y) c = case b !? y of
    Just r -&gt; case r !? x of
        Just _ -&gt; Right $ b // [(y,r // [(x,Just c)])] 
        Nothing -&gt; Left "x is out of bounds"
    Nothing -&gt; Left "y is out of bounds"

makePath :: Board -&gt; Coord -&gt; Bool -&gt; Coord -&gt; Vector Coord
makePath b (x,y) c (px,py) = case lookupBoard b (nx,ny) of
        Right (Just pc) -&gt; if pc == c
            then empty
            else case lookupBoard b (nx+px,ny+py) of
                Right (Just _) -&gt; (nx,ny) `cons` makePath b (nx,ny) c (px,py)
                _ -&gt; empty
        Right (Nothing) -&gt; empty
        Left _ -&gt; empty
    where nx = x+px
          ny = y+py

makeMove :: Board -&gt; Coord -&gt; Bool -&gt; Either String Board
makeMove b xy@(x,y) c = if null cases 
        then Left $ "impossible move " ++ show xy ++ "."
        else foldM (\ob (cx,cy) -&gt; updateBoard ob (cx,cy) c) b $ toList $ cases `snoc` (x,y)
    where cases = join $ map (makePath b (x,y) c) directions

makeMoves :: Board -&gt; Vector (Bool,Coord) -&gt; Either String Board
makeMoves b ms = foldM (\ob (c,xy) -&gt; case makeMove ob xy c of
    rb@(Right _) -&gt; rb
    Left _ -&gt; if not $ null $ findIndices (\xy -&gt; isRight $ makeMove ob xy c) allCoords
        then Left $ "wrong move " ++ show xy ++ "."
        else makeMove ob xy (not c)) b $ toList ms


movesFromString :: String -&gt; Either String (Vector (Bool,Coord))
movesFromString cs = fromList &lt;$&gt; (zip $ cycle [False,True]) &lt;$&gt; coords cs
    where coords (x:y:cs) = (:) (read [x],read [y]) &lt;$&gt; coords cs
          coords (_:cs) = Left "invalid coordinates string"
          coords [] = Right []

isRight :: Either a b -&gt; Bool
isRight (Left _) = False
isRight (Right _) = True

main=getLine&gt;&gt;= \s-&gt;pm$movesFromString s&gt;&gt;=makeMoves initBoard


Note : Your second example should be 232425140504032627.

Tests

With screenshots to prevent eye burns.

$ printf "232425140504032627" | ./rve




$ printf "2324" | ./rve




$ printf "1" | ./rve
invalid coordinates string




$ printf "24" | ./rve
wrong move (2,4).


Is is possible to get impossible move (x,y) when you use innardics (functions from the innards of the program and that you should not use) and x/y is out of bounds.