[JavaScript前端开发及实例教程]计算器井字棋游戏的实现

计算器(网页内实现效果)

HTML部分

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Calculator</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <section>
        <div class="container">
            <div id="display"></div>
            <div class="buttons">
                <div class="button">C</div>
                <div class="button">/</div>
                <div class="button">*</div>
                <div class="button">&larr;</div>
                <div class="button">7</div>
                <div class="button">8</div>
                <div class="button">9</div>
                <div class="button">-</div>
                <div class="button">4</div>
                <div class="button">5</div>
                <div class="button">6</div>
                <div class="button">+</div>
                <div class="button">1</div>
                <div class="button">2</div>
                <div class="button">3</div>
                <div class="button">.</div>
                <div class="button">(</div>
                <div class="button">0</div>
                <div class="button">)</div>
                <div id="equal" class="button">=</div>
            </div>
        </div>
    </section>
    <script src="index.js"></script>
</body>
</html>

CSS部分

.container {
    max-width: 400px;
    margin: 10vh auto 0 auto;
    box-shadow: 0px 0px 43px 17px rgba(153,153,153,1);
}

#display {
    text-align: right;
    height: 70px;
    line-height: 70px;
    padding: 16px 8px;
    font-size: 25px;
}

.buttons {
    display: grid;
    border-bottom: 1px solid #999;
    border-left: 1px solid#999;
    grid-template-columns: 1fr 1fr 1fr 1fr;
}

.buttons > div {
    border-top: 1px solid #999;
    border-right: 1px solid#999;
}

.button {
    border: 0.5px solid #999;
    line-height: 100px;
    text-align: center;
    font-size: 25px;
    cursor: pointer;
}

#equal {
    background-color: rgb(85, 85, 255);
    color: white;
}

.button:hover {
    background-color: #323330;
    color: white;
    transition: 0.5s ease-in-out;
}

JavaScript部分


//思路:
//1.用map或者forEach或者for循环给每个按钮(button)加上一个事件监听器addEventListener()
//2.当点击c的时候归零
//3.当点击=的时候把display里的值进行计算,可以用eval函数
//4.当点击<-时候,减去一个数
//5.当点击其他按钮的时候,就是把数往display里面加
//6.你可以用switch case来运行以上的不同情况按键,用if else也可以


// Get the display element
var display = document.getElementById('display');

// Get all the buttons
var buttons = Array.from(document.getElementsByClassName('button'));

// Add click event listener to each button
buttons.forEach(function(button) {
    button.addEventListener('click', function() {
        handleButtonClick(button.textContent);
    });
});

// Function to handle button clicks
function handleButtonClick(value) {
    switch (value) {
        case 'C':
            // Clear the display
            display.textContent = '';
            break;
        case '=':
            try {
                // Evaluate the expression in the display using eval
                display.textContent = eval(display.textContent);
            } catch (error) {
                // Handle errors, e.g., division by zero
                display.textContent = 'Error';
            }
            break;
        case '←':
            // Remove the last character from the display
            display.textContent = display.textContent.slice(0, -1);
            break;
        default:
            // Append the clicked button value to the display
            display.textContent += value;
            break;
    }
}

井字棋

HTML部分

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>三连棋</title>
    <link href="index.css" rel="stylesheet" />
  </head>
  <body>
    <h1>三连棋</h1>
    <div id="board">
      <!-- 棋盘上每个格子我们管它叫tile,并且自定义一个属性叫data-index,方便计数-->
      <!-- right-border就是棋盘内部的边框,给border上颜色 -->
      <div data-index="1" class="tile right-border bottom-border"></div>
      <div data-index="2" class="tile right-border bottom-border"></div>
      <div data-index="3" class="tile bottom-border"></div>
      <div data-index="4" class="tile right-border bottom-border"></div>
      <div data-index="5" class="tile right-border bottom-border"></div>
      <div data-index="6" class="tile bottom-border"></div>
      <div data-index="7" class="tile right-border"></div>
      <div data-index="8" class="tile right-border"></div>
      <div data-index="9" class="tile"></div>
      <!-- 三个棋子连到一起会出现一条红色线,我们管这个红色线叫strike -->
      <div id="strike" class="strike"></div>
    </div>
    <div id="game-over-area" class="hidden">
      <h2 id="game-over-text">获胜的是 X</h2>
      <button id="play-again">Play Again</button>
    </div>
    <script src="index.js"></script>
  </body>
