ITMISS
试试这个,我引入了一个新的布尔变量this.winner作为 false 并在checkTie()函数中检查它。在gameOver()函数中,我将该变量设为 trueclass Stopwatch { constructor(display, results) { this.running = false; this.display = display; this.results = results; this.laps = []; this.winner = false; this.reset(); this.print(this.times); } reset() { this.times = [ 0, 0, 0 ]; } start() { if (!this.time) this.time = performance.now(); if (!this.running) { this.running = true; requestAnimationFrame(this.step.bind(this)); } } restart() { if (!this.time) this.time = performance.now(); if (!this.running) { this.running = true; requestAnimationFrame(this.step.bind(this)); } this.reset(); } step(timestamp) { if (!this.running) return; this.calculate(timestamp); this.time = timestamp; this.print(); requestAnimationFrame(this.step.bind(this)); } calculate(timestamp) { var diff = timestamp - this.time; // Hundredths of a second are 100 ms this.times[2] += diff / 10; // Seconds are 100 hundredths of a second if (this.times[2] >= 100) { this.times[1] += 1; this.times[2] -= 100; } // Minutes are 60 seconds if (this.times[1] >= 60) { this.times[0] += 1; this.times[1] -= 60; } } print() { this.display.innerText = this.format(this.times); } format(times) { return `\${pad0(times[0], 2)}:\${pad0(times[1], 2)}:\${pad0(Math.floor(times[2]), 2)}`; }}function pad0(value, count) { var result = value.toString(); for (; result.length < count; --count) result = '0' + result; return result;}function clearChildren(node) { while (node.lastChild) node.removeChild(node.lastChild);}let stopwatch = new Stopwatch( document.querySelector('.stopwatch'), document.querySelector('.results'));// @@@ TIC_TAC_TOE @@@@var board;const hplayer ="0"; //human playerconst aiplayer ="x"; //machine playerconst wincom = // DEACLARE WINING COMBINATIONS[ [0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [6,4,2],]//GET ALL INSIDE THE CELL CLASSconst cells = document.querySelectorAll('.cell');startGame();stopwatch.start();var mySound; //VARIABLE FOR SOUNDS function startGame(){ // AT THE GAME END DISPLAY NONE document.querySelector(".endgame").style.display = "none"; // CREATE ARRAYS FOR 9 BORD ELEMENTS board = Array.from(Array(9).keys()); //CLEAR BOARD AFTER WINNING for (var i = 0; i <cells.length; i++) { cells[i].innerText =''; // CLEAR CELLS cells[i].style.removeProperty('background-color'); //REMOVE WINING HIGHLIGHT COLOR FROM BOARD AND ASSIGN TO BACKGROUND COLOR cells[i].addEventListener('click', turnClick, false); // CALL CLICK mySound = new sound("bounce.mp3"); } }function turnClick(square){ // GENARATE TARGET CELL NUMBER USING HUMAN PLAYER CLICK EVENT //console.log(square.target.id, hplayer) if (typeof board[square.target.id] == 'number') {// DISABLE OTHER CELLS turn(square.target.id, hplayer) if (!checkTie()) turn(bestSpot(), aiplayer); } }function turn(squareId, player){ board[squareId] = player; // SHOW PLAYER AND SQUARE ID WHICH IS PLAYER CLICKED if(squareId) document.getElementById(squareId).innerText = player; let gameWon = checkWin(board, player) //GAME WON PLAYER AND BOARD CELLS if (gameWon) { this.winner = true; gameOver (gameWon) // IF GAME WON CALL GAMEOVER FUNCTION WITH GAMEWON VARIABLE }}function checkWin(board, player) { // TAKE ARRAY AND ADD THE INDEX TOO THE ARRAY, IDENTIFY EVERY INDEX OF PLAYER CLICKED //check all the spots on the board played (e = elements , i = array, a = qemulator) let plays = board.reduce((a, e, i) => (e===player) ? a.concat(i) : a, []); // SET GAME WON NULL DROW NO WINS let gameWon = null; //CHECK IF GAME HAS BEEN WON for(let[index, win] of wincom.entries()) //GET INDEX AND WIN { // CHECK IF THE PLAYER CLICK TO THE ANY WINING ELEMENTS IN WINING COMBINATION if (win.every(elem=>plays.indexOf(elem) >-1)) { // WIHICH PLAYER WON ? AND WINING INDEX ? gameWon = {index: index, player:player}; break; // BREAK FUNCTION } }return gameWon; //IF WON GAME WON RETURN OR NOT RETURN GAME WON NULL}function gameOver(gameWon){ for (let index of wincom[gameWon.index]) // INDEX OF WINNING COMBINATION WHICH PLAYER HAS CLICKED { document.getElementById(index).style.backgroundColor = gameWon.player == hplayer ? "red": "blue"; // IF THE PLAYER WHO WON HUMAN PLAYER INDEX OF WINING COMBINATIONS BECOME BLUE OR AI PLAYER INDEX BECOME RED } for (var i = 0; i < cells.length; i++) // check if available spots length is more than to 0 { cells[i].removeEventListener('click', turnClick, false); // DISABLE CELLS CLICKING AFTER WINING REMOVE CLICK } declareWinner(gameWon.player == hplayer ? "YOU WON!!" : "YOU LOSS!!"); stopwatch.running = false; stopwatch.time = null;}function declareWinner(who){ document.querySelector(".endgame").style.display = "block"; document.querySelector(".endgame .text").innerText = who;}function emptySquares(){ // fillter every element in the board to see if the type of the elemnts eqales to number return board.filter(s => typeof s == 'number'); //if type of is a number return the number}function bestSpot(){ return minimax(board, aiplayer).index; //RETURNS THE CALLING OF MINIMAX FUNCTION PASSING BOARD AND AI PLAYER AND GET INDEX OF COMPUTER PLAYING }function checkTie(){ if(emptySquares().length == 0 && !this.winner) // EVERY SQUARE FILLED UP *NO WINNER* { for (var i = 0; i < cells.length;i++) { cells[i].style.backgroundColor = "#1a0033"; // ALL CELLS GREEN cells[i].removeEventListener('click', turnClick,false); stopwatch.running = false; stopwatch.time = null; } declareWinner("Game Tie !! ") return true; } return false;}// minimax find a optimal move for player function minimax(newboard, player) // CREATE MINIMAX FUNCTION USING NEWBORD AND PLAYER ARGUMENT { var avaSpots = emptySquares(); // check available spots of the board (Empty squares) if (checkWin(newboard, player)) //if checking someone winning states { return{score: -10}; // if human player wins return -10 } else if (checkWin(newboard, aiplayer)) // if AI player wins return +10 { return{score: 10}; } else if (avaSpots.length === 0) // if no available spots(0), game tie, then return 0 { return {score: 0}; } var moves =[];//ARRAY MOVES to collect scores for(var i = 0; i < avaSpots.length; i++) // check array available spots length morethan to 0 { var move = {}; // create moves object to catch available spots move.index = newboard[avaSpots[i]]; //set the index number of the available spots to the move object property newboard[avaSpots[i]] = player; // set the available spots for the current player if (player == aiplayer) { var result = minimax(newboard, hplayer); //call minimax for human player move.score = result.score; } else { var result = minimax (newboard, aiplayer); move.score = result.score; } //minimax reset newboard and push the move object to moves array newboard[avaSpots[i]] = move.index; moves.push(move); mySound.play(); } // check the best move in the move arrray var bestMove; if(player === aiplayer)//should chose with the highst score when AI play { var bestScore = -10000; for(var i = 0; i < moves.length; i++) { if (moves[i].score > bestScore) //store highst score { bestScore = moves[i].score; bestMove = i; } } } else { var bestScore = 10000; for(var i = 0; i < moves.length; i++) { if(moves[i].score < bestScore) { bestScore = moves[i].score; // store lowest score bestMove = i; } } } return moves[bestMove]; //return object store inside the bestmove} function sound(src) { this.sound = document.createElement("audio"); this.sound.src = src; this.sound.setAttribute("preload", "auto"); this.sound.setAttribute("controls", "none"); this.sound.style.display = "none"; document.body.appendChild(this.sound); this.play = function(){ this.sound.play(); } this.stop = function(){ this.sound.pause(); } }body{ background-image: url(background.jpg);}table{ margin-top: 80px; background: transparent; box-shadow: 0px 0px 0px 0px #393d44;}td{ height: 130px; width: 120px; text-align: center; vertical-align: middle; font-family: "Bradley Hand ITC"; color: red; padding: 10px; font-size: 70px; cursor: pointer;}table tr:first-child{ box-shadow:0px 8px 5px -5px blue;}table tr:nth-child(2){ box-shadow:0px -8px 5px -5px blue , 0px 8px 5px -5px blue;}table tr:last-child{ box-shadow:0px -8px 5px -5px blue; }table tr td:first-child{ box-shadow:8px 0px 5px -5px blue; }table tr td:nth-child(2){ box-shadow:-8px 0px 5px -5px blue , 8px 0px 5px -5px blue;}table tr td:last-child{ box-shadow:-8px 0px 5px -5px blue; }.endgame{ display: none; width: 300px; top: 100px; background-color: rgba(70, 80, 120, 0.66); position: absolute; left: 645px; margin-left: -112px; margin-top: 10%; padding-bottom: 0px; padding-top: 20px; text-align: center; border-radius: 5px; color: #f9f1f1; font-background: #0C3F6F !important; font-size:45px; font-family: monospace;}.button { height:35px; background-color: #e0f1ed2e; color: white; border:none; border-radius: 10px; cursor: pointer; margin-bottom:20px; margin-top: 20px; font-size: 25px; transition: 0.3s; font-family: monospace; }.button:hover { opacity: 1; background-color: coral;}a { text-decoration-line: none; text-decoration: none; color: white;}.button_f{ height:35px; background-color: #e0f1ed2e; border:none; border-radius: 10px; cursor: pointer; margin-bottom:20px; margin-top: 0px; font-size: 20px; background: #0C3F6F !important; font-family: monospace; color:white !important;}html { color: #bbb; font-family: Menlo;}.stopwatch { font-size: 80px; text-align: center;}.results { border-color: lime; list-style: none; margin: 0; padding: 0; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);}<html> <title>Tic Tac Toe</title> <!--LINK CSS STYLESHEET--> <head> <link rel="stylesheet" href="tic_tac_toe.css"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> </head> <body><embed src="dChanyeol (EXO) & Punch - Stay With Me FMV (Goblin OST Part 1) (Eng Sub + Rom + Han).mp3" autostart="true" hidden="true" loop ="true"><!--BACKGROUND MUSI<audio id="myaudio"> <source src="music.mp3"></audio> JS FOR MUSIC VOLUME<script> var audio = document.getElementById("myaudio").loop=true; audio.volume = 0.2; </script>C--><div class="stopwatch"></div> <ul class="results"></ul> <!--CREATE BORD FOR TIC TAC TOE GAME--> <table align="center"> <tr> <td class="cell" id="0"></td> <td class="cell" id="1"></td> <td class="cell" id="2"></td> </tr> <tr> <td class="cell" id="3"></td> <td class="cell" id="4"></td> <td class="cell" id="5"></td> </tr> <tr> <td class="cell" id="6"></td> <td class="cell" id="7"></td> <td class="cell" id="8"></td> </tr> <!--MESSAGE CLASS FOR END GAME--> <div class="endgame"> <div class="text"></div> <!--BUTTON FOR REPLAY--> <button onclick="startGame(), stopwatch.restart();" class="button">Restart</button> <br> <!--<button onclick="location.reload();" class="button">Restart New Game</button>--> <button class="button_f"><a href="https://en-gb.facebook.com/">Share This on Facebook</a></button> </div> <!--END MESSAGE--> </table> <!--END GAME TABLE BOARD--> <!--LINK JAVASCRIPT--> <script src="tic_tac_toe.js"></script> </body></html>