Wordless: 一个周末打造的小爆游戏

简介: Wordless 是一款类似 Wordle 的猜单词游戏,使用 Next.js 构建,支持 3 到 8 个字母的单词猜测,具备智能生成、实时反馈与丰富动画效果,技术上采用 React 18、TypeScript 与 Tailwind CSS,结构清晰、性能优化,适配多端,提供流畅用户体验。

这个项目是什么

Wordless就是个类似 Wordle 的猜单词游戏,用 Next.js 搭建的。玩家有 6 次机会猜出单词,支持 3 到 8 个字母的单词。说实话,开始只是想做点跟 wordle 不一样东西,没想到做着做着就越来越有意思了。
image.png

点击这里可以体验:https://wordless.online/

我用了一个周末把代码撸完以后,直接发布上线,也没怎么关注,没想到几个月过去了,这个小游戏的流量一直很稳定,有 50%的自然搜索,40%的直接访问流量,这可是个非常漂亮的流量数据呀。
image.png

用了什么技术

主要框架

  • React 18.3.1 - 没什么好说的,前端必备
  • Next.js 14.2.4 - 选它主要是因为 SSR 和 API 路由很方便
  • TypeScript - 虽然写起来麻烦点,但能避免很多低级错误
  • Tailwind CSS - 写样式贼快,不用想类名

UI 相关

  • Radix UI - 弹窗、通知这些组件用的,无障碍做得不错
  • Lucide React - 图标库,简洁好看
  • Canvas Confetti - 猜对了撒彩带的特效,挺有意思的

其他工具

  • SWR - 数据获取用的,缓存机制不错
  • Zod - 数据验证,比手写 if-else 强多了
  • nspell - 检查单词拼写是否正确

文件结构

wordlessgame/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── api/ # API 路由
│ │ │ ├── ai-completion/ # AI 辅助功能
│ │ │ ├── validate-word/ # 单词验证
│ │ │ └── words/ # 单词生成
│ │ ├── layout.tsx # 根布局
│ │ └── page.tsx # 主页面
│ ├── components/ # React 组件
│ │ ├── ui/ # 基础 UI 组件
│ │ ├── game-grid.tsx # 游戏网格
│ │ ├── key-board.tsx # 虚拟键盘
│ │ └── result-modal.tsx # 结果弹窗
│ ├── data/ # 静态数据
│ │ └── word-lists.ts # 单词词库
│ ├── lib/ # 工具函数
│ │ ├── api.ts # API 调用
│ │ └── utils.ts # 工具函数
│ ├── ai/ # AI 相关功能
│ └── styles/ # 样式文件
└── public/ # 静态资源

核心功能实现

  1. 游戏状态管理

游戏使用 React Hooks 管理复杂的状态:

// 主要状态
const [columns, setColumns] = useState(3); // 单词长度
const [gridContent, setGridContent] = useState([]); // 网格内容
const [currentCell, setCurrentCell] = useState(-1); // 当前输入位置
const [word, setWord] = useState(''); // 目标单词
const [matchResults, setMatchResults] = useState([]); // 匹配结果
const [cellMatchClasses, setCellMatchClasses] = useState([]); // 样式类

  1. 单词生成系统

采用优化的单词生成器,避免重复选择同一单词:

class WordGenerator {
private static instance: WordGenerator;
private readonly cache: Map = new Map();
private readonly usedIndices: Map> = new Map();
private readonly shuffledIndices: Map = new Map();

public getRandomWord(length: number): string {
// Fisher-Yates 洗牌算法确保随机性
// 避免重复选择相同单词
}
}

  1. 游戏逻辑算法
    const matchWord = (guessedWord: string, targetWord: string) => {
    const result = new Array(guessedWord.length).fill('X'); // X=不匹配
    const targetCounts = new Map();

    // 第一遍:标记完全匹配的字母
    for (let i = 0; i < guessedWord.length; i++) {
    if (guessedWord[i] === targetWord[i]) {
    result[i] = 'C'; // C=正确位置
    } else {
    targetCounts.set(targetWord[i]!, (targetCounts.get(targetWord[i]!) || 0) + 1);
    }
    }

    // 第二遍:标记位置错误的字母
    for (let i = 0; i < guessedWord.length; i++) {
    if (result[i] !== 'C') {
    const char = guessedWord[i]!;
    if (targetCounts.get(char)! > 0) {

     result[i] = 'P'; // P=位置错误
     targetCounts.set(char, targetCounts.get(char)! - 1);
    

    }
    }
    }

    return result;
    };

  2. 游戏网格组件

