Upgrade to Pro — share decks privately, control downloads, hide ads and more …

State & Monsters

State & Monsters

What's Big Ball of Mud?
How to write a stateless Tic Tac Toe game (in Haskell)
Benefits of good state management.

nbartlomiej

June 12, 2012
Tweet

More Decks by nbartlomiej

Other Decks in Programming

Transcript

  1. 1 var months = { 2 '2012': [ 'jan', 'feb',

    'mar', 'apr', 3 'may', 'jun', 'jul', 'aug', 4 'sep', 'oct', 'nov', 'dec' ], 5 6 '2011': [ 'jan', 'feb', 'mar', 'apr', 7 'may', 'jun', 'jul', 'aug', 8 'sep', 'oct', 'nov', 'dec' ], 9 10 '2010': [ 'jan', 'feb', 'mar', 'apr', 11 'may', 'jun', 'jul', 'aug', 12 'sep', 'oct', 'nov', 'dec' ], 13 14 '2009': [ 'jan', 'feb', 'mar', 'apr', 15 'may', 'jun', 'jul', 'aug', 16 'sep', 'oct', 'nov', 'dec' ] 17 18 // (...)
  2. 1 $(document).ready( function(){ 2 3 4 5 6 7 8

    9 10 11 12 13 14 15 16 17 18 19 });
  3. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 8 9 10 11 12 13 14 15 16 17 18 19 });
  4. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 12 13 14 15 16 17 18 19 });
  5. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 12 13 $('.board-element').click(function(){ 14 15 16 17 18 }); 19 });
  6. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 12 13 $('.board-element').click(function(){ 14 var x = $(this).attr('data-x'); 15 var y = $(this).attr('data-y'); 16 17 18 }); 19 });
  7. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 12 13 $('.board-element').click(function(){ 14 var x = $(this).attr('data-x'); 15 var y = $(this).attr('data-y'); 16 placeMark(x,y, 17 18 }); 19 });
  8. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 var currentMark = 'X'; 12 13 $('.board-element').click(function(){ 14 var x = $(this).attr('data-x'); 15 var y = $(this).attr('data-y'); 16 placeMark(x,y, 17 18 }); 19 });
  9. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 var currentMark = 'X'; 12 13 $('.board-element').click(function(){ 14 var x = $(this).attr('data-x'); 15 var y = $(this).attr('data-y'); 16 placeMark(x,y,currentMark); 17 18 }); 19 });
  10. 1 $(document).ready( function(){ 2 3 var board = [ ['_','_','_'],

    4 ['_','_','_'], 5 ['_','_','_'] ]; 6 7 var placeMark = function(x,y,mark){ 8 board[x][y] = mark; 9 } 10 11 var currentMark = 'X'; 12 13 $('.board-element').click(function(){ 14 var x = $(this).attr('data-x'); 15 var y = $(this).attr('data-y'); 16 placeMark(x,y,currentMark); 17 swapCurrentMark(); 18 }); 19 });
  11. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 5

    var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 10 }); 11 12 13 14 15 16 17 18 19 20
  12. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 5

    var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 10 }); 11 12 13 14 $('#resign').click(function(){ 15 16 17 18 19 20 });
  13. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 5

    var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 10 }); 11 12 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 18 19 20 });
  14. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 5

    var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 18 19 20 });
  15. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 5

    var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  16. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  17. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  18. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  19. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  20. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  21. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  22. 1 var currentMark = 'X'; 2 3 $('.board-element').click(function(){ 4 if

    (!winner){ 5 var x = $(this).attr('data-x'); 6 var y = $(this).attr('data-y'); 7 placeMark(x,y,currentMark); 8 swapCurrentMark(); 9 } 10 }); 11 12 var winner = null; 13 14 $('#resign').click(function(){ 15 if (currentMark = 'X'){ 16 winner = 'O'; 17 } else { 18 winner = 'X'; 19 } 20 });
  23. “A large fraction of the flaws in software development are

    due to programmers not fully understanding all the possible states their code may execute in.” John Carmack, “Functional programming in C++”, 2012
  24. 1 var board = [ ['_','_','_'], 2 ['_','_','_'], 3 ['_','_','_']

    ]; 4 5 var currentMark = 'X'; 6 7 var winner = null; 8 9 var turn = 0; 10 11 //...
  25. 1 var board = [ ['_','_','_'], 2 ['_','_','_'], 3 ['_','_','_']

    ]; 4 5 var currentMark = 'X'; 6 7 var winner = null; 8 9 var turn = 0; 10 11 //...
  26. 1 var board = [ ['_','_','_'], 2 ['_','_','_'], 3 ['_','_','_']

    ]; 4 5 var currentMark = 'X'; 6 7 var winner = null; 8 9 var turn = 0; 10 11 //...
  27. 1 var board = [ ['_','_','_'], 2 ['_','_','_'], 3 ['_','_','_']

    ]; 4 5 var currentMark = 'X'; 6 7 var winner = null; 8 9 var turn = 0; 10 11 //...
  28. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  29. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  30. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  31. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 15 16 17 18 19 20 21 22 23 24 25
  32. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 17 18 19 20 21 22 23 24 25
  33. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 17 18 19 20 21 22 winner board 23 24 25
  34. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 17 18 19 20 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 25
  35. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 17 18 19 20 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  36. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 17 18 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  37. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  38. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  39. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  40. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  41. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  42. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  43. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  44. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  45. 4 board = [[Nothing, Nothing, Nothing], 5 [Nothing, Nothing, Nothing],

    6 [Nothing, Nothing, Nothing]] 7 8 replace index element list = 9 (take index list) ++ [element] ++ (drop (index+1) list) 10 11 replace' x y element matrix = 12 replace x (replace y element (matrix !! x)) matrix 13 14 data Mark = O | X deriving (Eq) 15 16 diagonals [[a,_,b], 17 [_,c,_], 18 [d,_,e]] = [[a,c,e],[b,c,d]] 19 20 patterns board = board ++ (transpose board) ++ (diagonals board) 21 22 winner board 23 | any (== [Just O, Just O, Just O]) (patterns board) = Just O 24 | any (== [Just X, Just X, Just X]) (patterns board) = Just X 25 | otherwise = Nothing
  46. 1 2 // var winner = null; 3 4 Board.prototype.winner

    = function(){ 5 if ( this.winnerX() ) { 6 return 'X'; 7 } else if ( this.winnerO() } { 8 return 'O'; 9 } else { 10 return null; 11 } 12 }
  47. 1 // var currentMark = 'X'; 2 3 Board.prototype.place =

    function(x,y,mark){ 4 this.board[x][y] = mark; 5 } 6
  48. 1 // $('.board-element').click(function(){ 2 // if (!winner){ 3 // var

    x = $(this).attr('data-x'); 4 // var y = $(this).attr('data-y'); 5 // placeMark(x,y,currentMark); 6 // swapCurrentMark(); 7 // } 8 // }); 9 10 11 12 13 14 15 16 17 18 19
  49. 1 // $('.board-element').click(function(){ 2 // if (!winner){ 3 // var

    x = $(this).attr('data-x'); 4 // var y = $(this).attr('data-y'); 5 // placeMark(x,y,currentMark); 6 // swapCurrentMark(); 7 // } 8 // }); 9 10 $('*[data-board-element]').click(function(){ 11 board.moveIntent( 12 $(this).attr('data-x'), 13 $(this).attr('data-y') 14 ); 15 } 16 17 18 19
  50. 1 // $('.board-element').click(function(){ 2 // if (!winner){ 3 // var

    x = $(this).attr('data-x'); 4 // var y = $(this).attr('data-y'); 5 // placeMark(x,y,currentMark); 6 // swapCurrentMark(); 7 // } 8 // }); 9 10 $('*[data-board-element]').click(function(){ 11 board.moveIntent( 12 $(this).attr('data-x'), 13 $(this).attr('data-y') 14 ); 15 } 16 17 $('*[data-board-element]').click(function(){ 18 new BoardInput(this); 19 }