| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns:ng="http://angularjs.org">
  <head>
    <script type="text/javascript"
         src="../src/angular-bootstrap.js#autobind"></script>
  </head>
  <body ng:init="$window.$root = this">
<script>
function TicTacToeCntl(){
  this.cellStyle= {
    'height': '20px',
    'width': '20px',
    'border': '1px solid black',
    'text-align': 'center',
    'vertical-align': 'middle',
    'cursor': 'pointer'
  };
  this.reset();
  this.$watch('$location.hashPath', this.setMemento);
  this.$onEval(function(){
    this.$location.hashPath = this.getMemento();
  });
}
TicTacToeCntl.prototype = {
  dropPiece: function(row, col) {
    if (!this.winner && !this.board[row][col]) {
      this.board[row][col] = this.nextMove;
      this.nextMove = this.nextMove == 'X' ? 'O' : 'X';
      this.grade();
    }
  },
  reset: function(){
    this.board = [
      ['', '', ''],
      ['', '', ''],
      ['', '', '']
    ];
    this.nextMove = 'X';
    this.winner = '';
  },
  grade: function(){
   var b = this.board;
   this.winner =
    row(0) || row(1) || row(2) ||
    col(0) || col(1) || col(2) ||
    diagonal(-1) || diagonal(1);
   function row(r) { return same(b[r][0], b[r][1], b[r][2]);}
   function col(c) { return same(b[0][c], b[1][c], b[2][c]);}
   function diagonal(i) { return same(b[0][1-i], b[1][1], b[2][1+i]);}
   function same(a, b, c) { return (a==b && b==c) ? a : '';};
  },
  getMemento: function(){
    var rows = [];
    angular.foreach(this.board, function(row){
      rows.push(row.join(','));
    });
    return rows.join(';') + '/' + this.nextMove;
  },
  setMemento: function(value) {
    if (value) {
      value = value.split('/');
      this.nextMove = value[1];
      angular.foreach(value[0].split(';'), function(row, i){
        this.board[i] = row.split(',');
      }, this);
    } else {
      this.reset();
    }
  }
};
</script>
<h3>Tic-Tac-Toe</h3>
Next Player: {{nextMove}}
<div ng:show="winner">Player {{winner}} has won!</div>
<table ng:controller="TicTacToeCntl">
  <tr ng:repeat="row in board" style="height:15px;">
    <td ng:repeat="cell in row" ng:style="cellStyle"
            ng:click="dropPiece($parent.$index, $index)">{{cell}}</td>
  </tr>
</table>
<button ng:click="reset()">reset board</button>
  </body>
</html>
 |