JavaScript implements AI tic-tac-toe game through the maximum and minimum algorithm

JavaScript implements AI tic-tac-toe game through the maximum and minimum algorithm

Without further ado, let’s run the screenshot directly:

The black pieces are the player's positions, and the red pieces are the computer's. The computer will choose a situation that is favorable to itself but unfavorable to the player based on the current situation on the board.

The algorithm can achieve a computer victory, or a tie between the computer and the player.

The code is as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TicTacToe AI</title>
<style>
	.title {
		text-align: center;
	}
	
	.chess {
		display: block;
		/*Become a block-level element and use margin to center it*/
		margin: 50px auto;
		box-shadow: 5px 5px 5px #B9B9B9, -2px -2px 2px #EFEFEF;
		cursor: pointer;
	}
	
	div {
		text-align: center;
	}
	
	.restart {
		padding: 10px 20px;
		background-color: #EE82EE;
		border-radius: 5px;
		color: white;
		cursor: pointer;
	}
</style>
</head>
 
<body>
	<h3 class="title">--Tic-Tac-toe--</h3>
	<canvas class="chess" width="450px" height="450px"></canvas>
	<div>
		<a class="restart" onclick="rst()">Restart</a>
	</div>
</body>
 
<script>
	var chess = document.getElementsByClassName("chess")[0];
	var title = document.getElementsByClassName("title")[0];
	var context = chess.getContext("2d");
	context.strokeStyle = "#B9B9B9"
 
	window.onload = function() {
		drawChessBoard();
		Init()
	}
 
	function drawChessBoard() {
		for(var i = 0; i < 4; i++) {
			//Set the coordinates of the starting point of the horizontal line context.moveTo(15, 15 + i * 140)
			//Set the coordinates of the end point of the horizontal line context.lineTo(435, 15 + i * 140)
			//Connect 2 points context.stroke();
			//Set the vertical line context.moveTo(15 + i * 140, 15)
			//Set the coordinates of the end point of the horizontal line context.lineTo(15 + i * 140, 435)
			//Connect 2 points context.stroke();
		}
	}
 
	//Define a two-dimensional array to mark chess pieces var chessboard = []
	for(var i = 0; i < 4; i++) {
		chessboard[i] = [];
		for(var j = 0; j < 4; j++) {
			chessboard[i][j] = 0;
		}
	}
 
	const NUMBER = 3
	const STEP = 9
	const MAN = 1
	const COMPUTER = -1
	const SEARCHDEPTH = 9
	const INT_MAX = 999999
	const INT_MIN = -1000000
 
	var player = 0
	var isGameOver = false
	var currentDepth = 0
	var bestPosition = {
		x: 0,
		y: 0
	}
 
	function Init() {
		for(let i = 0; i < NUMBER; i++) {
			for(let j = 0; j < NUMBER; j++) {
				chessboard[i][j] = 0
			}
		}
		player = MAN
		isGameOver = false
		currentDepth = 0
	}
 
	function isEnd() {
		let i = 0
		let j = 0
		var count = 0
		for(i = 0; i < NUMBER; i++) { //row count = 0;
			for(j = 0; j < NUMBER; j++)
				count += chessboard[i][j];
			if(count == 3 || count == -3)
				return count / 3;
		}
		for(j = 0; j < NUMBER; j++) { //column count = 0;
			for(i = 0; i < NUMBER; i++)
				count += chessboard[i][j];
			if(count == 3 || count == -3)
				return count / 3;
		}
		count = 0;
		count = chessboard[0][0] + chessboard[1][1] + chessboard[2][2];
		if(count == 3 || count == -3)
			return count / 3;
		count = chessboard[0][2] + chessboard[1][1] + chessboard[2][0];
		if(count == 3 || count == -3)
			return count / 3;
		return 0;
	}
 
	function MaxMinSearch(depth) {
		var value = 0;
		if(player == MAN) value = INT_MIN;
		if(player == COMPUTER) value = INT_MAX;
		if(isEnd() != 0) {
			return Evaluate();
		}
		if(depth == SEARCHDEPTH) {
			value = Evaluate();
			return value;
		}
 
		for(let i = 0; i < NUMBER; i++) {
			for(let j = 0; j < NUMBER; j++) {
				if(chessboard[i][j] == 0) {
					if(player == MAN) {
						chessboard[i][j] = MAN;
						player = COMPUTER;
						var nextvalue = MaxMinSearch(depth + 1);
						player = MAN;
						if(value < nextvalue) {
							value = nextvalue;
							if(depth == currentDepth) {
								bestPosition.x = i;
								bestPosition.y = j;
							}
 
						}
 
					} else if(player == COMPUTER) {
						chessboard[i][j] = COMPUTER;
						player = MAN;
						var nextvalue = MaxMinSearch(depth + 1);
						player = COMPUTER;
						if (value > nextvalue) {
							value = nextvalue;
							if(depth == currentDepth) {
								bestPosition.x = i;
								bestPosition.y = j;
							}
 
						}
					}
					chessboard[i][j] = 0;
				}
 
			}
		}
 
		return value;
	}
	function Logic(){
		if (isGameOver) {
			if (isEnd() == MAN) {
				alert("Game ends and player wins")
			} else if (isEnd() == COMPUTER) {
				alert("Game over, computer wins")
			} else {
				alert("Game ends in a draw")
			}
		}
	}
 
	function Evaluate() {
		var value = isEnd();
		if(value == MAN) return INT_MAX;
		if(value == COMPUTER) return INT_MIN;
	}
 
	chess.onclick = function(event) {
		if(player != MAN) {
			return;
		}
		//Get coordinates var x = event.offsetX;
		var y = event.offsetY;
 
		x = Math.trunc((x - 15) / 140)
		y = Math.trunc((y - 15) / 140)
 
		ManPlay(x, y)
		if(isEnd() == 0 && currentDepth < 8) {
			ComputerPlay()
			if(isEnd() != 0) {
				isGameOver = true
			}
		} else {
			isGameOver = true
		}
		Logic()
	}
 
	function ManPlay(x, y) {
		chessboard[x][y] = MAN
		DrawBroad(x,y,MAN)
		currentDepth++
		player = COMPUTER
	}
 
	function ComputerPlay() {
		MaxMinSearch(currentDepth)
		chessboard[bestPosition.x][bestPosition.y] = COMPUTER
		DrawBroad(bestPosition.x,bestPosition.y,COMPUTER)
		currentDepth++
		player = MAN
	}
 
	//Draw the board when placing a move function DrawBroad(i, j, player) {
		context.beginPath();
		context.arc(85 + i * 140, 85 + j * 140, 40, 0, 2 * Math.PI); //Draw a circle context.closePath();
 
		var color;
		if(player == MAN) {
			color = "#000";
		} else {
			color = "red"
		}
		context.fillStyle = color;
		context.fill();
	}
 
	function rst() {
		window.location.reload();
	}
