零基础鸿蒙应用开发第九节:流程控制综合练习

零基础鸿蒙应用开发第九节:流程控制综合练习 【学习目标】吃透嵌套循环的核心逻辑行/列控制能独立实现杨辉三角、99乘法表的算法掌握猜数字游戏的核心规则随机数生成、输入校验、次数控制、分支判断、游戏终止逻辑理解二维数组的初始化、赋值与遍历解决杨辉三角这类结构化数据存储问题掌握输入校验的三层过滤逻辑空值、类型、范围提升程序健壮性掌握字符串格式化技巧对齐、填充优化控制台输出可读性【学习重点】嵌套循环外层控“整体结构行”内层控“局部细节列”输入校验isNaN()判断数字合法性 范围边界判断拦截非法输入二维数组杨辉三角的核心数据结构重点掌握“上一行数据复用”生成当前行分支判断猜数字游戏的多状态猜大/猜小/猜对/次数用尽逻辑闭环状态控制通过布尔变量如isGameOver控制流程启停避免无效操作一、工程结构本节我们将创建名为ArkTSFunPractice的工程基于鸿蒙5.0API12开发使用DevEco Studio 6.0工具项目结构目录如下ArkTSFunPractice/ ├── AppScope # 应用全局配置 ├── entry/ │ ├── src/ │ │ ├── main/ │ │ │ ├── ets/ │ │ │ │ ├── entryability/ # 应用入口 │ │ │ │ │ └── EntryAbility.ets │ │ │ │ ├── pages/ # 页面代码 │ │ │ │ │ └── Index.ets # 核心页面猜数字游戏完整代码 │ │ │ │ └── utils/ # 纯逻辑工具函数 │ │ │ │ └── TableLogic.ets # 杨辉三角99乘法表逻辑 │ │ │ ├── resources/ # 资源文件默认生成无需修改 │ │ │ └── module.json5 # 模块配置默认生成无需修改二、案例解析案例1猜数字游戏以下是猜数字游戏的纯逻辑代码实现“随机数生成→输入校验→次数控制→分支判断→游戏终止”的完整规则闭环// 游戏核心状态lettargetNumber:numbergenerateRandomNumber();// 目标数字1-100letuserInput:string;// 用户输入的字符串letguessCount:number0;// 已猜次数letmaxAttempts:number10;// 最大尝试次数letmessage:string请输入1-100之间的数字开始游戏;// 提示信息lethistory:string[][];// 历史记录letisGameOver:booleanfalse;// 游戏是否结束// 1. 生成1-100的随机数核心算法functiongenerateRandomNumber():number{returnMath.floor(Math.random()*100)1;// 关键1 避免生成0保证范围1-100}// 2. 重置游戏状态重置逻辑functionresetGame(){targetNumbergenerateRandomNumber();// 重新生成答案userInput;// 清空输入缓存guessCount0;// 重置次数message游戏已重置请重新输入1-100之间的数字;history[];// 清空历史记录isGameOverfalse;// 激活游戏流程}// 3. 猜数字核心逻辑核心规则实现functionhandleGuess(){// 前置拦截游戏结束后拒绝处理新猜测if(isGameOver)return;// 输入校验三层过滤核心健壮性保障constguessNumber(userInput);if(isNaN(guess)||guess1||guess100){message请输入有效的1-100之间的数字;console.log([猜数字游戏],message);// 替代UI提示控制台输出return;}// 次数计数每提交一次猜测次数1guessCount;constremainingmaxAttempts-guessCount;// 计算剩余次数constrecord第${guessCount}次${guess};// 构建历史记录模板// 核心分支判断根据猜测值与目标值的关系更新状态if(guesstargetNumber){message猜大了还剩${remaining}次机会;history.unshift(${record}→ 猜大了);}elseif(guesstargetNumber){message猜小了还剩${remaining}次机会;history.unshift(${record}→ 猜小了);}else{// 猜对终止游戏流程message恭喜你猜对了答案就是${guess}共猜了${guessCount}次;history.unshift(${record}→ 猜对了);isGameOvertrue;console.log([猜数字游戏],message);return;// 猜对后直接退出避免后续次数用尽判断}// 次数用尽终止游戏流程if(remaining0){message游戏结束正确答案是${targetNumber};history.unshift(次数用尽 → 正确答案${targetNumber});isGameOvertrue;}// 输出本次操作结果console.log([猜数字游戏],message);// 清空输入缓存准备下一次输入userInput;}// 测试示例控制台运行可选// userInput 50; handleGuess(); // 模拟输入50并提交// userInput 80; handleGuess(); // 模拟输入80并提交// resetGame(); // 重置游戏关键逻辑要点逻辑模块核心作用关键代码/规则随机数生成确定游戏唯一答案Math.floor(Math.random() * 100) 11是核心保证1-100范围输入校验拦截非法输入避免程序异常isNaN(guess)判断数字合法性 guess 1次数控制限制游戏次数控制流程节奏guessCount计数 remaining maxAttempts - guessCount计算剩余次数分支判断实现游戏核心规则猜大/猜小更新提示历史猜对/次数用尽设置isGameOver true终止游戏状态重置支持游戏重新开始所有变量恢复初始值且重新生成随机数⚠️ 易错点随机数范围错误漏写1导致生成0-99的数字不符合1-100的规则未拦截游戏结束状态isGameOver为true时仍执行猜数字逻辑导致次数异常增加输入校验遗漏未判断isNaN(guess)用户输入非数字时会导致后续比较逻辑出错猜对后未提前退出猜对后仍执行后续的次数用尽判断可能覆盖正确提示。案例2杨辉三角嵌套循环二维数组纯逻辑实现杨辉三角的生成与控制台格式化输出核心是“二维数组存储嵌套循环生成边界规则上一行数据复用”/** * 杨辉三角生成逻辑 * param rowCount 生成行数默认10行 */exportfunctiontestYanghuiTriangle(rowCount:number10){// 输入校验限制行数范围非法值兜底健壮性设计if(isNaN(rowCount)||rowCount1||rowCount20){rowCount10;console.log([testYanghuiTriangle] 输入行数非法默认显示10行);}console.log(\n 杨辉三角${rowCount}行 );// 二维数组存储杨辉三角的所有行数据lettriangle:number[][][];// 外层循环控制生成的总行数行索引从0开始for(letrowIdx:number0;rowIdxrowCount;rowIdx){letcurrentRow:number[][];// 临时存储当前行的元素// 内层循环控制当前行的元素个数列索引≤行索引保证第n行有n1个元素for(letcolIdx:number0;colIdxrowIdx;colIdx){// 边界规则每行第一个/最后一个元素固定为1if(colIdx0||colIdxrowIdx){currentRow.push(1);}else{// 核心算法中间元素 上一行的当前列-1元素 上一行的当前列元素constprevRow:number[]triangle[rowIdx-1];currentRow.push(prevRow[colIdx-1]prevRow[colIdx]);}}triangle.push(currentRow);// 将当前行存入二维数组}// 格式化输出控制台可视化非核心逻辑triangle.forEach((row:number[],index:number){constspaceCount:number(rowCount-index-1)*2;constrowStr:stringrow.join( );// 由于空格无法被打印用*占位console.log(*.repeat(spaceCount)rowStr);});}关键逻辑要点逻辑模块核心作用关键代码/规则输入校验避免非法行数导致逻辑异常isNaN(rowCount)二维数组初始化存储结构化的杨辉三角数据triangle: number[][] []定义二维数组currentRow: number[] []初始化当前行外层循环控制总行数rowIdx从0到rowCount-1逐行生成内层循环控制每行元素数colIdx从0到rowIdx保证第n行有n1个元素边界规则杨辉三角基础规则colIdx 0中间元素计算杨辉三角核心算法prevRow[colIdx - 1] prevRow[colIdx]复用上一行数据⚠️ 易错点二维数组行未初始化直接给triangle[rowIdx][colIdx]赋值未先创建currentRow导致数组越界内层循环条件错误写成colIdx rowCount导致每行元素数超出正确应为colIdx rowIdx中间元素计算错误误用当前行数据triangle[rowIdx][colIdx - 1]而非上一行prevRow行索引理解错误忘记rowIdx从0开始导致行数少生成1行。案例399乘法表嵌套循环格式化纯逻辑实现两种样式的99乘法表核心是“嵌套循环控制行/列组合字符串格式化保证输出对齐”/** * 99乘法表生成 */exportfunctiontestMultiplicationTable(){console.log(\n 99乘法表直角三角形版 );for(leti:number1;i9;i){// 外层控制乘数行letline:string;// 内层控制被乘数列仅到当前行避免1×2和2×1重复for(letj:number1;ji;j){line${j}×${i}${j*i}\t;// \t制表符保证元素对齐}console.log(line);}}⚠️ 易错点内层循环条件错误写成j 9导致生成完整矩形而非三角格式化对齐遗漏未用\t或padEnd导致输出内容参差不齐循环变量混淆将乘数和被乘数搞反如i×j写成j×i不影响结果但不符合常规展示习惯三、完整代码示例// UI内容本阶段不学习重点掌握代码程序逻辑基础。import{promptAction,router}fromkit.ArkUIimport{testYanghuiTriangle,testMultiplicationTable}from../utils/TableLogic;EntryComponentstruct Index{// 游戏核心状态State 感知数据变化刷新UIStatetargetNumber:numberthis.generateRandomNumber()// 目标数字1-100StateuserInput:string// 用户输入的字符串StateguessCount:number0// 已猜次数StatemaxAttempts:number10// 最大尝试次数Statemessage:string请输入1-100之间的数字开始游戏// 提示信息Statehistory:string[][]// 历史记录StateisGameOver:booleanfalse// 游戏是否结束// 页面加载时执行杨辉三角和乘法表逻辑控制台输出aboutToAppear(){testYanghuiTriangle();testMultiplicationTable();}// 生成1-100的随机数generateRandomNumber():number{returnMath.floor(Math.random()*100)1;}// 重置游戏resetGame(){this.targetNumberthis.generateRandomNumber();this.userInput;this.guessCount0;this.message游戏已重置请重新输入1-100之间的数字;this.history[];this.isGameOverfalse;}// 处理猜数字逻辑handleGuess(){if(this.isGameOver)return;constguessNumber(this.userInput);if(isNaN(guess)||guess1||guess100){this.message请输入有效的1-100之间的数字;promptAction.showToast({message:this.message});return;}this.guessCount;constremainingthis.maxAttempts-this.guessCount;constrecord第${this.guessCount}次${guess};if(guessthis.targetNumber){this.message猜大了还剩${remaining}次机会;this.history.unshift(${record}→ 猜大了);}elseif(guessthis.targetNumber){this.message猜小了还剩${remaining}次机会;this.history.unshift(${record}→ 猜小了);}else{this.message恭喜你猜对了答案就是${guess}共猜了${this.guessCount}次;this.history.unshift(${record}→ 猜对了);this.isGameOvertrue;return;}if(remaining0){this.message游戏结束正确答案是${this.targetNumber};this.history.unshift(次数用尽 → 正确答案${this.targetNumber});this.isGameOvertrue;}this.userInput;}build(){Column(){// 游戏标题Text(猜数字小游戏).fontSize(24).fontWeight(FontWeight.Bold).margin(20).onClick((){router.push({url:pages/nextPage})})// 游戏规则Text(规则猜1-100之间的数字共${this.maxAttempts}次机会).fontSize(14).fontColor(#666).margin({bottom:20})// 输入区域Row(){TextInput({placeholder:请输入数字,text:this.userInput}).type(InputType.Number)// 限制为数字输入.width(200).height(40).border({width:1}).padding(5).onChange((value)this.userInputvalue)Button(猜一下).width(100).height(40).margin({left:10}).onClick(()this.handleGuess())}.margin({bottom:20})// 提示信息Text(this.message).fontSize(16).fontColor(this.isGameOver?#e53935:#2e7d32).margin({bottom:10})// 历史记录Text(历史记录).fontSize(16).fontWeight(FontWeight.Medium).margin({bottom:5,top:10})Scroll(){Column(){ForEach(this.history,(item:string){Text(item).fontSize(14).margin(2).fontColor(#555)})}}.height(200).width(100%).border({width:1,style:BorderStyle.Dashed}).padding(5)// 重置按钮Button(重新开始).width(150).height(40).margin({top:20}).backgroundColor(#42a5f5).onClick(()this.resetGame())}.width(100%).height(100%).padding(15).backgroundColor(#f5f5f5)}}运行结果四、内容总结1. 逻辑核心回顾猜数字游戏核心是随机数生成输入校验次数控制分支判断状态终止重点掌握“三层输入过滤”和“游戏状态闭环”杨辉三角核心是二维数组嵌套循环边界规则上一行数据复用重点掌握“中间元素的计算逻辑”99乘法表核心是嵌套循环的行/列控制重点是j i避免重复。2. 通用逻辑技巧输入校验优先任何接收外部输入的逻辑先做合法性校验再处理核心规则嵌套循环分层外层控“行/整体”内层控“列/细节”避免层级超过2层状态控制闭环用布尔变量如isGameOver控制流程启停避免无效操作数据结构匹配场景结构化数据如杨辉三角用二维数组线性数据如历史记录用一维数组。五、代码仓库工程名称ArkTSFunPractice仓库地址https://gitee.com/juhetianxia321/harmony-os-code-base.git六、下节预告本节我们学习了猜数字小游戏、杨辉三角、九九乘法表的实现逻辑对之前所学知识做了一次系统巩固但还留下了关键的知识伏笔。在逻辑与运算章节中我们发现0.1 0.2 0.30000000000000004而非预期的 0.3当时仅知晓是浮点数精度问题未深究底层原因。下一节我们将进入一个重要的知识分支——计算机底层进制与编码原理核心学习掌握二进制、八进制、十进制、十六进制的定义以及在ArkTS中的表示方法与相互转换技巧理解位bit、字节Byte、半字节Nibble的核心概念以及它们之间的换算关系彻底搞懂ASCII码的本质、表示形式以及在ArkTS中的实际应用场景掌握二进制科学计数法的规范化表示为后续学习浮点数存储标准IEEE 754打下基础建立“计算机所有数据均以二进制存储”的核心认知理解整数、浮点数的存储本质揭开“0.1 0.2 ≠ 0.3”的底层奥秘。通过下一节的学习你将打通计算机底层存储的基础逻辑为后续深入理解数据类型、数值运算精度、编码转换等知识点提供关键支撑让编程思维从“表面应用”深入到“底层原理”。