</html>

CSS部分

/* 整体的棋盘 */
body {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: black;
  color: greenyellow;
}

/* 把1-9的数字,分成三列 */
#board {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  /* 鼠标移动到格子里就变成一个手掌图标 */
  cursor: pointer;
  position: relative;
}

/* 每个格子 */
.tile {
  color: currentColor;/*currentColor继承于body里面的color*/
  font-size: 2em;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 给格子边框上颜色 */
.right-border {
  border-right: 0.2em solid indigo;
}

/* 给格子边框上颜色 */
.bottom-border {
  border-bottom: 0.2em solid indigo;
}

/* 三个棋子连到一起会出现一条红色线,我们管这个红色线叫strike */
.strike {
  position: absolute;
  background-color: darkred;
}

/* 三个棋子在第1行连成一条线 */
.strike-row-1 {
  width: 100%;
  height: 4px;
  top: 15%;
}

/* 三个棋子在第2行连成一条线 */
.strike-row-2 {
  width: 100%;
  height: 4px;
  top: 48%;
}

/* 三个棋子在第3行连成一条线 */
.strike-row-3 {
  width: 100%;
  height: 4px;
  top: 83%;
}

/* 三个棋子在第1列连成一条线 */
.strike-column-1 {
  height: 100%;
  width: 4px;
  left: 15%;
}

/* 三个棋子在第2列连成一条线 */
.strike-column-2 {
  height: 100%;
  width: 4px;
  left: 48%;
}

/* 三个棋子在第3列连成一条线 */
.strike-column-3 {
  height: 100%;
  width: 4px;
  left: 83%;
}

/* 三个棋子在斜对角连成一条线 */
.strike-diagonal-1 {
  width: 90%;
  height: 4px;
  top: 50%;
  left: 5%;
  transform: skewY(45deg); /* skewy可以改变线的角度 */

}
.strike-diagonal-2 {
  width: 90%;
  height: 4px;
  top: 50%;
  left: 5%;
  transform: skewY(-45deg);
}

h1 {
  color: currentColor;
}

#game-over-area {
  text-align: center;
  border: indigo 8px solid;
  padding: 50px;
  width: 50%;
  margin-top: 50px;
}

h2 {
  color: currentColor;
  font-size: 2em;
  margin-top: 0px;
}

/* 重玩的按钮 */
button {
  background-color: transparent;
  color: currentColor;
  border: currentColor 1px solid;
  padding: 10px;
  font-size: 1.5em;
}

/* play again区域在游戏结束前不显示 */
.hidden {
  display: none;
}

/* play again区域在游戏结束后显示 */
.visible {
  display: block;
}

/* 玩家1点一下棋盘显示X */
.x-hover:hover::after {
  content: "X";
  opacity: 0.4;
}

/* 玩家2点一下棋盘显示O */
.o-hover:hover::after {
  content: "O";
  opacity: 0.4;
}

JavaScript部分

//选中所有的格子tile
var tiles = document.querySelectorAll(".tile");
//玩家X
var PLAYER_X = "X";
//玩家O
var PLAYER_O = "O";

//玩家X先下,之后这个变量turn会切换成另外一个玩家
var turn = PLAYER_X;

//boardstate追踪棋盘上的情况,把每一步下的棋放在对应下标放进数组。Array(tiles.length)就是9个格子
var boardState = Array(tiles.length);
boardState.fill(null);

//获取棋盘上的一些元素
var strike = document.getElementById("strike");
var gameOverArea = document.getElementById("game-over-area");
var gameOverText = document.getElementById("game-over-text");
var playAgain = document.getElementById("play-again");

//重新开始 play again
playAgain.addEventListener("click", startNewGame);

