Some problems in IE11 - javascript

The problem is that I have created a dynamic navigation...
You click on a a-tag which has a function that displays some buttons.
I have assigned the function to the a-tag with an addEventListener.
It works in all the browsers, but IE...
When I click the tag, buttons are not becoming visible. And no error appears.
P.S.: I'm spanish btw, I'm sorry about my english :3
/* Javascript */
window.onload = function() {
var boton_menu = document.getElementById("boton_menu");
/* Compatibilidad con navegadores web */
if(boton_menu.addEventListener){
boton_menu.addEventListener("click", menu_usuario, false);
} else {
if(boton_menu.attachEvent){
boton_menu.attachEvent("onclick", menu_usuario);
}
}
}
/* Despliega el menú del usuario*/
function menu_usuario() {
var boton_menu = document.getElementById("boton_menu");
var perfil = document.getElementById("perfil");
var ajustes = document.getElementById("ajustes");
var desconectar = document.getElementById("desconectar");
if(boton_menu.className == ""){
boton_menu.className = "active";
perfil.className = "active";
ajustes.className = "active";
desconectar.className = "active";
} else {
boton_menu.className = "";
perfil.className = "";
ajustes.className = "";
desconectar.className = "";
}
}

This works in IE:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="">
<meta charset="utf-8">
<meta name="author" content="Antonio Bueno">
<title>Button Problems</title>
<style>
a {background-color: red; color: #FFF; padding: 10px;}
a.active {background-color: blue;}
</style>
<script>
window.onload = function(){
var some_button = document.getElementById("some_button");
if(some_button.addEventListener){
some_button.addEventListener("click", DisplayButton, false);
} else {
if(some_button.attachEvent){
some_button.attachEvent("onclick", DisplayButton);
}
}
}
function DisplayButton(){
var some_button = document.getElementById("some_button");
var another_button = document.getElementById("another_button");
if(some_button.className == ""){
some_button.className = "active";
another_button.style.display = "none";
} else {
some_button.className = "";
another_button.style.display = "inline-block";
}
}
</script>
</head>
<body>
<a id="some_button" class="">Click on me</a>
<input id="another_button" type="submit" value="example" />
</body>
</html>

Related

Cannot delete buttons using js

I can't delete two <button> tags using javascript. When you enter the wrong pin, I want the buttons to delete themselves but somehow it's not working.
var radar = document.getElementsByTagName("button");
var pin = 3778;
var pin_request = prompt("Podaj pin")
if (pin_request == pin) {
document.write("Podany pin: " + pin_request);
alert("Podano właściwy pin.");
} else {
document.write("odmowa dostępu.");
radar.parentNode.removeChild(radar);
}
<html>
<head>
<meta charset="UTF-8">
<style>
html {
text-align: center;
padding: 7em;
display: block;
}
button {
margin: 1cm;
}
</style>
</head>
<body><br>
<button>dodaj pieniądze</button>
<button>zainwestuj w nieruchomości</button>
<script src="do visual studio code.js"></script>
</body>
</html>
Also sorry for half-English code.
You can use querySelectorAll to get elements and in loop remove them.
var radar = document.querySelectorAll("button");
var pin = 3778;
var pin_request = prompt("Podaj pin")
if (pin_request == pin)
{
document.write("Podany pin: "+pin_request);
alert("Podano właściwy pin.");
}
else {
document.write("odmowa dostępu.");
radar.forEach(el=>{
el.remove();
})
}
<html>
<head>
<meta charset="UTF-8">
<style>
html{text-align:center; padding:7em; display:block;}
button{
margin:1cm;
}
</style>
</head>
<body><br>
<button>dodaj pieniądze</button>
<button>zainwestuj w nieruchomości</button>
<script src="do visual studio code.js"></script>
</body>
getElementyByTagName() returns an array of elements, but removeChild() only takes one element as an argument. If you use a loop it should work:
var parent = radar[0].parentNode
for(var i = 0; i < radar.length; i++) {
parent.removeChild(radar[i])
}
<!DOCTYPE HTML5>
<html>
<head>
<meta charset="UTF-8">
<style>
html{text-align:center; padding:7em; display:block;}
button{
margin:1cm;
}
</style>
</head>
<body><br>
<button>dodaj pieniądze</button>
<button>zainwestuj w nieruchomości</button>
<script>
var radar = document.querySelectorAll("button");
var pin = 3778;
var pin_request = prompt("Podaj pin")
if (pin_request == pin)
{
document.write("Podany pin: "+pin_request);
alert("Podano właściwy pin.");
}
else {
document.write("odmowa dostępu.");
radar.forEach(ele =>{
ele.remove();
})
}
</script>
</body>
</html>
This should work
var radar = document.getElementsByTagName("button");
var pin = 3778;
var pin_request = prompt("Podaj pin")
if (pin_request == pin)
{
document.write("Podany pin: "+pin_request);
alert("Podano właściwy pin.");
}
else {
document.write("odmowa dostępu.");
var elem = document.getElementById('btn1');
elem.parentNode.removeChild(elem);
var elem2 = document.getElementById('btn2');
elem2.parentNode.removeChild(elem2);
}
<button id = 'btn1'>dodaj pieniądze</button>
<button id = 'btn2'>zainwestuj w nieruchomości</button>

textarea undo & redo button using only plain JavaScript

I understand that Chrome has built in CTRL Z and Y for Undo and Redo function. But is it possible for the Undo/Redo button to work on textarea using plain JavaScript?
I found the code here (answered by Neil) helpful but it needs jQuery:
How do I make undo/redo in <textarea> to react on 1 word at a time, word by word or character by character?
Here is a StateMaker I made. It is used for undo, redo, and save. It's quite simple. It works fine.
The issue is that e.ctrlKey && e.key === 'z' and the like have strange behavior, when e.preventDefault() in Firefox, so I removed that part. The code below is admittedly imperfect, in that it writes over the last state if the words and states are the same length. But, if I didn't do that, it would have saved a state with every character, which is also doable. Another solution would be to save states based on time. I did not go that route for this example.
//<![CDATA[
/* external.js */
/* StateMaker created by Jason Raymond Buckley */
var doc, bod, I, StateMaker; // for use on other loads
addEventListener('load', function(){
doc = document; bod = doc.body;
I = function(id){
return doc.getElementById(id);
}
StateMaker = function(initialState){
var o = initialState;
if(o){
this.initialState = o; this.states = [o];
}
else{
this.states = [];
}
this.savedStates = []; this.canUndo = this.canRedo = false; this.undoneStates = [];
this.addState = function(state){
this.states.push(state); this.undoneStates = []; this.canUndo = true; this.canRedo = false;
return this;
}
this.undo = function(){
var sl = this.states.length;
if(this.initialState){
if(sl > 1){
this.undoneStates.push(this.states.pop()); this.canRedo = true;
if(this.states.length < 2){
this.canUndo = false;
}
}
else{
this.canUndo = false;
}
}
else if(sl > 0){
this.undoneStates.push(this.states.pop()); this.canRedo = true;
}
else{
this.canUndo = false;
}
return this;
}
this.redo = function(){
if(this.undoneStates.length > 0){
this.states.push(this.undoneStates.pop()); this.canUndo = true;
if(this.undoneStates.length < 1){
this.canRedo = false;
}
}
else{
this.canRedo = false;
}
return this;
}
this.save = function(){
this.savedStates = this.states.slice();
return this;
}
this.isSavedState = function(){ // test to see if current state in use is a saved state
if(JSON.stringify(this.states) !== JSON.stringify(this.savedStates)){
return false;
}
return true;
}
}
var text = I('text'), val, wordCount = 0, words = 0, stateMaker = new StateMaker, save = I('save');
text.onkeyup = function(e){
save.className = undefined; val = this.value.trim(); wordCount = val.split(/\s+/).length;
if(wordCount === words && stateMaker.states.length){
stateMaker.states[stateMaker.states.length-1] = val;
}
else{
stateMaker.addState(val); words = wordCount;
}
}
I('undo').onclick = function(){
stateMaker.undo(); val = text.value = (stateMaker.states[stateMaker.states.length-1] || '').trim();
text.focus();
save.className = stateMaker.isSavedState() ? 'saved' : undefined;
}
I('redo').onclick = function(){
stateMaker.redo(); val = text.value = (stateMaker.states[stateMaker.states.length-1] || '').trim();
text.focus();
save.className = stateMaker.isSavedState() ? 'saved' : undefined;
}
save.onclick = function(){
stateMaker.save(); text.focus(); this.className = 'saved';
}
}); // end load
//]]>
/* external.css */
*{
padding:0; margin:0; border:0; box-sizing:border-box;
}
html,body{
width:100%; height:100%; background:#aaa; color:#000;
}
input{
font:22px Tahoma, Geneva, sans-serif; padding:3px;
}
#text{
width:calc(100% - 20px); height:calc(100% - 70px); font:22px Tahoma, Geneva, sans-serif; padding:3px 5px; margin:10px;
}
#undoRedoSave{
text-align:right;
}
input[type=button]{
padding:0 7px; border-radius:5px; margin-right:10px; border:2px solid #ccc;
}
input[type=button].saved{
border:2px solid #700;
}
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1' />
<title>Test Template</title>
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<textarea id='text'></textarea>
<div id='undoRedoSave'>
<input id='undo' type='button' value='undo' />
<input id='redo' type='button' value='redo' />
<input id='save' type='button' value='save' />
</div>
</body>
</html>

