Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var cells = {}; // This object is used for recording all the values of buttons in the game
- // These functions help in the game
- function valueAssign(id, newValue) {document.getElementById(id).value = newValue} // assigns value to button/cell of tictactoe
- function valueGrabber(id) {return document.getElementById(id).value} // Grabs current value of cell/button
- function innerHTMLAssign(id, newValue){document.getElementById(id).innerHTML = newValue} //Used only to assign value to the <p> id= "winner"
- function innerHTMLGrabber(id){return document.getElementById(id).innerHTML} // I don't use it but made it just in case if it needed
- function resetCells(){
- cells.A1 = "";
- cells.A2 = "";
- cells.A3 = "";
- cells.B1 = "";
- cells.B2 = "";
- cells.B3 = "";
- cells.C1 = "";
- cells.C2 = "";
- cells.C3 = "";
- } // This functions reset the cells object ONLY and doesn't reset buttons of HTML
- function gameRestart(){
- innerHTMLAssign('playAgain',"") // play again asks for playing again its the restart game button from which gamer restarts game
- document.getElementById('playAgain').style.border = "0px solid black"
- document.getElementById('playAgain').disabled = true // I disable it becuase when game restarts it becomes invisible and then it shifts its positoin on top but it can be clicked so I disable it
- // For JS
- valueAssign('A1', "");
- valueAssign('A2', "");
- valueAssign('A3', "");
- valueAssign('B1', "");
- valueAssign('B2', "");
- valueAssign('B3', "");
- valueAssign('C1', "");
- valueAssign('C2', "");
- valueAssign('C3', "");
- innerHTMLAssign('winner', "");
- buttonLock(false) // buttonlocks is used to prevent player to change the button value if result is declared
- }// This function is used when player wants to restart the game it resets all fields
- function buttonLock(bool){
- document.getElementById('A1').disabled = bool
- document.getElementById('A2').disabled = bool
- document.getElementById('A3').disabled = bool
- document.getElementById('B1').disabled = bool
- document.getElementById('B2').disabled = bool
- document.getElementById('B3').disabled = bool
- document.getElementById('C1').disabled = bool
- document.getElementById('C2').disabled = bool
- document.getElementById('C3').disabled = bool
- } // The button lock function which can disable or enable cells/ buttons
- function afterGameOver(){
- resetCells(); // Will reset cells object
- innerHTMLAssign('playAgain',"↻") // will make playagain appear
- document.getElementById('playAgain').style.border = "1px solid black" // will make playagain appear
- document.getElementById('playAgain').disabled = false // unlock the diabled playagain button
- buttonLock(true) // this will lock all buttons so that player couldn't change the value of buttons after the winner is declarede
- }// This function is triggered by refree or the fucntions who declares winner of the game down is the refre function
- function refre(){
- /*The functions has some problems if you try to do some weird moves it'll fail to declare winner
- below are the if statements which are based on cells object for information
- they compare cells like if the X in A1 A2 A3 are all X i.e. a Diagonal is formed of X which means X is winner then function return
- result which'll be pasted on the <p> with id winner
- it also calls afterGameOver() which does all the work of locking buttons and showing restart game button with id playAgain
- Actually I use if statement cells.A2 == "X" which concludes that X is winner
- the if statement out has condiotoin "(cells.A1 == "X" && cells.A2 == "X" && cells.A3 == "X") || (cells.A1 == "O" && cells.A2 == "O" && cells.A3 == "O")"
- becuase of the this if ((cells.A1 == "X" && cells.A2 == "X" && cells.A3 == "X") || (cells.A1 == "O" && cells.A2 == "O" && cells.A3 == "O")) {
- statement refree knows somebody won but WHO X or O the decision is taken by nested if statment it also calls afterGameOver()
- so the nested if statement checks for who is winner by checking middle value of the 3 cells
- X== USER O == COM
- */
- if ((cells.A1 == "X" && cells.A2 == "X" && cells.A3 == "X") || (cells.A1 == "O" && cells.A2 == "O" && cells.A3 == "O")) {
- if (cells.A2 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.A2 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.B1 == "X" && cells.B2 == "X" && cells.B3 == "X") || (cells.B1 == "O" && cells.B2 == "O" && cells.B3 == "O")) {
- if (cells.B2 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.B2 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.C1 == "X" && cells.C2 == "X" && cells.C3 == "X") || (cells.C1 == "O" && cells.C2 == "O" && cells.C3 == "O")) {
- if (cells.C2 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.C2 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.A1 == "X" && cells.B1 == "X" && cells.C1 == "X") || (cells.A1 == "O" && cells.B1 == "O" && cells.C1 == "O")) {
- if (cells.B1 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.B1 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.A2 == "X" && cells.B2 == "X" && cells.C2 == "X") || (cells.A2 == "O" && cells.B2 == "O" && cells.C2 == "O")) {
- if (cells.B2 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.B2 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.A3 == "X" && cells.B3 == "X" && cells.C3 == "X") || (cells.A3 == "O" && cells.B3 == "O" && cells.C3 == "O")) {
- if (cells.B3 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.B3 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.A1 == "X" && cells.B2 == "X" && cells.C3 == "X") || (cells.A1 == "O" && cells.B2 == "O" && cells.C3 == "O")) {
- if (cells.B2 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.B2 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } if ((cells.C1 == "X" && cells.B2 == "X" && cells.A3 == "X") || (cells.C1 == "O" && cells.B2 == "O" && cells.A3 == "O")) {
- if (cells.B2 == "X") {
- afterGameOver();
- return "You Win!";
- } else if(cells.B2 == "O"){
- afterGameOver();
- return "You Lose!";
- }
- } else { // the statement below is not working properly, why, I don't know it just declares about Draw
- if (valueGrabber('A3') != "" && valueGrabber('A1') != "" && valueGrabber('A2') != "" && valueGrabber('B2') != "" && valueGrabber('B3') != "" && valueGrabber('B1') != "" && valueGrabber('C2') != "" && valueGrabber('C1') != "" && valueGrabber('C3') != "") {
- afterGameOver();
- return "Draw!";
- }
- }
- }// if u try to make weird moves refree will fail to make decision
- function markO(id){
- if (valueGrabber(id) == "") {
- valueAssign(id, "O")
- }
- } // In this game user plays first then the COM but COM is O user is X computer must know where to mark the O it must not overwrite some cell so if statment checks that cell is empty or not?
- function records(){
- cells.A1 = valueGrabber('A1');
- cells.A2 = valueGrabber('A2');
- cells.A3 = valueGrabber('A3');
- cells.B1 = valueGrabber('B1');
- cells.B2 = valueGrabber('B2');
- cells.B3 = valueGrabber('B3');
- cells.C1 = valueGrabber('C1');
- cells.C2 = valueGrabber('C2');
- cells.C3 = valueGrabber('C3');
- } // the function keeps record of all values in the object cells
- function ai_X(){
- /*
- This is brain which tells expected moves of USER to COM...
- It actually thinks for USER and tells COM where the user may mark his X in next move
- like if he marks XX in horizontal then he'll probably move XXX so that he can win
- At that time COM knows in next move USER will try to complete the line so
- COM will mark at the horizontal line like XXO so that USER will be blocked and will not win
- Ultra special and Super Special conditions are the conditions when USER doesn't play as expected
- One can make a shape of kite in the Square of Tictactoe by clicking on A2 B1 C2 and B3 too fool the COM if the Ultra speical condition is not there
- COM will not react in such cases and will grant USER to play and fill 4 buttons (A2 B1 C2 and B3) without playing his move
- Still COM is stupid and it couldn't understand other weird moves played by USER to fool it
- */
- // Ultra Super Special Condition
- if (cells.B2 == "X" && cells.C3 == "X") {
- if(valueGrabber("C1") == "") {
- return "C1"
- }
- }
- // Super Special Condition
- if (cells.A2 == "X" && cells.C2 == "X") {
- if(valueGrabber("B1") == "") {
- return "B1"
- }
- }
- // Special Conditions
- if (cells.B1 == "X" && cells.C2 == "X") {
- if(valueGrabber("A3") == "") {
- return "A3"
- }
- } if (cells.C2 == "X" && cells.B3 == "X") {
- if(valueGrabber("A1") == "") {
- return "A1"
- }
- } if (cells.B3 == "X" && cells.A2 == "X") {
- if(valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.A2 == "X" && cells.B1 == "X") {
- if(valueGrabber("C3") == "") {
- return "C3"
- }
- }
- // Diagonal /
- /*
- Till now you've got a good idea of what ai_X function does
- if USER had played two moves diagonally and now its turn of COM
- ai_X tells COM that the user may try to compelte his Diagonal with X
- with this hint COM marks his O to stop USER completing his diagonal, same with the horizontal and vertical lines
- */
- if (cells.A3 == "X" && cells.B2 == "X") {
- if(valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.C1 == "X" && cells.B2 == "X") {
- if(valueGrabber("A3") == "") {
- return "A3"
- }
- } if (cells.C1 == "X" && cells.A3 == "X") {
- if(valueGrabber("B2") == "") {
- return "B2"
- }
- }
- // Diagonal \
- if (cells.B2 == "X" && cells.C3 == "X") {
- if(valueGrabber("A1") == "") {
- return "A1"
- }
- } if (cells.A1 == "X" && cells.B2 == "X") {
- if(valueGrabber("C3") == "") {
- return "C3"
- }
- } if (cells.A1 == "X" && cells.C3 == "X") {
- if(valueGrabber("B2") == "") {
- return "B2"
- }
- }
- // Vertical Lines
- if (cells.A2 == "X" && cells.A3 == "X") {
- if(valueGrabber("A1") == "") {
- return "A1"
- }
- } if (cells.A1 == "X" && cells.A3 == "X") {
- if(valueGrabber("A2") == "") {
- return "A2"
- }
- } if (cells.A1 == "X" && cells.A2 == "X") {
- if(valueGrabber("A3") == "") {
- return "A3"
- }
- }
- if (cells.B2 == "X" && cells.B3 == "X") {
- if(valueGrabber("B1") == "") {
- return "B1"
- }
- } if (cells.B1 == "X" && cells.B2 == "X") {
- if(valueGrabber("B3") == "") {
- return "B3"
- }
- } if (cells.B1 == "X" && cells.B3 == "X") {
- if(valueGrabber("B2") == "") {
- return "B2"
- }
- }
- if (cells.C1 == "X" && cells.C2 == "X") {
- if(valueGrabber("C3") == "") {
- return "C3"
- }
- } if (cells.C2 == "X" && cells.C3 == "X") {
- if(valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.C1 == "X" && cells.C3 == "X") {
- if(valueGrabber("C2") == "") {
- return "C2"
- }
- }
- // Horizontal Lines
- if (cells.A1 == "X" && cells.C1 == "X") {
- if(valueGrabber("B1") == "") {
- return "B1"
- }
- } if (cells.A1 == "X" && cells.B1 == "X") {
- if(valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.B1 == "X" && cells.C1 == "X") {
- if(valueGrabber("A1") == "") {
- return "A1"
- }
- }
- if (cells.A2 == "X" && cells.C2 == "X") {
- if(valueGrabber("B2") == "") {
- return "B2"
- }
- } if (cells.B2 == "X" && cells.C2 == "X") {
- if(valueGrabber("A2") == "") {
- return "A2"
- }
- } if (cells.A2 == "X" && cells.B2 == "X") {
- if(valueGrabber("C2") == "") {
- return "C2"
- }
- }
- if (cells.B3 == "X" && cells.C3 == "X") {
- if(valueGrabber("A3") == "") {
- return "A3"
- }
- } if (cells.A3 == "X" && cells.C3 == "X") {
- if(valueGrabber("B3") == "") {
- return "B3"
- }
- } if (cells.A3 == "X" && cells.B3 == "X") {
- if(valueGrabber("C3") == "") {
- return "C3"
- }
- }
- }
- function ai_O(){
- /*
- This is function ai_O which helps COM to make decision
- You know COM just can't keep blocking USER and reult game intro a DRAW he must win so
- COM gets clues about the expected moves of USER through ai_X function which makes COM to block USER
- Similarly ai_O function helps COM to win by telling COM where to mark his O when he has successfully blocked USER
- Now USER has played a stupid move which yeilds nothing to him
- It's turn of COM and COM has already marked his two Os on a vertical line now he just want one O on the line to win in such cases
- ai_O function will tell COM to mark on the vertical line to make the COM winner
- Diagonal, Vertical and all the statements are similar to ai_X
- In a nutshell both ai_O and ai_X know, if 2 marks are near i.e. diagonally or vertically or horizontally
- predict the next i.e. 3rd move of USER or COM
- */
- // Diagonal /
- if (cells.A3 == "O" && cells.B2 == "O") {
- if (valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.C1 == "O" && cells.B2 == "O") {
- if (valueGrabber("A3") == "") {
- return "A3"
- }
- } if (cells.C1 == "O" && cells.A3 == "O") {
- if (valueGrabber("B2") == "") {
- return "B2"
- }
- }
- // Diagonal \
- if (cells.B2 == "O" && cells.C3 == "O") {
- if (valueGrabber("A1") == "") {
- return "A1"
- }
- } if (cells.A1 == "O" && cells.B2 == "O") {
- if (valueGrabber("C3") == "") {
- return "C3"
- }
- } if (cells.A1 == "O" && cells.C3 == "O") {
- if (valueGrabber("B2") == "") {
- return "B2"
- }
- }
- // Vertical Lines
- if (cells.A2 == "O" && cells.A3 == "O") {
- if (valueGrabber("A1") == "") {
- return "A1"
- }
- } if (cells.A1 == "O" && cells.A3 == "O") {
- if (valueGrabber("A2") == "") {
- return "A2"
- }
- } if (cells.A1 == "O" && cells.A2 == "O") {
- if (valueGrabber("A3") == "") {
- return "A3"
- }
- }
- if (cells.B2 == "O" && cells.B3 == "O") {
- if (valueGrabber("B1") == "") {
- return "B1"
- }
- } if (cells.B1 == "O" && cells.B2 == "O") {
- if (valueGrabber("B3") == "") {
- return "B3"
- }
- } if (cells.B1 == "O" && cells.B3 == "O") {
- if (valueGrabber("B2") == "") {
- return "B2"
- }
- }
- if (cells.C1 == "O" && cells.C2 == "O") {
- if (valueGrabber("C3") == "") {
- return "C3"
- }
- } if (cells.C2 == "O" && cells.C3 == "O") {
- if (valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.C1 == "O" && cells.C3 == "O") {
- if (valueGrabber("C2") == "") {
- return "C2"
- }
- }
- // Horizontal Lines
- if (cells.A1 == "O" && cells.C1 == "O") {
- if (valueGrabber("B1") == "") {
- return "B1"
- }
- } if (cells.A1 == "O" && cells.B1 == "O") {
- if (valueGrabber("C1") == "") {
- return "C1"
- }
- } if (cells.B1 == "O" && cells.C1 == "O") {
- if (valueGrabber("A1") == "") {
- return "A1"
- }
- }
- if (cells.A2 == "O" && cells.C2 == "O") {
- if (valueGrabber("B2") == "") {
- return "B2"
- }
- } if (cells.B2 == "O" && cells.C2 == "O") {
- if (valueGrabber("A2") == "") {
- return "A2"
- }
- } if (cells.A2 == "O" && cells.B2 == "O") {
- if (valueGrabber("C2") == "") {
- return "C2"
- }
- }
- if (cells.B3 == "O" && cells.C3 == "O") {
- if (valueGrabber("A3") == "") {
- return "A3"
- }
- } if (cells.A3 == "O" && cells.C3 == "O") {
- if (valueGrabber("B3") == "") {
- return "B3"
- }
- } if (cells.A3 == "O" && cells.B3 == "O") {
- if (valueGrabber("C3") == "") {
- return "C3"
- }
- }
- }
- function prior(){
- /*
- The function prior is really essential for game more than the ai_X and ai_O
- The prior actually does the move which can be the difference between Win and Lose
- if USER is about to win and has to mark one X to win
- And COM is also about to win he has to mark one O in the line to win
- at such time COM will confuse whom to listen ai_X is telling to block USER annd ai_O is telling to mark O and win
- at such cases winning is important so prior function helps COM to make a decision when he's confused about whom to listen?
- Till there are no 2 marks consecuently ai_X and ai_O don't work in such cases either game continues or COM doesn't play his move and lets
- USER to play more than one move at a time Which is bad
- */
- var aix = ai_X() // The value that function return is asigned to var aix
- var aio = ai_O() // The value that this function returns is assigned to var aio
- if (aio != undefined) {
- if (aio != undefined) { // Truly speaking I started this project after a month or two so I don't remember why I nested two if statements with same conditions let it be
- return aio // if aio is not equal to undefined which means it has something to tell COM, COM will listen to aio to win within one move
- }
- } else if (aio == undefined){ // aio is telling us nothing which means COM's NOT about win within one move at such time COM must block USER
- if (aix != undefined) { // aix is not equal to undefined i.e. it has something to tell COM, COM will listen to aix this time
- return aix // Now COM will listen to aix to block the USER
- }
- }
- }
- // Now not sure some code is excess I use it for Debugging to see where problem lies but now help me becuase I failed to put enough AI into it... :(
- function userClick(value, id){
- if (value == "") {
- valueAssign(id, "X")
- records() // It records move played by USER
- computerChoice(id) // COM will make choice on basis of records and id
- var winner = refre() // refre returns strings "you win " and "you lose" they are stored in var winner
- if (winner != undefined){// refre is executed several times but when it dectects nothing it returns undefined
- innerHTMLAssign('winner', winner) // when winner isn't equal to undefined it means somebody is winner then the string is assigned to <p> id = 'winner'
- }
- }
- }
- function computerChoice(id){
- do {
- if (id != "B2") {
- markO("B2") // Little bit code that makes sure that if USER clicks on any other button than B2 then It'll mark on B2 becuase its more strategic
- } else if (id == "B2") {
- markO("A1") // Unfortunately If USER clicks on central cell B2 then COM will mark on A1
- }
- }while(false) // It just executes on startup of game
- markO(prior())
- records() // Keeping tracks of things is must so record() records move played by markO(prior())
- };
Add Comment
Please, Sign In to add comment