智胜面试挑战:融合冯·诺依曼智慧,创新构建趣味猜拳游戏互动体验
前言
在数字世界的浩瀚里,游戏不仅是娱乐的载体,也是智慧碰撞的火花。本篇前言,旨在借由冯·诺依曼架构的精妙逻辑,揭开一场别开生面的猜拳对决序幕。冯·诺依曼原理,作为现代计算机体系的基石,其核心在于程序与数据共存的存储理念,恰似猜拳游戏中策略与随机性的交织舞蹈。在这场思维的较量中,人机互动不仅模拟了古老游戏的趣味,更展现了智能时代对传统的一次温馨致敬。接下来让我们运用冯诺依曼原理,设置一个电脑与人类的猜拳小游戏吧。
1.冯诺依曼原理
冯·诺依曼原理,全称作冯·诺伊曼体系结构(Von Neumann architecture),是由著名美籍匈牙利数学家约翰·冯·伊曼(John von Neumann)在1940年代提出的一种计算机设计模型。这一原理奠定了现代计算机体系结构的基础,至今仍被广泛应用。冯·诺伊曼原理主要包括以下几个关键要素:
- 存储程序概念:** 这是冯·诺曼原理的核心,即计算机的指令(程序)和数据被一并存储在同一个地址空间内存储器中。这意味着计算机可以自动地读取指令并执行它们,无需人工逐条干预。
- 二进制:计算机内部操作基于二制,所有数据和指令都以0和1的形式表示。这简化了设计,因为二制易于电子元件实现逻辑运算。
- 控制器:负责从存储器中读取指令,解码并执行。根据指令内容决定计算机的下一步动作,如算术操作或数据传输。
- 运算器:执行算术和逻辑运算,如加减乘除、除、比较等,是计算机处理数据的核心部分。
- 存储器:存储器,包括内存和外存。内存(RAM)暂时存储程序运行时需要的数据和指令;外存(如硬盘)则永久保存长期信息。
- 输入设备:如键盘、鼠标,用于将外部信息传递给计算机。
- 输出设备:屏幕、打印机等,展示计算机处理的结果。
2.代码实现
我们先上代码
// console.log('aaa');
// - 冯诺依曼
// - 获得用户的输入
// 后端的进程对象 程序运行的最小单元
// process 进程对象
// 冯诺依曼计算设备 process 对象 .输入设备
// on data 监听输入事件 enter
/**
* @func 根据用户的输入,输出胜或赢
* @return win/lose
*/
const game = (action) => {
const arr = ['rock', 'scissor', 'paper']
// 输入的校验
if (arr.indexOf(action) == -1) {
throw new Error('用户输入错误')
}
let computerAction
let random = Math.floor(Math.random() * 3)
computerAction = arr[random]
console.log('电脑出了' + computerAction)
if (computerAction == action) {
console.log('平局')
return 0 // 平局
} else if ((computerAction == 'rock' && action == 'scissor') ||
(computerAction == 'scissor' && action == 'paper') ||
(computerAction == 'paper' && action == 'rock')
) {
console.log('你输了')
return -1
} else {
console.log('你赢了')
return 1
}
}
let winCount = 0
process.stdin.on('data', (buffer) => {
// 存储和通信的底层是二进制
// console.log(buffer)
const action = buffer.toString().trim()
// console.log(action, '--------')
// 独立的随机出拳业务
const result = game(action)
if (result == 1) {
winCount++
if (winCount == 3) {
console.log('不玩了')
process.exit()
}
}
})
2.1代码细节
- 冯·诺曼体系:代码中,程序逻辑(如游戏规则、胜负判断)与数据(用户输入、随机选择)均存储在同一内存中,通过
process.stdin.on('data', ...)
监听输入,`处理用户数据。 - 用户交互: 使用
process.stdin.on('data', ...)
监听标准输入流事件,用户每按回车键入命令行输入。 - 转换处理: 将接收到的二进制数据
buffer
toString()转字符串,并去掉首尾空白
trim()`。 - 游戏逻辑:
game
函数根据用户和电脑选择判断结果,返回输赢(-1)、平(0)、赢(1)。 - 胜利计数
winCount
累计用户胜利次数,若达到3则提示并process.exit()
退出程序。
2.2代码要点
- 全局作用域污染:
game
函数和winCount
变量都是在全局作用域定义的。在大型项目中,这可能会导致变量名冲突。考虑使用立即执行的函数表达式或者模块模式来封装它们。 - 异常处理:在
game
函数中,通过抛出错误来处理无效的用户输入。然而,在实际的命令行应用中,直接抛出错误可能不是最友好的用户体验。可以考虑捕获这个错误并给出友好提示后继续运行程序。 - 编码风格:代码风格较为紧凑,虽然能减少篇幅,但不利于阅读和维护。例如,增加空格和换行来区分逻辑块,使得代码更加清晰。
- 注释:虽然代码上方有一段JSDoc风格的注释说明函数用途和返回值,但函数内部缺乏注释,尤其是逻辑判断部分。对关键逻辑和边界条件添加注释有助于理解代码意图。
- 输入处理:
process.stdin.on('data', ...)
监听用户输入,buffer.toString().trim()
转换并去除首尾空白字符。这里假设用户总是正确输入,实际上应加入更多输入验证,比如确保用户输入的确实是预设选项之一。 - 递归调用与退出:当用户连续赢得三次游戏时,通过
process.exit()
终止程序。这是一种快速退出方式,但在某些情况下可能不是最优雅的退出策略,比如没有给其他清理工作(如关闭文件句柄)的机会。 - 异步处理:虽然此脚本主要基于同步逻辑,但考虑到Node.js偏向于异步操作,未来扩展功能时注意异步流程控制,如使用Promise或async/await。
运行结果
PS C:\Users\86150\Desktop\fullstuck_ai\node\game> node index.js
paper
电脑出了paper
平局
paper
电脑出了rock
你赢了
paper
电脑出了paper
平局
paper
电脑出了paper
平局
paper
电脑出了rock
你赢了
paper
电脑出了scissor
你输了
paper
电脑出了rock
你赢了
不玩了
最后会退出进程,到此我们就圆满结束啦!
转载自:https://juejin.cn/post/7371716394302357542