I'm trying to build a basic tic tac toe game in angular 1. When I click on a square I want to either add X or O depending on the turn. I cannot figure out how to do that. I can do it in jquery but I want to do it in angular.
<div class="squares-container" ng-repeat="square in squares">
<div class="s" id="{{ $index + 1 }}" ng-click="move(square)", ng-bind="{{ $index + 1 }}"></div>
</div>
angular
.module('app')
.directive('ticTacToe', function(){
return {
restrict: 'E',
templateUrl: 'tic-tac-toe.html',
controller: controller
};
function controller($scope){
function init() {
let turn = 0;
let currentPiece = 'X';
$scope.squares = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$scope.move = function(id){
currentPiece = turn % 2 === 0 ? 'X' : 'O';
$scope.id = currentPiece;
turn++;
};
}
init();
}
})
Here's the code. https://plnkr.co/edit/UwHsltXVLFAVG6pHKKwO?p=preview
You can set your squares to objects and simply alter the properties of them.
When you click on a square, pass it to your move
function, find the index of it and change the piece
property of that square.
(function() {
'use strict';
angular.module('app', []);
})();
(function() {
'use strict';
angular.module('app').directive('ticTacToe', TicTacToeDirective);
function TicTacToeDirective() {
return {
restrict: 'E',
templateUrl: 'tic-tac-toe.html',
controller: TicTacToeController,
controllerAs: 'TicTacToeCtrl'
};
}
TicTacToeController.$inject = [];
function TicTacToeController() {
// reference this to make it available in the view using the controller as syntax
var vm = this;
// expose our move function to the view
vm.move = move;
// we can even expose our newGame function to start a new game
vm.newGame = newGame;
// set our defaults - we will add turn to this controller so we can display it in the view
vm.turn = 0;
var currentPiece = "X";
// start a new game
newGame();
function move(square) {
// get the index of the square passed in
var index = vm.squares.indexOf(square);
// set the squares piece property to the correct piece if it doesn't already have one set
if (!vm.squares[index].piece) {
vm.squares[index].piece = vm.turn % 2 === 0 ? 'X' : 'O';
// increment the number of turns
vm.turn++;
}
}
function newGame() {
// reset turn
vm.turn = 0;
// reset current piece
currentPiece = "X";
// setup our squares
vm.squares = [{
id: 1,
piece: null
}, {
id: 2,
piece: null
},
{
id: 3,
piece: null
},
{
id: 4,
piece: null
},
{
id: 5,
piece: null
},
{
id: 6,
piece: null
},
{
id: 7,
piece: null
}, {
id: 8,
piece: null
},
{
id: 9,
piece: null
}
];
}
}
})();
/* Styles go here */
.container {
background-color: #14bdac;
}
.s {
border: 1px solid #000;
width: 50px;
height: 50px;
float: left;
}
.divider {
display: block;
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<div ng-app="app">
<tic-tac-toe></tic-tac-toe>
<script type="text/ng-template" id="tic-tac-toe.html">
<button ng-click="TicTacToeCtrl.newGame()">New game</button> Turns taken: {{TicTacToeCtrl.turn}}
<hr>
<div class="squares-container" ng-repeat-start="square in TicTacToeCtrl.squares track by $index">
<div class="s" id="{{::square.id}}" ng-click="TicTacToeCtrl.move(square)">
{{::square.id}}
<span class="checked">{{square.piece}}</span>
</div>
</div>
<div ng-repeat-end class="divider" ng-if="!(square.id % 3)"></div>
</script>
</div>