//音效
var gameOverSound = new Audio("sounds/game_over.wav");
var clickSound = new Audio("sounds/click.wav");

//用forEach给每一个格子增加addEventListener,当玩家点击这个格子的时候,
//你需要执行一个tileClick函数(在37行),tileClick函数的作用是显示X 或者 O
//*******************请写代码完成上述功能*******************

tiles.forEach(function (tile) {
  tile.addEventListener("click", tileClick);
});

//event参数是玩家点击的方块
//*******************请写代码完成上述功能*******************
function tileClick(event) {
  //如果游戏已经结束了,那就return,停止
  if (gameOverArea.classList.contains("visible")) {
    return;
  }
  var clickedTile = event.target;
  var tileIndex =  parseInt(clickedTile.dataset.index) - 1;

  if (boardState[tileIndex] !== null) {
    return;
  }

  if (turn === PLAYER_X) {
    clickedTile.innerText = PLAYER_X;
    boardState[tileIndex] = PLAYER_X;
    turn = PLAYER_O;
  } else {
    clickedTile.innerText = PLAYER_O;
    boardState[tileIndex] = PLAYER_O;
    turn = PLAYER_X;
  }
  //获取玩家点击的方块
  //*******************请写代码完成上述功能*******************


  //获取方块的编号:tile.dataset.index是获取data-index自定义属性内容的固定写法
  //*******************请写代码完成上述功能*******************

  //查看方块内是否已经被玩家点击过了
  //*******************请写代码完成上述功能*******************

  //如果这一轮是X玩家,那么给这个点击方块里写上X,如果是玩家O,那就给这个点击方块里写上0
  //一个玩家落子后,需要切换玩家
  //*******************请写代码完成上述功能*******************

  
  //播放点击音效
  clickSound.play();
  //显示悬浮的文字O或者X
  setHoverText();
  //查看谁胜了
  checkWinner();
}

//当玩家X鼠标移动在方框上时候,显示X;玩家O显示o
function setHoverText() {
  //移除所有hover 文字
  tiles.forEach(function (tile) {
    tile.classList.remove("x-hover");
    tile.classList.remove("o-hover");
  });

  var hoverClass = "".concat(turn.toLowerCase(), "-hover");

  tiles.forEach(function (tile) {
    if (tile.innerText == "") {
      tile.classList.add(hoverClass);
    }
  });
}

setHoverText();


//查看谁胜利了
function checkWinner() {

  //*********************给以下每一行代码添加注释~注释到return那一行*********************
  for (var _i = 0, _winningCombinations = winningCombinations; _i < _winningCombinations.length; _i++) {
    var winningCombination = _winningCombinations[_i];
    // console.log(boardState)
    var combo = winningCombination.combo,
        strikeClass = winningCombination.strikeClass;

    var tileValue1 = boardState[combo[0] - 1];
    var tileValue2 = boardState[combo[1] - 1];
    var tileValue3 = boardState[combo[2] - 1];

    if (tileValue1 != null && tileValue1 === tileValue2 && tileValue1 === tileValue3) {
      strike.classList.add(strikeClass);
      gameOverScreen(tileValue1); 
      return;
    }
  }

  //查看平局
  var allTileFilledIn = boardState.every(function (tile) {
    return tile !== null;
  });
  if (allTileFilledIn) {
    gameOverScreen(null);
  }
}

//game over的框
function gameOverScreen(winnerText) {
    gameOverArea.classList.remove("hidden");
    gameOverText.innerText = winnerText ? `Player ${winnerText} wins!` : "平局!";
    //把game over的框显示出来
  //*******************请写代码完成上述功能*******************
}

//重新开始一局游戏
function startNewGame() {
  strike.className = "strike";
  gameOverArea.className = "hidden";
  boardState.fill(null);
  tiles.forEach(function (tile) {
    return (tile.innerText = "");
  });
  turn = PLAYER_X;
  setHoverText();
}