</script>
 
</html>

Among them, the code lines 242 and 244

context.beginPath();
context.arc(85 + i * 140, 85 + j * 140, 40, 0, 2 * Math.PI); //Draw a circle context.closePath();

They are the operations of putting the pen down and lifting the pen. This can avoid the problem of paths being connected when drawing circles on the canvas.

This concludes the article on implementing AI Tic-Tac-toe game in JavaScript through the minimax algorithm. For more JavaScript Tic-Tac-toe game content, please search 123WORDPRESS.COM’s previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • JavaScript Canvas implements Tic-Tac-Toe game
  • JavaScript implements a Tic-Tac-toe game source code with AI
  • Python introductory game tic-tac-toe example code
  • Implementing Tic-Tac-Toe Game Based on C Language
  • Python implements a tic-tac-toe game with an interface
  • Implementing a simple tic-tac-toe game in C
  • Vue implements tic-tac-toe game

<<:  HTML form tag usage learning tutorial

>>:  Solution for mobile browsers not supporting position: fix

Recommend

Jenkins packaging microservices to build Docker images and run them

Table of contents Environment Preparation start 1...

HTML+CSS to achieve layered pyramid example

This article mainly introduces the example of imp...

HTML marquee tag usage examples

This tag is not part of HTML3.2 and only supports ...

Problems with creating placeholders for HTML selection boxes

I'm using a placeholder in a text input and i...

Two box models in web pages (W3C box model, IE box model)

There are two types of web page box models: 1: Sta...

An example of how JavaScript can prevent duplicate network requests

Preface During development, we often encounter va...

JavaScript Regular Expressions Explained

Table of contents 1. Regular expression creation ...

MySQL full backup and quick recovery methods

A simple MySQL full backup script that backs up t...

How to use native JS to implement touch sliding monitoring events

Preface I wrote a small demo today. There is a pa...

VUE implements a Flappy Bird game sample code

Flappy Bird is a very simple little game that eve...

How to create LVM for XFS file system in Ubuntu

Preface lvm (Logical Volume Manager) logical volu...

In-depth study of MySQL multi-version concurrency control MVCC

MVCC MVCC (Multi-Version Concurrency Control) is ...

How to solve the problem of ERROR 2003 (HY000) when starting mysql

1. Problem Description When starting MYSQL, a pro...

Why MySQL should avoid large transactions and how to solve them

What is a big deal? Transactions that run for a l...

Example of how to create a database name with special characters in MySQL

Preface This article explains how to create a dat...