I am building a tic tac toe game where one can play an AI. In the $scope.move function()
there is a while loop that grabs a random cell and makes it the value of the AI. Somehow this is not working. Here's the codepen link http://codepen.io/theMugician/pen/ojJrRp
我正在构建一个tac脚趾游戏,在那里你可以玩一个AI。在美元的范围。move函数()有一个while循环获取随机单元格并使其成为AI的值。不知何故,这行不通。这是codepen链接http://codepen.io/themugician/pen/ojrrp
var app = angular.module("ticTacToe", []);
app.controller("MainCtrl", function($scope){
var cell = $(".square");
$scope.player = "";
$scope.AI = "";
var cross = "×";
var circle = "◯";
/*** Choose a shape ***/
$scope.choosePlayer = function(e) {
$scope.player = $(e.currentTarget).text();
$('.choose').css('top', '-2000px');
$('#wrapper').css('top', '-600px');
$('#wrapper').css('opacity', '1');
if($scope.player === "×"){
$scope.AI = "◯";
}else if($scope.player === "◯"){
$scope.AI = "×";
}
}
/*** Shape Cells ***/
$scope.cells = [ { value: '' }, { value: '' }, { value: '' },
{ value: '' }, { value: '' }, { value: '' } ,
{ value: '' }, { value: '' }, { value: '' }
];
/*** Make a move ***/
$scope.move = function(cell){
cell.value = $scope.player;
var round = 0;
/*** AI makes a move ***/
while(round < 1){
var randomCell = $scope.cells[Math.floor((Math.random()*8)+1)];
if(randomCell.value === "" ){
randomCell.value = $scope.AI;
round = 1;
}else{
round = 0;
}
}
};
});
2 个解决方案
#1
2
I have changed your code a bit and added comments where I saw the problem
我已经稍微修改了您的代码,并在看到问题的地方添加了注释
var app = angular.module("ticTacToe", []);
app.controller("MainCtrl", function($scope){
var cell = $(".square");
$scope.player = "";
$scope.AI = "";
// changed special chars to X and O as the if statement failed.
var cross = "X";
var circle = "O";
/*** Choose a shape ***/
$scope.choosePlayer = function(e) {
$scope.player = $(e.currentTarget).text();
$('.choose').css('top', '-2000px');
$('#wrapper').css('top', '-600px');
$('#wrapper').css('opacity', '1');
//these if statements failed before (AI was always empty)
if($scope.player === cross){
$scope.AI = circle;
}else if($scope.player === circle){
$scope.AI = cross;
}
}
/*** Shape Cells ***/
$scope.cells = [ { value: '' }, { value: '' }, { value: '' },
{ value: '' }, { value: '' }, { value: '' } ,
{ value: '' }, { value: '' }, { value: '' }
];
// made a ref to scope cells
$scope.emptyCells = $scope.cells;
/*** Make a move ***/
$scope.move = function(cell){
cell.value = $scope.player;
var round = 0;
/*** AI makes a move ***/
while(round < 1){
// filtered to get only available cells (for performance)
$scope.emptyCells = $scope.cells.filter(function(cell){
return cell.value === '';
});
// got random cell according to empty cells
var randomCell = $scope.emptyCells[Math.floor((Math.random()*($scope.emptyCells.length-1))+1)];
if(randomCell.value === "" ){
randomCell.value = $scope.AI;
round = 1;
}else{
round = 0;
}
}
};
});
also needed to change in HTML:
还需要更改HTML:
<button ng-click="choosePlayer($event)" class="btn btn-red" id="choose-cross">X</button>
<button ng-click="choosePlayer($event)" class="btn btn-green" id="choose-circle">O</button>
#2
1
You are using the wrong unicode character for crosses based on your HTML. Change it to ✖ and it will work.
基于HTML,您使用了错误的unicode字符。将其更改为✖工作。
Avoid the use of "magic values". Simply assign cross
and circle
to the correct values once, and then refer to cross and circle everywhere else in your code. This will help to prevent future errors of this kind since the values will have one point of reference and can be easily changed rather than digging through your code and changing all the incorrect string literals.
避免使用“魔法值”。只需将cross和circle分配给正确的值一次,然后在代码中的其他地方引用cross和circle。这将有助于防止将来出现此类错误,因为这些值将具有一个引用点,并且可以很容易地进行更改,而不是在代码中挖掘和更改所有不正确的字符串文字。
Ideally, the best practice would be have everything based on one central point of reference. So either your HTML should refer to the variables in your JS or your JS should refer to the text node in your HTML. This is a software development principle known as DRY or Dont Repeat Yourself, and basically it means that the only repetitions in your code should be references to other code. A string literal should not be repeated. Instead repeat a reference to that string literal.
理想情况下,最佳实践应该是,所有内容都基于一个中心参考点。因此,HTML应该引用JS中的变量,或者JS应该引用HTML中的文本节点。这是一种软件开发原则,称为DRY或don ' t Repeat Yourself,基本上它意味着代码中惟一的重复应该是对其他代码的引用。字符串文字不应该重复。相反,重复对字符串文字的引用。
Demo: http://codepen.io/anon/pen/GpbaLz
演示:http://codepen.io/anon/pen/GpbaLz
Updated JS:
JS:更新
var app = angular.module("ticTacToe", []);
app.controller("MainCtrl", function($scope){
var cell = $(".square");
$scope.player = "";
$scope.AI = "";
// *** fixed unicode char
var cross = "✖";
var circle = "◯";
/*** Choose a shape ***/
$scope.choosePlayer = function(e) {
$scope.player = $(e.currentTarget).text();
$('.choose').css('top', '-2000px');
$('#wrapper').css('top', '-600px');
$('#wrapper').css('opacity', '1');
// *** use correct unicode chars above
if($scope.player === cross){
$scope.AI = circle;
}else if($scope.player === circle){
$scope.AI = cross;
}
}
/*** Shape Cells ***/
$scope.cells = [ { value: '' }, { value: '' }, { value: '' },
{ value: '' }, { value: '' }, { value: '' } ,
{ value: '' }, { value: '' }, { value: '' }
];
/*** Make a move ***/
$scope.move = function(cell){
cell.value = $scope.player;
var round = 0;
/*** AI makes a move ***/
while(round < 1){
// *** random select fix
var randomCell = $scope.cells[Math.floor((Math.random()*9))];
if(randomCell.value === "" ){
randomCell.value = $scope.AI;
round = 1;
}else{
round = 0;
}
}
};
});
#1
2
I have changed your code a bit and added comments where I saw the problem
我已经稍微修改了您的代码,并在看到问题的地方添加了注释
var app = angular.module("ticTacToe", []);
app.controller("MainCtrl", function($scope){
var cell = $(".square");
$scope.player = "";
$scope.AI = "";
// changed special chars to X and O as the if statement failed.
var cross = "X";
var circle = "O";
/*** Choose a shape ***/
$scope.choosePlayer = function(e) {
$scope.player = $(e.currentTarget).text();
$('.choose').css('top', '-2000px');
$('#wrapper').css('top', '-600px');
$('#wrapper').css('opacity', '1');
//these if statements failed before (AI was always empty)
if($scope.player === cross){
$scope.AI = circle;
}else if($scope.player === circle){
$scope.AI = cross;
}
}
/*** Shape Cells ***/
$scope.cells = [ { value: '' }, { value: '' }, { value: '' },
{ value: '' }, { value: '' }, { value: '' } ,
{ value: '' }, { value: '' }, { value: '' }
];
// made a ref to scope cells
$scope.emptyCells = $scope.cells;
/*** Make a move ***/
$scope.move = function(cell){
cell.value = $scope.player;
var round = 0;
/*** AI makes a move ***/
while(round < 1){
// filtered to get only available cells (for performance)
$scope.emptyCells = $scope.cells.filter(function(cell){
return cell.value === '';
});
// got random cell according to empty cells
var randomCell = $scope.emptyCells[Math.floor((Math.random()*($scope.emptyCells.length-1))+1)];
if(randomCell.value === "" ){
randomCell.value = $scope.AI;
round = 1;
}else{
round = 0;
}
}
};
});
also needed to change in HTML:
还需要更改HTML:
<button ng-click="choosePlayer($event)" class="btn btn-red" id="choose-cross">X</button>
<button ng-click="choosePlayer($event)" class="btn btn-green" id="choose-circle">O</button>
#2
1
You are using the wrong unicode character for crosses based on your HTML. Change it to ✖ and it will work.
基于HTML,您使用了错误的unicode字符。将其更改为✖工作。
Avoid the use of "magic values". Simply assign cross
and circle
to the correct values once, and then refer to cross and circle everywhere else in your code. This will help to prevent future errors of this kind since the values will have one point of reference and can be easily changed rather than digging through your code and changing all the incorrect string literals.
避免使用“魔法值”。只需将cross和circle分配给正确的值一次,然后在代码中的其他地方引用cross和circle。这将有助于防止将来出现此类错误,因为这些值将具有一个引用点,并且可以很容易地进行更改,而不是在代码中挖掘和更改所有不正确的字符串文字。
Ideally, the best practice would be have everything based on one central point of reference. So either your HTML should refer to the variables in your JS or your JS should refer to the text node in your HTML. This is a software development principle known as DRY or Dont Repeat Yourself, and basically it means that the only repetitions in your code should be references to other code. A string literal should not be repeated. Instead repeat a reference to that string literal.
理想情况下,最佳实践应该是,所有内容都基于一个中心参考点。因此,HTML应该引用JS中的变量,或者JS应该引用HTML中的文本节点。这是一种软件开发原则,称为DRY或don ' t Repeat Yourself,基本上它意味着代码中惟一的重复应该是对其他代码的引用。字符串文字不应该重复。相反,重复对字符串文字的引用。
Demo: http://codepen.io/anon/pen/GpbaLz
演示:http://codepen.io/anon/pen/GpbaLz
Updated JS:
JS:更新
var app = angular.module("ticTacToe", []);
app.controller("MainCtrl", function($scope){
var cell = $(".square");
$scope.player = "";
$scope.AI = "";
// *** fixed unicode char
var cross = "✖";
var circle = "◯";
/*** Choose a shape ***/
$scope.choosePlayer = function(e) {
$scope.player = $(e.currentTarget).text();
$('.choose').css('top', '-2000px');
$('#wrapper').css('top', '-600px');
$('#wrapper').css('opacity', '1');
// *** use correct unicode chars above
if($scope.player === cross){
$scope.AI = circle;
}else if($scope.player === circle){
$scope.AI = cross;
}
}
/*** Shape Cells ***/
$scope.cells = [ { value: '' }, { value: '' }, { value: '' },
{ value: '' }, { value: '' }, { value: '' } ,
{ value: '' }, { value: '' }, { value: '' }
];
/*** Make a move ***/
$scope.move = function(cell){
cell.value = $scope.player;
var round = 0;
/*** AI makes a move ***/
while(round < 1){
// *** random select fix
var randomCell = $scope.cells[Math.floor((Math.random()*9))];
if(randomCell.value === "" ){
randomCell.value = $scope.AI;
round = 1;
}else{
round = 0;
}
}
};
});