export function GameGrid({
gridContent,
columns,
currentCell,
cellMatchClasses,
flippingRows
}: GameGridProps) {
return (


{gridContent.map((content, index) => {
const matchClass = cellMatchClasses[index];
const isFlipping = flippingRows.has(Math.floor(index / columns));
    return (
      <div 
        className={cn(
          'w-14 h-14 flex items-center justify-center text-2xl font-bold rounded-md',
          matchClass === 'C' ? 'bg-green-500 text-white' : 
          matchClass === 'P' ? 'bg-yellow-500 text-white' : 
          matchClass === 'X' ? 'bg-zinc-400 text-white' : 'bg-white',
          isFlipping ? 'animate-flip' : ''
        )}
        style={
   {
          animationDelay: isFlipping ? `${(index % columns) * 100}ms` : '0ms'
        }}
      >
        {content}
      </div>
    );
  })}
</div>

);
}

  1. 虚拟键盘组件

使用 memo 优化渲染性能:

const KeyButton = memo(({
letter,
isMatched,
noMatched,
onClick
}: KeyButtonProps) => {
return (

);
});

数据结构

单词词库
词库按长度分类存储,每个长度包含 500+ 个单词:

export const WORD_LISTS: Record = {
3: ['ace', 'age', 'air', ...], // 500+ 三字母单词
4: ['able', 'acid', 'aged', ...], // 500+ 四字母单词
5: ['about', 'above', 'abuse', ...], // 500+ 五字母单词
6: ['abroad', 'accept', 'access', ...], // 500+ 六字母单词
7: ['abandon', 'ability', 'absence', ...], // 500+ 七字母单词
8: ['absolute', 'academic', 'accepted', ...] // 500+ 八字母单词
};

API 设计

Edge Runtime API
使用 Next.js Edge Runtime 提供快速的 API 响应:

export const runtime = 'edge';

export async function GET(request: NextRequest) {
// API 逻辑
return NextResponse.json({ data });
}

用户体验优化

  1. 动画效果
  • 卡片翻转动画:使用 CSS animate-flip 类
  • 按键反馈:按键按下时的视觉反馈
  • 胜利庆祝:使用 canvas-confetti 库
  1. 响应式设计
  • 移动端优化的键盘布局
  • 自适应网格大小
  • 触摸友好的交互
  1. 性能优化
  • 使用 React.memo 减少不必要的重渲染
  • useCallback 和 useMemo 优化函数和计算
  • 单词生成器的缓存机制

部署和 SEO

SEO 优化
export const metadata: Metadata = {
title: "Unlimited Wordless Online: Guess the Word in 6 Tries!",
description: "Wordless Online: Endless Word Challenges...",
keywords: "wordless,wordly, wordle, game, puzzle, word, words, letters, play, online, guess,unlimited",
};

分析工具

  • Google Analytics 用户行为追踪
  • 自定义事件追踪

开发工具

代码质量

  • ESLint - 代码规范检查
  • Prettier - 代码格式化
  • TypeScript - 类型安全

包管理

  • PNPM - 快速、节省磁盘空间的包管理器

游戏流程

  1. 初始化:选择单词长度(3-8个字母)
  2. 生成目标单词:从词库中随机选择
  3. 用户输入:通过虚拟键盘或物理键盘输入
  4. 验证输入:检查是否为有效单词
  5. 匹配算法:计算字母匹配情况
  6. 视觉反馈:显示颜色提示(绿色=正确位置,黄色=错误位置,灰色=不存在)
  7. 游戏结束:6次尝试后或猜中单词后结束
  8. 结果展示:显示结果弹窗和庆祝动画

特色功能

  1. 可变单词长度
    支持 3-8 个字母的单词,增加游戏难度选择

  2. 智能单词生成
    避免重复,确保每次游戏都有新鲜感

  3. 实时反馈
    即时的视觉和交互反馈,提升用户体验

  4. 无限游戏
    没有次数限制,可以连续游戏

  5. 响应式设计
    适配各种设备屏幕尺寸

技术亮点

  1. 现代化技术栈:使用最新的 React、Next.js 和 TypeScript
  2. 性能优化:多层次的性能优化策略
  3. 可维护性:清晰的代码结构和组件分离
  4. 用户体验:流畅的动画和交互效果
  5. 可扩展性:模块化设计便于功能扩展

总结
Wordless 是一款用现代 Web 技术打造的游戏,干净利落,跑得飞快,代码还容易维护。没堆花里胡哨的东西,但该有的全都有——好玩、流畅、写得明白。
欢迎来体验https://wordless.online/