Auto-Play feature not executing in JS

I have somewhat of a baseball game, obviously there are not bases or hits. Its all stikes, balls and outs. The buttons work and the functionality of the inning (top and bottom as well as count) are working. I want this to ideally randomly throw a pitch on its own every few seconds. Basically to randomly "click" the ball or strike button. I am trying to use the setTimeout function with no success. Any help?
HTML:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="bullpen.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Bullpen</title>
</head>
</html>
<body>
<button id=buttons onclick="playBall()">Auto-Play</button>
<h2>Inning: <span id=inningHalf></span> <span id=inningNum></span></h2>
<div id=buttons>
<button onclick="throwBall(), newInning()">Ball</button>
<button onclick="throwStrike(), newInning()">Strike</button>
</div>
<h2>Count: <span id=ball>0</span> - <span id=strike>0</span></h2>
<h2>Outs: <span id=out>0</span></h2>
<h2>----------------</h2>
<h2>Walks: <span id=walks>0</span></h2>
<h2>Strikeouts: <span id=strikeout>0</span></h2>
<script src="bullpen.js"></script>
</body>
</html>
JS:
var ball = 0;
var strike = 0;
var out = 0;
var walks = 0;
var strikeout = 0;
//---------------------------------
var outPerInning = 0;
var inning = 1;
//---------------------------------
document.getElementById('inningNum').innerHTML = inning;
document.getElementById('inningHalf').innerHTML = '▲';
function throwBall(){
ball++;
document.getElementById('ball').innerHTML = ball;
if (ball == 4){
ball = 0;
strike = 0;
walks++;
document.getElementById('walks').innerHTML = walks;
document.getElementById('strike').innerHTML = 0;
document.getElementById('ball').innerHTML = 0;
}
};
function throwStrike(){
strike++;
document.getElementById('strike').innerHTML = strike;
if(strike == 3){
ball = 0;
strike = 0;
strikeout++;
out++;
outPerInning++;
document.getElementById('strikeout').innerHTML = strikeout;
document.getElementById('out').innerHTML = out;
document.getElementById('strike').innerHTML = 0;
document.getElementById('ball').innerHTML = 0;
}
};
function newInning(){
if(out == 3){
ball=0;
strike=0;
out=0;
document.getElementById('strike').innerHTML = 0;
document.getElementById('ball').innerHTML = 0;
document.getElementById('out').innerHTML = 0;
}
if(outPerInning == 3){
document.getElementById('inningHalf').innerHTML = '▼';
}
if(outPerInning == 6){
inning++;
document.getElementById('inningHalf').innerHTML = '▲';
outPerInning = 0;
document.getElementById('inningNum').innerHTML = inning;
}
};
function playBall(){
var play = Math.random;
if(play >= 0.4){
throwStrike();
newInning();
}
else{
throwBall();
newInning();
}
setTimeout(playBall, 5000);
};
CSS if needed:
h2{
margin-left: 50px;
font-size: 50px;
}
button{
font-size: 45px;
}
#buttons{
width: 227px;
margin-left:50px;
margin-top: 20px;
}
Perhaps this is the problem:
function playBall(){
var play = math.random;
if(play >= 0.4){
throwStrike;
newInning();
}
else{
throwBall;
newInning();
}
setTimeout(playBall, 5000);
};
Should be
function playBall(){
var play = Math.random();
if(play >= 0.4){
throwStrike(); //call the function
newInning();
}
else{
throwBall(); //call the function
newInning();
}
setTimeout(playBall, 5000);
};
You were not calling these functions!
Here is a working fiddle: https://jsfiddle.net/av6vsp7g/

