前端技术搭建五子棋游戏(内含源码)

news2025/1/11 20:06:08

The sand accumulates to form a pagoda

  • ✨ 写在前面
  • ✨ 功能介绍
  • ✨ 页面搭建
  • ✨ 样式设置
  • ✨ 逻辑部分


✨ 写在前面

上周我们实通过前端基础实现了拼图游戏,今天还是继续按照我们原定的节奏来带领大家完成一个五子棋游戏,功能也比较简单简单,也是想借助这样一个简单的功能,然后来帮助大家了解我们JavaScript在前端中的作用, 在前面的文章当中我们也提及到我们在本系列的专栏是循序渐进从简单到复杂的过程,这份专栏中我们会带领大家用前端实现翻卡片、飞机大战、弹珠游戏、贪吃蛇、井字游戏、拼图、连连看、扫雷等等有趣的小游戏,纯前端语言实现,都会陆续带给大家。欢迎大家订阅我们这份前端小游戏的专栏。订阅链接:https://blog.csdn.net/jhxl_/category_12261013.html


✨ 功能介绍

五子棋是一种古老而受欢迎的策略棋类游戏,它的目标是在棋盘上先形成连续的五个棋子(横向、纵向或对角线),以赢得比赛。这款游戏简单易学,同时也有很高的策略性和竞争性,因此深受广大玩家喜爱。

游戏棋盘:五子棋的棋盘是一个15x15的方格网格,共有225个交叉点。玩家可以在这些交叉点上放置自己的棋子。

游戏目标:玩家需要先于对手在棋盘上形成连续的五个棋子(横向、纵向或对角线),以获得胜利。

在这里插入图片描述

游戏流程:玩家与电脑(或其他玩家)轮流进行下棋,玩家先手。玩家可以通过点击棋盘上的交叉点来放置自己的棋子。电脑(或其他玩家)也会在空闲的交叉点上进行自己的下棋操作。每一步棋之后,都会检查是否有玩家获胜或者游戏结束。

获胜条件:如果玩家在横向、纵向或对角线上形成连续的五个棋子(即五子连珠),即可获得胜利。如果棋盘填满且没有玩家获胜,则宣布游戏为平局。

再来一局:在游戏结束后,玩家可以选择重新开始一局,棋盘会被清空,双方重新开始对决。

通过上述规则,你可以实现一个简单的玩家对电脑的五子棋游戏。你可以根据自己的喜好和需求进一步扩展和定制游戏功能,例如添加游戏设置、优化电脑的下棋策略等。祝你玩得愉快!


✨ 页面搭建

创建文件

首先呢我们创建我们的HTML文件,这里我就直接命名为 五子棋.html 了,大家可以随意命名, 文件创建生成后我们通过编辑器打开,这里我用的是VScode, 然后初始化我们的代码结构,那在这里告诉大家一个快捷键,就是我们敲上我们英文的一个 ! 我们敲击回车直接就会给我们生成基础版本的前端代码结构。

在这里插入图片描述

文档声明和编码设置: 在HTML文档的头部,使用<!DOCTYPE>声明HTML文档类型,确保浏览器以正确的方式渲染网页内容。同时,设置UTF-8编码,以确保浏览器能够正确地解析和显示中文字符。下面我就开始搭建我们的DOM结构了!

DOM结构搭建

<body>
    <div class="board"></div>
    <div class="message"></div>
    <button class="reset-button">重新开始</button>
</body>
  • <body>:页面的主体元素。
  • <div class="board">:一个具有board类的<div>元素,用于承载五子棋的棋盘。
  • <div class="message">:一个具有message类的<div>元素,用于显示游戏中的消息或提示。
  • <button class="reset-button">重新开始</button>:一个具有reset-button类的<button>元素,用于重新开始游戏。

这段代码描述了一个五子棋游戏的基本页面结构,其中棋盘、消息和重新开始按钮是游戏的主要组成部分。


✨ 样式设置