相关文章
|
移动开发 算法 调度
【贪心算法】一文让你学会“贪心”(贪心算法详解及经典案例)
贪心算法是一种非常常见的算法,它的简单和高效性使其在实际应用中被广泛使用。 贪心算法的核心思想是在每一步都采取当前状态下最优的选择,而不考虑未来可能产生的影响。虽然贪心算法不能保证总是得到最优解,但在很多情况下,它可以获得很好的结果。 本篇文章将介绍贪心算法的基本概念和一些经典应用,以及如何通过贪心算法来解决一些实际问题。希望通过本文的阅读,读者可以对贪心算法有更加深刻的理解,并能够在实际问题中应用贪心算法来得到更好的解决方案。 让我们暴打贪心算法吧!
7064 0
【QT】创建、打开QT项目只显示.pro文件的问题解决
【QT】创建、打开QT项目只显示.pro文件的问题解决
4729 0
|
2月前
|
存储 弹性计算 人工智能
阿里云服务器购买价格参考:特惠款价格与活动价2000至3000元云服务器实例配置和价格
2026年阿里云特惠款云服务器价格,入门级轻量应用服务器2核2G低至38元/年,2核4G仅9.9元/月;ECS经济型e实例99元/年、u1实例199元/年,均支持续费同价。预算2000-3000元可选经济型e(4核8G/16G)、通用算力型u2i(最高4核32G)、九代计算型c9i/通用型g9i/内存型r9i等,覆盖计算、内存、均衡等多种场景。选购需关注新用户限制、续费政策,建议先领优惠券再下单,实现性能与成本最优平衡。
|
3月前
|
存储 弹性计算 运维
阿里云服务器怎么买?四种主要方式详解+注意事项,新手购买参考教程
本文介绍了阿里云服务器的四大购买方式的适用场景与注意事项:自定义购买支持全参数精细配置,适合有技术基础的企业用户;快速购买通过预设模板简化流程,助力新手快速上云;活动购买提供低至38元/年的限时优惠,覆盖99计划、学生300元抵扣金、百炼先用后返等多重权益;云市场镜像购买提供预装环境的开箱即用方案,适合中小企业快速建站。
|
9月前
|
存储 人工智能 算法
超酷!用Python写回文音乐,3步搞定你的MIDI创作处女作
用Python将数学回文结构融入MIDI音乐创作,无需乐理基础,30分钟即可生成正反皆同的对称旋律。结合mido与pretty_midi库,实现从算法作曲到多声部合成的完整流程,让代码奏响艺术与科技交融的数字交响。
520 0
|
5月前
|
存储 人工智能
2026年阿里云AI采购季活动参考:1元域名注册,9.9元AI建站,9折备案
阿里云2026年AI采购季活动涵盖域名注册、智能建站、备案服务及企业邮箱。活动包括1元热门域名限时特惠、9.9元AI建站、备案服务9折等。万小智AI建站15元/首月,购建站赠.CN域名。阿里邮箱提供标准版、AI尊享版、国产化版,新人首购低至5折。活动还包含个人及企业用户优惠券、低至9.9元的OpenClaw部署及百炼大模型服务节省计划。
1502 2
|
Web App开发 网络协议 应用服务中间件
HTTP2.0 从原理到实践,保证把你治得服服帖帖!
HTTP/2 是 HTTP/1.1 的重要升级,通过多路复用、头部压缩、服务器推送等特性显著提升性能与效率。本文详细解析了 HTTP/2 的优势、配置方法及实际应用,涵盖 Nginx/Apache/IIS 配置、curl 测试工具使用,并对比 HTTP/1.1 指出其优化点。同时提醒需注意 HTTPS 支持、客户端兼容性等问题,助你高效掌握并运用 HTTP/2 技术。
1253 5
HTTP2.0 从原理到实践,保证把你治得服服帖帖!
|
安全 Java 编译器
JD-GUI,java反编译工具及原理: JavaDecompiler一个Java反编译器
Java Decompiler (JD-GUI) 是一款由 Pavel Kouznetsov 开发的图形化 Java 反编译工具,支持 Windows、Linux 和 Mac Os。它能将 `.class` 文件反编译为 Java 源代码,支持多文件标签浏览、高亮显示,并兼容 Java 5 及以上版本。JD-GUI 支持对整个 Jar 文件进行反编译,可跳转源码,适用于多种 JDK 和编译器。其原理基于将字节码转换为抽象语法树 (AST),再通过反编译生成代码。尽管程序可能带来安全风险,但可通过代码混淆降低可读性。最新版修复了多项识别错误并优化了内存管理。
10969 1
|
Windows
Windows系统命令dir使用详解
Windows系统命令dir使用详解
2882 2
|
Dubbo 网络协议 Java
RPC框架:一文带你搞懂RPC
这篇文章全面介绍了RPC(远程过程调用)的概念、原理和应用场景,解释了RPC如何工作以及为什么在分布式系统中广泛使用,并探讨了几种常用的RPC框架如Thrift、gRPC、Dubbo和Spring Cloud,同时详细阐述了RPC调用流程和实现透明化远程服务调用的关键技术,包括动态代理和消息的编码解码过程。
RPC框架:一文带你搞懂RPC