Why IIFE can fix "cannot set property 'onclick' of null"

I have a block of code as the following
<body id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
</script>
</body>
This line theLeftSide.lastChild.onclickwill throw an error, saying that "cannot set property 'onclick' of null", because at the time javascript engine scans through it, it hasn't has any child yet. This problem can be solved by putting this code inside $(document).ready, I know.
However, I also tried IIFE, which means that wrapping all those code inside
(function(){
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
})()
and also see that the problem is fixed, but cannot figure out why. Any one can explain me ?
Here's the full original code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>part4</title>
<style>
div{
position:absolute;
}
#left_side{
width:500px; height: 500px; border-right:#000 thin inset;
float: left;
}
#right_side{
width:500px; height: 500px;
float:left; left:500px;
}
img{
position: absolute;
}
body{
margin:0px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
</head>
<body onload="generateFace()" id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
var e = event;
var theBody= document.getElementById("main");
var post_left =0;
var post_top=0;
var quan = 4;
function generateFace(){
var i =0;
for(i=0; i<= quan; i++){
var img = document.createElement("img");
img.src="smile.png"; post_top=getRandom(); post_left=getRandom();
img.style.top = post_top + "px";
img.style.left = post_left +"px";
theRightSide.appendChild(img);
var clone = img.cloneNode(true);
theLeftSide.appendChild(clone);
}
//var clone = theRightSide.cloneNode(true);
//theLeftSide.appendChild(clone);
var extra = document.createElement("img");
extra.src="smile.png"; post_top=getRandom(); post_left=getRandom();
extra.style.top = post_top + "px";
extra.style.left = post_left +"px";
theLeftSide.appendChild(extra);
};
function getRandom(){
var i = Math.random() * 400 +1;
return Math.floor(i);
};
function dele(){
while(theLeftSide.firstChild != null){
theLeftSide.removeChild(theLeftSide.firstChild);
}
while(theRightSide.firstChild != null){
theRightSide.removeChild(theRightSide.firstChild);
}
};
theBody.onclick = function gameOver() {
alert("Game Over!");
dele();
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
function nextLevel(event){
event.stopPropagation();
quan+=5;
delse();
generateFace();
}
</script>
</body>
</html>
and with IIFE:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>part4</title>
<style>
div{
position:absolute;
}
#left_side{
width:500px; height: 500px; border-right:#000 thin inset;
float: left;
}
#right_side{
width:500px; height: 500px;
float:left; left:500px;
}
img{
position: absolute;
}
body{
margin:0px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
</head>
<body id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
(function(){
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
var e = event;
var theBody= document.getElementById("main");
var post_left =0;
var post_top=0;
var quan = 4;
generateFace();
function generateFace(){
var i =0;
for(i=0; i<= quan; i++){
var img = document.createElement("img");
img.src="smile.png"; post_top=getRandom(); post_left=getRandom();
img.style.top = post_top + "px";
img.style.left = post_left +"px";
theRightSide.appendChild(img);
var clone = img.cloneNode(true);
theLeftSide.appendChild(clone);
}
//var clone = theRightSide.cloneNode(true);
//theLeftSide.appendChild(clone);
var extra = document.createElement("img");
extra.src="smile.png"; post_top=getRandom(); post_left=getRandom();
extra.style.top = post_top + "px";
extra.style.left = post_left +"px";
theLeftSide.appendChild(extra);
};
function getRandom(){
var i = Math.random() * 400 +1;
return Math.floor(i);
};
function dele(){
while(theLeftSide.firstChild != null){
theLeftSide.removeChild(theLeftSide.firstChild);
}
while(theRightSide.firstChild != null){
theRightSide.removeChild(theRightSide.firstChild);
}
};
theBody.onclick = function gameOver() {
alert("Game Over!");
dele();
//theBody.onclick = undefined;
//theLeftSide.lastChild.onclick = undefined;
};
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
})();
</script>
</body>
</html>
In the original piece of code, generateFace() is called on page load. In the second piece of code, generateFace() is called directly. There is no relation with the IIFE. Please forget it! :-P Here is a simplified version of what you are doing in each case (open your browser console before running the snippets):
Original code (throws a TypeError)
console.log('attempting to initialize onclick');
document.getElementById('clickable').onclick = function () {
alert(this.id);
};
console.log('onclick initialized successfully');
function gendiv () {
console.log('gendiv was called');
document.body.innerHTML = '<div id="clickable">click me</div>';
}
<body onload="gendiv()"></body>
Modified code
gendiv();
console.log('trying to initialize onclick');
document.getElementById('clickable').onclick = function () {
alert(this.id);
};
console.log('onclick initialized successfully');
function gendiv () {
console.log('gendiv was called');
document.body.innerHTML = '<div id="clickable">click me</div>';
}
<body></body>

Bug with minimax/computer move selection (TicTacToe/Javascript)?

I'm trying to implement a single player tic tac toe game in which the computer player never loses (forces a draw or wins every time). After searching around it seems using the minimax strategy is pretty standard for this, yet I can't seem to get my algorithm to work correctly, which causes the computer to pick a really bad move. Can anyone help me find where my code has gone wrong?
'O' is the user (max) and 'X' is the computer (min)
EDIT: I re-posted my code, I've fixed some things within getComputerNextMove and a few minor bugs...now my code is finding better scores, but it doesn't always pick up if someone wins (the functions seem to be alright, I think I'm just not checking in the right spots). It also isn't picking the best move. There are some tester functions at the bottom to look at how minimax works/to test game states (winners/draw).
tictactoe.js:
// Setup
var user = new Player('user', 'O', 'green');
var computer = new Player('computer', 'X', 'pink');
window.players = [user, computer];
var gameBoard = new GameBoard();
gameBoard.initializeBoard();
// Trackers for the board and moves
var wins = ['012', '345', '678', '036', '147', '258', '048', '246'];
var moves = 1;
var currentPlayer = players[0];
var game = true;
function Player(name, selector, color) {
this.name = name;
this.moves = [];
this.selector = selector;
this.color = color;
this.makeMove = function(boxId){
if(!gameBoard.isGameOver() && gameBoard.isValidMove(boxId)){
markBox(this, boxId);
this.updateMoves(boxId);
gameBoard.updateBoard(this.selector, boxId);
setTimeout(function () { nextTurn() }, 75);
}
else{
if(gameBoard.isXWinner())
endGame("Computer");
else if(gameBoard.isOWinner())
endGame("You");
else
endGame();
}
}
this.updateMoves = function(boxId){
moves = moves + 1;
this.moves.push(boxId);
}
}
function Square(mark){
this.mark = mark;
this.position;
this.id;
this.score = 0; //for minimax algorithm
}
function GameBoard(){
this.state = [9];
this.initializeBoard = function(){
for(var space = 0; space < 9; space++){
var square = new Square("-");
this.state[space] = square;
this.state[space].position = space;
this.state[space].id = space;
this.state[space].score = 0;
}
}
this.getAvailableSpaces = function(){
var availableSpaces = [];
for(var space = 0; space < this.state.length; space++){
if(this.state[space].mark === "-")
availableSpaces.push(this.state[space]);
}
return availableSpaces;
}
this.updateBoard = function(selector, position){
this.state[position].mark = selector;
}
this.getPositionOfMarks = function(){
var positionOfMarks = [];
for(var sqr=0; sqr<this.state.length; sqr++){
var positionOfMark = {
'position' : this.state[sqr].position,
'mark' : this.state[sqr].mark
}
positionOfMarks.push(positionOfMark);
}
return positionOfMarks;
}
this.getXMovesAsString = function(){
var positionOfMarks = this.getPositionOfMarks();
var xMoves = "";
for(var pm=0; pm < positionOfMarks.length; pm++){
if(positionOfMarks[pm].mark === "X"){
var m = parseInt(positionOfMarks[pm].position);
xMoves += m;
}
}
return xMoves;
}
this.getOMovesAsString = function(){
var positionOfMarks = this.getPositionOfMarks();
var oMoves = "";
for(var pm=0; pm < positionOfMarks.length; pm++){
if(positionOfMarks[pm].mark === "O"){
var m = parseInt(positionOfMarks[pm].position);
oMoves += m;
}
}
return oMoves;
}
this.isValidMove = function(boxId){
return this.state[boxId].mark === "-"
}
this.isOWinner = function(){
var winner = false;
var oMoves = this.getOMovesAsString();
for(var win=0; win<wins.length; win++){
if(oMoves.search(wins[win]) >= 0)
winner = true
}
return winner;
}
this.isXWinner = function(){
var winner = false;
var xMoves = this.getXMovesAsString();
for(var win=0; win<wins.length; win++){
if(xMoves.search(wins[win]) >= 0)
winner = true;
}
return winner;
}
this.isDraw = function(){
var draw = true;
if(!this.isOWinner() && !this.isXWinner()){
for(var space=0; space < this.state.length; space++){
if(this.state[space].mark === "-"){
draw = false;
}
}
}
return draw;
}
this.isGameOver = function(){
var gameOver = false;
if(gameBoard.isDraw() ||
gameBoard.isOWinner() ||
gameBoard.isXWinner())
gameOver = true;
return gameOver;
}
this.printBoardToConsole = function(){
var row1 = [];
var row2 = [];
var row3 = [];
for(var space=0; space<this.state.length; space++){
if(space < 3)
row1.push((this.state[space].mark));
else if(space >= 3 && space < 6)
row2.push((this.state[space].mark));
else
row3.push((this.state[space].mark));
}
console.log(row1);
console.log(row2);
console.log(row3);
}
GameBoard.prototype.clone = function(){
var clone = new GameBoard();
clone.initializeBoard();
for(var square=0; square < this.state.length; square++){
clone.state[square].mark = this.state[square].mark;
clone.state[square].position = this.state[square].position;
clone.state[square].id = this.state[square].id;
clone.state[square].score = this.state[square].score;
}
return clone;
}
}
// Handle clicks
$(".box").click(function (event) {
if (getCurrentPlayer() === user && game == true){
user.makeMove(event.target.id);
}
else overlay("Wait your turn!");
});
// *** MOVES ***
// With every move, these functions update the state of the board
function getComputerNextMove(board){
var availableSquares = board.getAvailableSpaces();
var prevScore = -100000;
var bestMove;
for(var square = 0; square < availableSquares.length; square++){
var gameBoardChild = board.clone();
gameBoardChild.updateBoard("X", availableSquares[square].position);
console.log("gameBoardChild: " + gameBoardChild.printBoardToConsole());
console.log("===================");
var currentScore = min(gameBoardChild);
console.log("Child Score: " + currentScore);
if(currentScore > prevScore){
prevScore = currentScore;
bestMove = availableSquares[square].position;
console.log("Best Move: " + bestMove);
}
}
console.log("====================================");
return bestMove;
}
function max(board){
if(board.isOWinner()) return 1;
else if(board.isXWinner()) return -1;
else if(board.isDraw()) return 0;
var availableSquares = board.getAvailableSpaces();
var bestScore = -100000;
for(var square=0; square<availableSquares.length; square++){
var gameBoardChild = board.clone();
gameBoardChild.updateBoard("O", availableSquares[square].position);
var move = min(gameBoardChild);
if(move > bestScore)
bestScore = move;
}
return bestScore;
}
function min(board){
if(board.isOWinner()) return 1;
else if(board.isXWinner()) return -1;
else if(board.isDraw()) return 0;
var availableSquares = board.getAvailableSpaces();
var bestScore = 100000;
for(var square=0; square<availableSquares.length; square++){
var gameBoardChild = board.clone();
gameBoardChild.updateBoard("X", availableSquares[square].position);
var move = max(gameBoardChild);
if(move < bestScore)
bestScore = move;
}
return bestScore;
}
function markBox(player, boxId) {
$("#" + boxId).text(player.selector).addClass(player.color);
}
// *** SETTERS & GETTERS
function getCurrentPlayer() {
return currentPlayer;
}
function setCurrentPlayer(player) {
currentPlayer = player;
return currentPlayer;
}
function nextTurn() {
if(!gameBoard.isGameOver()){
if (getCurrentPlayer() === user) {
setCurrentPlayer(computer);
computer.makeMove(getComputerNextMove(gameBoard));
}
else setCurrentPlayer(user);
}
else{
if(gameBoard.isOWinner())
endGame("You");
else if(gameBoard.isXWinner())
endGame("Computer");
else
endGame();
}
}
function endGame(winner) {
game = false;
if (winner) {
overlay(winner.name + " wins!");
} else overlay("It's a draw!");
}
//Toggles info box (to avoid using alerts)
function overlay(message) {
$("#info").text(message);
$el = $("#overlay");
$el.toggle();
}
function buildTestBoard(test){
var board = new GameBoard();
board.initializeBoard();
if(test === "minimax"){
board.updateBoard("O", 0);
board.updateBoard("O", 2);
board.updateBoard("O", 4);
board.updateBoard("O", 8);
board.updateBoard("X", 1);
board.updateBoard("X", 6);
board.updateBoard("X", 7);
}
else if(test === "xwin"){
board.updateBoard("X", 6);
board.updateBoard("X", 4);
board.updateBoard("X", 2);
}
board.printBoardToConsole();
return board;
}
function testMinimax(){
var board = buildTestBoard("minimax");
var move = getComputerNextMove(board);
console.log("Best move: " + move);
}
function testWinner(){
var board = buildTestBoard("xwin");
return board.isXWinner();
}
index.html:
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/vendor/modernizr-2.6.2.min.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an <strong>outdated</strong> browser. Please
upgrade your browser or
activate Google Chrome Frame
to improve your experience.
</p>
<![endif]-->
<h2 id="title">Single Player Tic Tac Toe</h2>
<div id='0' class='box'></div>
<div id='1' class='box'></div>
<div id='2' class='box'></div>
<br />
<div id='3' class='box'></div>
<div id='4' class='box'></div>
<div id='5' class='box'></div>
<br />
<div id='6' class='box'></div>
<div id='7' class='box'></div>
<div id='8' class='box'></div>
<div id="overlay">
<div>
<p id="info"></p>
</div>
</div>
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
<script>
var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src='//www.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
</body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<script src="js/game/tictactoe.js"></script>
</html>
css:
.box {
width:100px;
height:100px;
display:inline-block;
background:#eee;
margin:3px 1px;
text-align:center;
font-size:24px;
font-family:arial;
vertical-align:bottom;
line-height:450%
}
.box:hover {
cursor: pointer;
}
a {
text-decoration:none;
}
.label {
position:relative;
bottom:0;
right:0
}
.green {
background:#90EE90;
}
.pink {
background:#FDCBBB;
}
.credit {
color:#333;
font-family:arial;
font-size:13px;
margin-top:40px;
}
#overlay {
position: absolute;
left: 300px;
top: 0px;
width:20%;
height:20%;
text-align:center;
z-index: 1000;
}
#overlay div {
width:100px;
margin: 100px auto;
background-color: #fff;
border:1px solid #000;
padding:15px;
text-align:center;
align: right;
}

Categories

Resources