好的,所以我一次用Python制作了一个非常简单的Tic-Tac-Toe游戏,而且非常有趣,所以我想我会对其进行调味,并在HTML / JS / CSS中进行制作再漂亮一点一切都很好,但是当为游戏制作简单的“ AI”时,我遇到了一些困难。这款游戏的简易AI应该是完全随机的,但是,有时它会占据一个已经占据的正方形,有时甚至根本不会移动,所以我知道这可能很简单,我就是不知道我认为它可能在此代码块中的某处,但我不知道:
function computerEasyModeMove(){
if(player == 'x'){
computer = 'o';
}
if(player == 'o'){
computer = 'x';
}
var computerMove = Math.floor(Math.random() * 9) + 1;
while(computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 3 && (topRightBox.innerHTML == 'o' || topRightBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 4 && (middleLeftBox.innerHTML == 'o' || middleLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 5 && (middleMiddleBox.innerHTML == 'o' || middleMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 6 && (middleRightBox.innerHTML == 'o' || middleRightBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 7 && (bottomLeftBox.innerHTML == 'o' || bottomLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 8 && (bottomMiddleBox.innerHTML == 'o' || bottomMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 9 && (bottomRightBox.innerHTML == 'o' || bottomRightBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
if(computerMove == 1){
topLeftBox.innerHTML = computer;
topLeftBox.style.pointerEvents = 'none';
}
if(computerMove == 2){
topMiddleBox.innerHTML = computer;
topMiddleBox.style.pointerEvents = 'none';
}
if(computerMove == 3){
topRightBox.innerHTML = computer;
topRightBox.style.pointerEvents = 'none';
}
if(computerMove == 4){
middleLeftBox.innerHTML = computer;
middleLeftBox.style.pointerEvents = 'none';
}
if(computerMove == 5){
middleMiddleBox.innerHTML = computer;
middleMiddleBox.style.pointerEvents = 'none';
}
if(computerMove == 6){
middleRightBox.innerHTML = computer;
middleRightBox.style.pointerEvents = 'none';
}
if(computerMove == 7){
bottomLeftBox.innerHTML = computer;
bottomLeftBox.style.pointerEvents = 'none';
}
if(computerMove == 8){
bottomMiddleBox.innerHTML = computer;
bottomMiddleBox.style.pointerEvents = 'none';
}
if(computerMove == 9){
bottomRightBox.innerHTML = computer;
bottomRightBox.style.pointerEvents = 'none';
}
}
基本上,这是我用于简易AI的代码,下面是完整代码。我认为我的游戏看起来不错。如果您想尝试一下,我一直在repl.it(https://repl.it/@AnthonyRobinso2/Tic-Tac-Toe-HTMLJS)上进行,如果这样可以更轻松地为我提供帮助。我仍在开发游戏,以及更困难的AI模式,因此我仍然需要完成这些工作,但是我想拥有一个可玩的游戏,即使它真的很简单。再次感谢!
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<center>
<div id='setup'>
Hey! Welcome to my Tic-Tac-Toe game! Please choose some settings below!
<br>
<div class='xOrO'>
<h3>Player:</h3>
Do you want to be X's?<input type='checkbox' id='Xs' value='X' onchange='player = "x"'>
Or do you want to be O's?<input type='checkbox' id='Os' value='O' onchange='player = "o"'>
<h3>Opponent AI Level:</h3>
Easy<input type='checkbox' id='easy' value='easyMode'>
Medium (Coming Soon)<input type='checkbox' id='medium' value='mediumMode'>
Hard (Coming Soon)<input type='checkbox' id='hard' value='hardMode'>
<br>
<h4>Do you want to go first, or have the computer go first?</h4>
First<input type='checkbox' id='goFirst' value='first' onchange='playerFirst = true'>
  Second<input type='checkbox' id='goSecond' value='second' onchange='playerFirst = false'>
<br>
<br>
<br>
<button id='confirm' onclick='getGameUp()'>Confirm</button>
</div>
<div id='ticTacBoard'>
<div id='topLeft' onclick='move("topLeft")'> </div>
<div id='topMiddle' onclick='move("topMiddle")'> </div>
<div id='topRight' onclick='move("topRight")'> </div>
<br>
<div id='middleLeft' onclick='move("middleLeft")'> </div>
<div id='middleMiddle' onclick='move("middleMiddle")'> </div>
<div id='middleRight' onclick='move("middleRight")'> </div>
<br>
<div id='bottomLeft' onclick='move("bottomLeft")'> </div>
<div id='bottomMiddle' onclick='move("bottomMiddle")'> </div>
<div id='bottomRight' onclick='move("bottomRight")'> </div>
</div>
<br>
<br>
<br>
<br>
<br>
<div id='winDiv'>
<h1 id='winHeader'>
YOU WON!!!
</h1>
</div>
<div id='lossDiv'>
<h1 id='lossHeader'>
You lost...
</h1>
</div>
<div id='tieDiv'>
<h1 id='tieHeader'>
It's a tie!
</h1>
</div>
</center>
<script src="script.js"></script>
</body>
</html>
Javascript:
var player;
var computer;
var playerFirst;
var topLeftBox = document.getElementById('topLeft');
var topMiddleBox = document.getElementById('topMiddle');
var topRightBox = document.getElementById('topRight');
var middleLeftBox = document.getElementById('middleLeft');
var middleMiddleBox = document.getElementById('middleMiddle');
var middleRightBox = document.getElementById('middleRight');
var bottomLeftBox = document.getElementById('bottomLeft');
var bottomMiddleBox = document.getElementById('bottomMiddle');
var bottomRightBox = document.getElementById('bottomRight');
var winDiv = document.getElementById('winDiv');
var lossDiv = document.getElementById('lossDiv');
var ticTacBoard = document.getElementById('ticTacBoard');
var setup = document.getElementById('setup');
function getGameUp(){
setup.style.visibility = "hidden";
ticTacBoard.style.visibility = "visible";
if(playerFirst == false){
computerEasyModeMove();
}
}
function move(x){
if(x=='topLeft'){
if(topLeftBox.innerHTML != 'o' && topLeftBox.innerHTML != 'x'){
topLeftBox.innerHTML = player;
topLeftBox.style.pointerEvents = 'none';
}
}
if(x=='topMiddle'){
if(topMiddleBox.innerHTML != 'o' && topMiddleBox.innerHTML != 'x'){
topMiddleBox.innerHTML = player;
topMiddleBox.style.pointerEvents = 'none';
}
}
if(x=='topRight'){
if(topRightBox.innerHTML != 'o' && topRightBox.innerHTML != 'x'){
topRightBox.innerHTML = player;
topRightBox.style.pointerEvents = 'none';
}
}
if(x=='middleLeft'){
if(middleLeftBox.innerHTML != 'o' && middleLeftBox.innerHTML != 'x'){
middleLeftBox.innerHTML = player;
middleLeftBox.style.pointerEvents = 'none';
}
}
if(x=='middleMiddle'){
if(middleMiddleBox.innerHTML != 'o' && middleMiddleBox.innerHTML != 'x' ){
middleMiddleBox.innerHTML = player;
middleMiddleBox.style.pointerEvents = 'none';
}
}
if(x=='middleRight'){
if(middleRightBox.innerHTML != 'o' && middleRightBox.innerHTML != 'x'){
middleRightBox.innerHTML = player;
middleRightBox.style.pointerEvents = 'none';
}
}
if(x=='bottomLeft'){
if(bottomLeftBox.innerHTML != 'o' && bottomLeftBox.innerHTML != 'x'){
bottomLeftBox.innerHTML = player;
bottomLeftBox.style.pointerEvents = 'none';
}
}
if(x=='bottomMiddle'){
if(bottomMiddleBox.innerHTML != 'o' && bottomMiddleBox.innerHTML != 'x'){
bottomMiddleBox.innerHTML = player;
bottomMiddleBox.style.pointerEvents = 'none';
}
}
if(x=='bottomRight'){
if(bottomRightBox.innerHTML != 'o' && bottomRightBox.innerHTML != 'x'){
bottomRightBox.innerHTML = player;
bottomRightBox.style.pointerEvents = 'none';
}
}
checkWinCondition();
if(winDiv.style.visibility != 'visible'){
computerEasyModeMove();
checkWinCondition();
}
}
function computerEasyModeMove(){
if(player == 'x'){
computer = 'o';
}
if(player == 'o'){
computer = 'x';
}
var computerMove = Math.floor(Math.random() * 9) + 1;
while(computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 3 && (topRightBox.innerHTML == 'o' || topRightBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 4 && (middleLeftBox.innerHTML == 'o' || middleLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 5 && (middleMiddleBox.innerHTML == 'o' || middleMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 6 && (middleRightBox.innerHTML == 'o' || middleRightBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 7 && (bottomLeftBox.innerHTML == 'o' || bottomLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 8 && (bottomMiddleBox.innerHTML == 'o' || bottomMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 9 && (bottomRightBox.innerHTML == 'o' || bottomRightBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
if(computerMove == 1){
topLeftBox.innerHTML = computer;
topLeftBox.style.pointerEvents = 'none';
}
if(computerMove == 2){
topMiddleBox.innerHTML = computer;
topMiddleBox.style.pointerEvents = 'none';
}
if(computerMove == 3){
topRightBox.innerHTML = computer;
topRightBox.style.pointerEvents = 'none';
}
if(computerMove == 4){
middleLeftBox.innerHTML = computer;
middleLeftBox.style.pointerEvents = 'none';
}
if(computerMove == 5){
middleMiddleBox.innerHTML = computer;
middleMiddleBox.style.pointerEvents = 'none';
}
if(computerMove == 6){
middleRightBox.innerHTML = computer;
middleRightBox.style.pointerEvents = 'none';
}
if(computerMove == 7){
bottomLeftBox.innerHTML = computer;
bottomLeftBox.style.pointerEvents = 'none';
}
if(computerMove == 8){
bottomMiddleBox.innerHTML = computer;
bottomMiddleBox.style.pointerEvents = 'none';
}
if(computerMove == 9){
bottomRightBox.innerHTML = computer;
bottomRightBox.style.pointerEvents = 'none';
}
}
function computerMediumModeMove(){
}
function computerHardModeMove(){
}
function checkWinCondition(){
//Top 3 Player
if(topLeftBox.innerHTML == player && topMiddleBox.innerHTML == player && topRightBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Top 3 Computer
if(topLeftBox.innerHTML == computer && topMiddleBox.innerHTML == computer && topRightBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Middle 3 Player
if(middleLeftBox.innerHTML == player && middleMiddleBox.innerHTML == player && middleRightBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Middle 3 Computer
if(middleLeftBox.innerHTML == computer && middleMiddleBox.innerHTML == computer && middleRightBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Bottom 3 Player
if(bottomLeftBox.innerHTML == player && bottomMiddleBox.innerHTML == player && bottomRightBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Bottom 3 Computer
if(bottomLeftBox.innerHTML == computer && bottomMiddleBox.innerHTML == computer && bottomRightBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Left 3 Player (Up and Down)
if(bottomLeftBox.innerHTML == player && topLeftBox.innerHTML == player && middleLeftBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Left 3 Computer (Up and Down)
if(bottomLeftBox.innerHTML == computer && topLeftBox.innerHTML == computer && middleLeftBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Middle 3 Player (Up and Down)
if(bottomMiddleBox.innerHTML == player && topMiddleBox.innerHTML == player && middleMiddleBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Middle 3 Computer (Up and Down)
if(bottomMiddleBox.innerHTML == computer && topMiddleBox.innerHTML == computer && middleMiddleBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Right 3 Player (Up and Down)
if(bottomRightBox.innerHTML == player && topRightBox.innerHTML == player && middleRightBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Right 3 Computer (Up and Down)
if(bottomRightBox.innerHTML == computer && topRightBox.innerHTML == computer && middleRightBox.innerHTML == computer ){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Diagonal Left to Right Player (Down Slope)
if(bottomRightBox.innerHTML == player && topLeftBox.innerHTML == player && middleMiddleBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Diagonal Left to Right Computer (Down Slope)
if(bottomRightBox.innerHTML == computer && topLeftBox.innerHTML == computer && middleMiddleBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
//Diagonal Right to Left Player (Up Slope)
if(bottomLeftBox.innerHTML == player && topRightBox.innerHTML == player && middleMiddleBox.innerHTML == player){
ticTacBoard.style.pointerEvents = 'none';
winDiv.style.visibility = 'visible';
}
//Diagonal Right to Left Computer(Up Slope)
if(bottomLeftBox.innerHTML == computer && topRightBox.innerHTML == computer && middleMiddleBox.innerHTML == computer){
ticTacBoard.style.pointerEvents = 'none';
lossDiv.style.visibility = 'visible';
}
}
CSS:
#setup{
background-color:white;
height:75vh;
width:75vw;
}
#ticTacBoard{
text-transform:capitalize;
font-size:0vw;
background-color:white;
visibility:hidden;
position:absolute;
top:2vh;
}
#winDiv{
visibility:hidden;
background-color:white;
position:relative;
border:2px solid black;
}
#lossDiv{
visibility:hidden;
background-color:white;
position:relative;
border:2px solid black;
}
#tieDiv{
visibility:hidden;
background-color:white;
position:relative;
border:2px solid black;
}
#topLeft{
display:inline-block;
padding:30px;
border-right:2px solid black;
border-bottom:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#topLeft:hover{
background-color:lightgrey;
}
#topMiddle{
display:inline-block;
padding:30px;
border-bottom:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#topMiddle:hover{
background-color:lightgrey;
}
#topRight{
display:inline-block;
padding:30px;
border-left:2px solid black;
border-bottom:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#topRight:hover{
background-color:lightgrey;
}
#middleLeft{
display:inline-block;
padding:30px;
border-right:2px solid black;
border-bottom:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#middleMiddle:hover{
background-color:lightgrey;
}
#middleMiddle{
display:inline-block;
padding:30px;
border-bottom:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#middleLeft:hover{
background-color:lightgrey;
}
#middleRight{
display:inline-block;
padding:30px;
border-left:2px solid black;
border-bottom:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#middleRight:hover{
background-color:lightgrey;
}
#bottomLeft{
display:inline-block;
padding:30px;
border-right:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#bottomLeft:hover{
background-color:lightgrey;
}
#bottomMiddle{
display:inline-block;
padding:30px;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#bottomMiddle:hover{
background-color:lightgrey;
}
#bottomRight{
display:inline-block;
padding:30px;
border-left:2px solid black;
width:15vw;
height:15vh;
font-size:9vw;
cursor:pointer;
}
#bottomRight:hover{
background-color:lightgrey;
}
body{
background-color:grey;
}
答案 0 :(得分:3)
发生这种情况是因为您的逻辑存在缺陷。我将拿一小部分代码(如下所示):
var computerMove = Math.floor(Math.random() * 9) + 1;
while(computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
while(computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x')){
computerMove = Math.floor(Math.random() * 9) + 1;
}
请考虑以下情况:代码的第一行生成computerMove = 1
,并且 topLeftBox
已经用'x'或'o'填充了(没关系)。然后,我们转到第二行(第一个while
循环)。因为它检测到topLeftBox
已被填充,所以它将随机化一个数字。假设随机化得到computerMove = 2
。然后,由于computerMove
不再是1
,因此第一个while
循环退出,进入第二个while
循环。为了这个示例,我们假设topMiddleBox
也已经用'x'或'o'填充。它满足循环条件,因此,它使数字随机化。假设它随机化computerMove = 1
。要求computerMove
的值为2
的第二个循环条件未满足,因此退出循环。问题:它产生了computerMove
的{{1}},并且1
已经填充。那是您的代码失败的时候。
我还注意到您给了所有topLeftBox
唯一的ID。但是,在这种特定情况下,您可以通过仅为所有div
提供一个可以迭代的类来简化代码。请参见以下代码,该代码可以解决您的问题,并且在您的特定情况下,无需为每个div
使用特定的ID:
JS
div
HTML(在let actionBox = document.querySelectorAll('div.action-box')
function computerEasyModeMove() {
let randomizeMove = () => Math.floor(Math.random() * 9)
let computerMove = randomizeMove()
computer = player == 'x' ? 'o' : 'x'
while (actionBox[computerMove].innerHTML.trim() != ' ') {
computerMove = randomizeMove()
}
actionBox[computerMove].innerHTML = computer
actionBox[computerMove].style.pointerEvents = 'none'
}
内部)
div#ticTacBoard
分叉的代码:here
答案 1 :(得分:3)
我还没有测试过,但是我认为如果将其更改为跟随它应该可以工作(将9 while循环替换为1 while循环)。想法是确保获取下一个随机单元格(如果已被占用)。
var computerMove = Math.floor(Math.random() * 9) + 1;
while (computerMove == 1 && (topLeftBox.innerHTML == 'o' || topLeftBox.innerHTML == 'x')
|| (computerMove == 2 && (topMiddleBox.innerHTML == 'o' || topMiddleBox.innerHTML == 'x'))
|| (computerMove == 3 && (topRightBox.innerHTML == 'o' || topRightBox.innerHTML == 'x'))
|| (computerMove == 4 && (middleLeftBox.innerHTML == 'o' || middleLeftBox.innerHTML == 'x'))
|| (computerMove == 5 && (middleMiddleBox.innerHTML == 'o' || middleMiddleBox.innerHTML == 'x'))
|| (computerMove == 6 && (middleRightBox.innerHTML == 'o' || middleRightBox.innerHTML == 'x'))
|| (computerMove == 7 && (bottomLeftBox.innerHTML == 'o' || bottomLeftBox.innerHTML == 'x'))
|| (computerMove == 8 && (bottomMiddleBox.innerHTML == 'o' || bottomMiddleBox.innerHTML == 'x'))
|| (computerMove == 9 && (bottomRightBox.innerHTML == 'o' || bottomRightBox.innerHTML == 'x'))) {
computerMove = Math.floor(Math.random() * 9) + 1;
}