我们看到了上面的的DOM已经搭建好了,但是页面什么都看不出来,下面我们简单的来配置一下样式吧,其实我们本专栏也是想带领大家掌握一些逻辑所以样式方面我们就一切从简;

  • .board:棋盘容器的样式规则,使用网格布局,设置背景颜色和间距。

  • .cell:每个棋盘格子的样式规则,设置背景颜色和边框。

  • .cell:hover:鼠标悬停在格子上时的样式规则,设置背景颜色。

  • .piece:棋子的样式规则,设置宽度、高度、边框半径和间距。

  • .black-piece:黑色棋子的样式规则,设置背景颜色。

  • .white-piece:白色棋子的样式规则,设置背景颜色。

  • .message:消息文本的样式规则,设置字体粗细。

  • .reset-button:重新开始按钮的样式规则,设置上方间距。

这些样式规则通过类名的方式应用到HTML元素上,从而实现了五子棋游戏界面的样式效果。

<style>
  .board {
    display: grid;
    grid-template-columns: repeat(15, 40px);
    grid-template-rows: repeat(15, 40px);
    gap: 1px;
    background-color: #aaa;
    margin-bottom: 20px;
  }

  .cell {
    background-color: #eee;
    border: 1px solid #ccc;
  }

  .cell:hover {
    background-color: #ddd;
  }

  .piece {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    margin: 2px;
  }

  .black-piece {
    background-color: #000;
  }

  .white-piece {
    background-color: #fff;
  }

  .message {
    font-weight: bold;
  }

  .reset-button {
    margin-top: 10px;
  }
</style>

在这里插入图片描述


✨ 逻辑部分

上面我们搭建了基本的样式,下面呢我们就通过js代码,实现我们游戏的功能吧,下面是对代码的简化解释:

  • createBoard():创建棋盘函数,用于动态生成一个15x15的棋盘,并为每个格子添加事件监听器。

  • handleCellClick(event):处理格子点击事件函数,根据当前游戏状态和点击的格子位置判断是否可以下子,并进行相应的处理。

  • placePiece(row, col, player):下子函数,根据给定的行、列和玩家类型,在指定的格子位置放置对应颜色的棋子,并更新棋盘状态。

  • switchPlayer():切换玩家函数,用于在玩家下子后切换到另一个玩家。

  • checkWin(row, col):检查胜利函数,根据当前下子的位置检查是否达到五子连珠的胜利条件。

  • checkDirection(row, col, dx, dy, player):检查方向函数,根据指定的方向,在当前位置的左右两侧检查是否有连续的同色棋子。

  • isValidPosition(row, col):验证位置有效性函数,用于判断指定的行和列是否在合法的范围内。

  • makeComputerMove():电脑下子函数,随机生成电脑下子的位置,并执行下子操作。

  • endGame(winner):结束游戏函数,当游戏达到胜利条件时,设置游戏结束标志,并显示胜利信息。

  • resetGame():重新开始游戏函数,用于重置游戏状态,清空棋盘,重新创建棋盘。

  • resetButton.addEventListener('click', resetGame):绑定重新开始按钮的点击事件监听器。

  • createBoard():在页面加载完成后,执行创建棋盘的函数,初始化游戏。