//所有胜利组合
var winningCombinations = [
  //例如
  { combo: [1, 2, 3], strikeClass: "strike-row-1" },
  { combo: [4, 5, 6], strikeClass: "strike-row-2" },
  { combo: [7, 8, 9], strikeClass: "strike-row-3" },
  { combo: [1, 4, 7], strikeClass: "strike-col-1" },
  { combo: [2, 5, 8], strikeClass: "strike-col-2" },
  { combo: [3, 6, 9], strikeClass: "strike-col-3" },
  { combo: [1, 5, 9], strikeClass: "strike-diagonal-1" },
  { combo: [3, 5, 7], strikeClass: "strike-diagonal-2" },
  //建立一个对象,把所有胜利组合都放进去,上面只是一个例子,一共有8个组合,你还要写7个组合
  //*******************请写代码完成上述功能*******************

];

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/221678.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ruff智能物联网网关助力工厂数智化运营,实现产量提升5%

数字化转型是大势所趋&#xff0c;以工业互联网为代表的数实融合是发展数字经济的重要引擎&#xff0c;也是新质生产力的一大助力。工业互联网是新工业革命的重要基石&#xff0c;加快工业互联网规模化应用&#xff0c;是数字技术和实体经济深度融合的关键支撑&#xff0c;是新…