以上是对给定的JavaScript代码中各个方法的大概作用进行的简要讲解。每个方法都承担着不同的功能,通过它们的协作实现了一个基本的人机对决的五子棋游戏。

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>几何⚡️前端小游戏⚡️五子棋</title>
    <style>
        .board {
            display: grid;
            grid-template-columns: repeat(15, 40px);
            grid-template-rows: repeat(15, 40px);
            gap: 1px;
            background-color: #aaa;
            margin-bottom: 20px;
        }

        .cell {
            background-color: #eee;
            border: 1px solid #ccc;
        }

        .cell:hover {
            background-color: #ddd;
        }

        .piece {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            margin: 2px;
        }

        .black-piece {
            background-color: #000;
        }

        .white-piece {
            background-color: #fff;
        }

        .message {
            font-weight: bold;
        }

        .reset-button {
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <div class="board"></div>
    <div class="message"></div>
    <button class="reset-button">重新开始</button>
</body>

<script>
    document.addEventListener('DOMContentLoaded', () => {
        const board = document.querySelector('.board');
        const message = document.querySelector('.message');
        const resetButton = document.querySelector('.reset-button');

        const PlayerType = {
            PLAYER: 'player',
            COMPUTER: 'computer',
        };

        let currentPlayer = PlayerType.PLAYER;
        let isGameOver = false;
        let boardState = [];

        function createBoard() {
            board.innerHTML = '';

            for (let row = 0; row < 15; row++) {
                boardState[row] = [];
                for (let col = 0; col < 15; col++) {
                    const cell = document.createElement('div');
                    cell.classList.add('cell');
                    cell.dataset.row = row;
                    cell.dataset.col = col;
                    cell.addEventListener('click', handleCellClick);
                    board.appendChild(cell);
                    boardState[row][col] = '';
                }
            }
        }

        function handleCellClick(event) {
            if (isGameOver) {
                return;
            }

            const cell = event.target;
            const row = parseInt(cell.dataset.row);
            const col = parseInt(cell.dataset.col);

            if (boardState[row][col] !== '') {
                return;
            }

            placePiece(row, col, currentPlayer);

            if (checkWin(row, col)) {
                endGame(currentPlayer);
                return;
            }

            switchPlayer();

            if (currentPlayer === PlayerType.COMPUTER && !isGameOver) {
                makeComputerMove();
            }
        }

        function placePiece(row, col, player) {
            const piece = document.createElement('div');
            piece.classList.add('piece');
            piece.classList.add(player === PlayerType.PLAYER ? 'black-piece' : 'white-piece');
            const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
            cell.appendChild(piece);
            boardState[row][col] = player;
        }

        function switchPlayer() {
            currentPlayer = currentPlayer === PlayerType.PLAYER ? PlayerType.COMPUTER : PlayerType.PLAYER;
        }

        function checkWin(row, col) {
            const directions = [
                [1, 0],
                [0, 1],
                [1, 1],
                [1, -1]
            ];

            const player = boardState[row][col];
            for (const direction of directions) {
                const [dx, dy] = direction;
                let count = 1;

                // Check for consecutive pieces in both directions
                count += checkDirection(row, col, dx, dy, player);
                count += checkDirection(row, col, -dx, -dy, player);

                if (count >= 5) {
                    return true;
                }
            }

            return false;
        }

        function checkDirection(row, col, dx, dy, player) {
            let count = 0;
            let newRow = row + dx;
            let newCol = col + dy;

            while (isValidPosition(newRow, newCol) && boardState[newRow][newCol] === player) {
                count++;
                newRow += dx;
                newCol += dy;
            }

            return count;
        }

        function isValidPosition(row, col) {
            return row >= 0 && row < 15 && col >= 0 && col < 15;
        }

        function makeComputerMove() {
            // Generate a random move for the computer
            let row, col;
            do {
                row = Math.floor(Math.random() * 15);
                col = Math.floor(Math.random() * 15);
            } while (boardState[row][col] !== '');

            placePiece(row, col, currentPlayer);

            if (checkWin(row, col)) {
                endGame(currentPlayer);
                return;
            }

            switchPlayer();
        }

        function endGame(winner) {
            isGameOver = true;
            message.textContent = winner === PlayerType.PLAYER ? 'You win!' : 'Computer wins!';
        }

        function resetGame() {
            currentPlayer = PlayerType.PLAYER;
            isGameOver = false;
            boardState = [];
            message.textContent = '';
            createBoard();
        }

        resetButton.addEventListener('click', resetGame);

        createBoard();
    });
</script>

</html>

几何送书七十二期

参与方式:本博客中进行评论即可,只要评论内容不被折叠都可以参与抽奖;
抽奖方式:程序自动拉取未折叠的评论随机抽取5位伙伴,每人最多可评论5次;
抽奖时间:2023-07-07 17:00
本期获奖者各送实体书《Python从入门到精通》一本(包邮到家)

在这里插入图片描述

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探究工业运营中的三大工具:根因分析、过程优化和预测性维护

在工业运营领域&#xff0c;根本原因分析、过程优化工具和预测性维护正在彻底改变维护实践的方式。这些工具的战略性组合使得制造工厂能够提升实践水平、提高生产力&#xff0c;并实现持续的成功。本文将以PreMaint为基础&#xff0c;探讨这些工具之间的差异&#xff0c;以及如…

添加数据维度并使用Python绘制5D散点图

大家好&#xff0c;散点图通常用于比较2个不同特征以确定它们之间的关系&#xff0c;散点图也可以添加更多的维度来反映数据&#xff0c;例如使用颜色、气泡大小等。在本文中&#xff0c;将介绍如何绘制一个五维的散点图。 数据集&#xff1a; https://github.com/checkming0…

物联网工控屏在ROV布放回收系统中的应用

一、背景 1. 深海作业装备制造行业 随着我国经济与科学技术的发展壮大&#xff0c;作为“蓝色粮仓”的海洋能源开采建设逐渐成为一项重要的事业。深海作业装备则成为海洋能源开采的必备和关键工具&#xff0c;其性能和可靠性须得以保障。也因此&#xff0c;开发性能表现更优、…

vs背景和主题设置(一看就会,简单实用)

VS背景设置 目录&#xff1a;一、背景插件下载二、主题切换三、调整成自己喜欢的界面 目录&#xff1a; 学习编程是个漫长的过程&#xff0c;设置一个自己喜欢的背景&#xff0c;可以使自己编写代码的时候更舒服。马上行动起来&#xff0c;设置一个自己喜欢的背景吧。 分享一下…

J2EE集合框架List

目录 一.UML ①集合类图 ②线下教育平台用例图 二.List集合特点 ①学集合框架就是了解容器的数据结构&#xff08;增删改查&#xff09; ②有序的 可重复的 三.遍历方式 ① foreach ② iterator 迭代器 ③ for 四.LinkedList ①对比ArrayList是数据结构 Linkedlist…

【回溯算法part01】| 理论基础、77.组合

&#x1f388;回溯算法理论基础 回溯算法的本质是穷举&#xff0c;并不是一个高效的算法&#xff0c;但是有的题必须要用回溯法&#xff0c;如&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集…

学习 | 药品GMP认证和药厂GMP认证是怎么回事?

可能本身从事药品生产经营的朋友会知道&#xff0c;药品的GMP认证是怎么一回事&#xff0c;但是对于一些想要进入药品生产行业的企业&#xff0c;例如化工产品想进入原料药生产、药用辅料生产&#xff0c;塑料等材料制作商进入药品包装材料生产&#xff0c;只是听这说听那说&am…

【STL】vector快速上手

目录 一&#xff0c;vector的模板特性 二&#xff0c;vector基本使用 1. 构造函数 2. operator 赋值 3. vector——增删 A, 尾插 && 尾删 B&#xff0c;insert C, erase 4. 访问vector 遍历vector中元素&#xff1a; 法一&#xff1a;数组[]法 || at法…

HashMap-JDK8源码讲解及常见面试题

数据结构 红黑树 在JDK8中&#xff0c;优化了HashMap的数据结构&#xff0c;引入了红黑树。即HashMap的数据结构&#xff1a;数组链表红黑树。HashMap变成了这样。 为什么要引入红黑树 1、主要是为了提高HashMap的性能&#xff0c;即解决发生hash冲突后&#xff0c;因为链…

一些总结-C++

1.spdlog 需要安装spdlog库&#xff0c;然后连接器增加-lspdlog 不需要复制头文件到目录&#xff0c;安装到机器上之后&#xff0c;从系统目录加载头文件即可。 部分用法&#xff1a; 2.redis 需要安装hiredis库&#xff0c;链接器-lhiredis 不需要复制头文件到目录&#…

Java Web HTTP 23.7.4

HTTP 1&#xff0c;Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏览器访问的网站。 在我们日常的生活中&#xff0c;经常会使用浏览器去访问百度、京东等这些网站&#xff0c;这些网站统称为Web网站。如下就是通过浏…

Linux学习之i节点(inode)和数据块操作

touch testfile创建一个空文件testfile。 stat testfile可以看一下文件的inode信息。 ls -li testfile看一下testfile相关信息。 上图中922208是inode号码&#xff0c;也称为inode编号&#xff0c;若是使用ls -i testfile就可以直接看到inode号码。 du -h testfile可以看…

【Unity3D 问题总结】☀️ | 解决LayoutGroup配合Content Size Fitter使用时发生子成员位置错乱问题

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…

Android、iOS快速全球化工具

动机 在进行移动端全球化的时候&#xff0c;我们需要根据语言类型准备格式相同&#xff0c;文本不同的好多个文件&#xff0c;如果一个一个翻译显然很浪费时间&#xff0c;如果整篇复制到Google翻译通常翻译出来的文本是没办法直接用的&#xff0c;所以我通过有道云API实现了一…

AIGC:【LLM(三)】——JARVIS:连接ChatGPT和HuggingFace解决AI问题

文章目录 0.摘要1.引言2.相关工作3.HuggingGPT3.1 任务规划3.2 模型选择3.3 任务执行3.4 响应生成 4.限制5.结论6.参考资料 0.摘要 解决具有不同领域和模态的复杂人工智能任务是通往人工通用智能的关键骤。尽管存在丰富的适用于不同领域和模态的人工智能模型&#xff0c;但它们…

Linux系统之iostat命令的基本使用

Linux系统之iostat命令的基本使用 一、iostat命令介绍二、iostat命令帮助1.1 iostat的帮助信息1.2 iostat的选项解释 三、iostat命令的基本使用3.1 查看iostat工具版本3.2 直接使用iostat命令3.3 间隔5秒查看3次信息3.4 只查看磁盘状态3.5 以k或M为单位显示信息 四、查看磁盘I/…

JMM 规范

JMM是Java Memory Model&#xff08;Java 内存模型&#xff09;的缩写&#xff0c;是Java虚拟机规范中定义的一套规则&#xff0c;用来规范Java程序在多线程环境下的内存访问方式。其主要作用是保证多线程之间的数据可见性、有序性和原子性。JMM规范定义了一些程序员和JVM实现者…

机器学习(ML)策略

目录 1、正交化的概念 2、单一数字评估指标&#xff08;Single number evaluation metric&#xff09; 3、训练/开发/测试集划分 4、迁移学习 5、多任务学习 6、端到端深度学习 1、正交化的概念 正交化是机器学习中一种常用的数据预处理技术&#xff0c;用于减少特征之间…

IMX6ull SPI 协议

一 SPI 简介 1.1 SPI SPI 全称是 Serial Perripheral Interface&#xff0c;也就是串行外围设备接口。 SPI 是 Motorola 公司推出的一种同步串行接口 技术&#xff0c;是一种高速、全双工的同步通信总线&#xff0c; SPI 时钟频率相比 I2C 要高很多&#xff0c;最高可以工作 …

【IT服务管理】MITRE :IT服务管理

定义&#xff1a; 信息技术 (IT) 服务管理 (ITSM) 是解决管理、支持和交付 IT 服务的最佳实践的框架、流程和模型的通用保护伞。IT 服务可能包括&#xff08;由 NIST 为云计算定义&#xff09;&#xff1a;软件即服务 (SaaS)、平台即服务 (PaaS) 和基础设施即服务 (IaaS)。 关键…