回归预测 | MATLAB实现CNN-BiLSTM(卷积双向长短期记忆神经网络

效果一览 基本介绍 提出一种同时考虑时间与空间因素的卷积&#xff0d;双向长短期记忆&#xff08; CNN-BiLSTM&#xff09;模型&#xff0c;将具有空间局部特征提取能力的卷积神经网络&#xff08;CNN&#xff09;和具有能同时考虑前后方向长时间信息的双向长短期记忆&#xf…

JavaScript基础知识21——for循环

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 今天学习for循环&#xff0c;以下为学习笔记。 1、while循环和for循环有啥不同&#xff1f; 1.1、在实际开发中&#xff0c;while循环用来解决循环次数不确定时使用&#xff0c;当一个循环不确定会循环多少次时&#…

【每日OJ —— 94. 二叉树的中序遍历】

每日OJ —— 94. 二叉树的中序遍历 1.题目&#xff1a;94. 二叉树的中序遍历2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目&#xff1a;94. 二叉树的中序遍历 2.解法 2.1.算法讲解 1.首先如果在每次每个节点遍历的时候都去为数组开辟空间&#xff0c;这样的效率太低…

OWASP安全练习靶场juice shop-更新中

Juice Shop是用Node.js&#xff0c;Express和Angular编写的。这是第一个 完全用 JavaScript 编写的应用程序&#xff0c;列在 OWASP VWA 目录中。 该应用程序包含大量不同的黑客挑战 用户应该利用底层的困难 漏洞。黑客攻击进度在记分板上跟踪。 找到这个记分牌实际上是&#…

【PyTorch】tensorboardX的安装和使用

文章目录 1. tensorboardX的安装2. tensorboardX的使用 tensorboardX是一种能将训练过程可视化的工具 1. tensorboardX的安装 安装命令&#xff1a; pip install tensorboardXVSCode集成了TensorBoard支持&#xff0c;不过事先要安装torch-tb-profiler&#xff0c;安装命令&…

文件管理和操作工具Path Finder mac功能介绍

Path Finder mac是一款Mac平台上的文件管理和操作工具&#xff0c;提供了比Finder更丰富的功能和更直观的用户界面。它可以帮助用户更高效地浏览、复制、移动、删除和管理文件&#xff0c;以及进行各种高级操作。 Path Finder mac软件功能 - 文件浏览&#xff1a;可以快速浏览文…

如何购买华为云服务器

华为云是华为推出的云计算服务平台&#xff0c;旨在为企业和个人提供全面的云端解决方案。它提供了包括计算、存储、数据库、人工智能、大数据、安全等多种云服务&#xff0c;覆盖了基础设施、平台和软件级别的需求。华为云致力于构建安全可信赖的云计算基础设施&#xff0c;以…

vite初识

Vite是伴随着Vue3正式版一起发布的&#xff0c;最开始Vite 1.0的版本是为Vue3服务的&#xff0c;并不是跨框架的。之后半年时间左右&#xff0c;出现了Vite 2.0版本&#xff0c;Vite 2.0真正脱离了和Vue3的强关联&#xff0c;以插件的方式&#xff0c;可以集成到目前流行的主流…

【每日一题】到达首都的最少油耗

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;贪心深搜 写在最后 Tag 【递归/深度优先搜索】【树】【2023-12-05】 题目来源 2477. 到达首都的最少油耗 题目解读 每个城市都有一位代表需要前往城市 0 进行开会。每个城市都有一辆座位数为 seats 的汽车&#xff0…

2023.12.4 关于 Spring Boot 统一异常处理

目录 引言 统一异常处理 异常全部监测 引言 将异常处理逻辑集中到一个地方&#xff0c;可以避免在每个控制器或业务逻辑中都编写相似的异常处理代码&#xff0c;这降低了代码的冗余&#xff0c;提高了代码的可维护性统一的异常处理使得调试和维护变得更加容易&#xff0c;通…

Python智能语音识别语翻译平台|项目后端搭建

Python程序设计基础&#xff0c;第三方库Django、requests、hashlib、pyttsx3等的使用&#xff0c;百度API语音识别业务接口、文本朗读业务接口、翻译业务接口的传入。 01、任务实现步骤 任务描述&#xff1a;本任务利用Django框架搭建智能语音识别与翻译平台的后端&#xff0…

leetcode:统计感冒序列的数目【数学题:组合数含逆元模版】

1. 题目截图 2.题目分析 需要把其分为多个段进行填充 长为k的段&#xff0c;从两端往中间填充的方案数有2 ** (k - 1)种 组合数就是选哪几个数填哪几个段即可 3.组合数含逆元模版 MOD 1_000_000_007 MX 100_000# 组合数模板 fac [0] * MX fac[0] 1 for i in range(1, MX…

GPT-Crawler一键爬虫构建GPTs知识库

GPT-Crawler一键爬虫构建GPTs知识库 写在最前面安装node.js安装GPT-Crawler启动爬虫结合 OpenAI自定义 assistant自定义 GPTs&#xff08;笔者用的这个&#xff09; 总结 写在最前面 GPT-Crawler一键爬虫构建GPTs知识库 能够爬取网站数据&#xff0c;构建GPTs的知识库&#xf…

LeetCode //C - 221. Maximal Square

221. Maximal Square Given an m x n binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area. Example 1: Input: matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,…

计算机操作系统2

1.计算机操作系统的发展和分类 2.操作系统的运行机制 3.中断 3.1.中断&#xff08;关键作用&#xff09; 4.系统调用 5.操作系统的内核 6.操作系统的体系结构 7.开机过程&#xff08;操作系统引导&#xff09;

Vue3网站用户引导功能【Intro.js】

一、介绍 Intro.js 是一个用于创建网站用户引导、功能介绍和教程的 JavaScript 库。它允许开发者通过步骤和提示突出显示网站上的特定元素&#xff0c;以帮助用户更好地了解和使用网站的功能。以下是 Intro.js 的一些关键特点和用法介绍&#xff1a; 更多Intro.js 功能网址&a…

Hadoop学习笔记(HDP)-Part.08 部署Ambari集群

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

C语言--每日选择题--Day37

第一题 1. 有以下说明语句&#xff1a;则下面引用形式错误的是&#xff08;&#xff09; struct Student {int num;double score; };struct Student stu[3] {{1001,80}, {1002,75}, {1003,91}} struct Student *p stu; A&#xff1a;p->num B&#xff1a;(p).num C&#…

使用 GPTs 手捏一个代码评分器(两小时速成)

嗨&#xff01;大家好久不见~ ChatGPT 支持 GPTs 也有段时间了&#xff0c;看着应用商店里大神们捏出来的 GPTs , 有些确实很有意思&#xff0c;比如&#xff1a;AI 杠精、模拟面试官、海龟汤… 团子也跃跃欲试&#xff0c;想捏一个 好玩且对大家有用 的 GPTs 出来。 考虑到关注…