前言
- 基于冯诺依曼原理, 编写石头剪刀布的游戏
在这篇文章中我们将介绍使用冯诺依曼原理来编写石头剪刀布游戏
冯诺依曼原理中的 计算机组成:冯·诺依曼架构认为计算机应由五大基本部件组成,包括:
- **运算器**(Arithmetic Unit):负责执行算术和逻辑运算。
- **控制器**(Control Unit):负责协调各部件工作,解读并执行存储在内存中的指令。
- **存储器**(Memory):用于存储程序和数据,程序指令和数据以相同的二进制形式存储。
- **输入设备**(Input Devices):用于向计算机输入数据和指令。
- **输出设备**(Output Devices):用于展示计算机处理结果。
我们要想完成这个游戏则需要这几个步骤:
输入
玩家输入他们的选择(石头、剪刀或布),并从计算机生成一个随机选择。
处理
程序对输入进行验证,比较玩家和计算机的选择,确定游戏结果,即如何判定胜负呢?
输出
程序输出结果,告诉玩家他们是赢了、输了还是平局。
那么我们该如何完成输入与输出.......
正文
这个代码片段是在Node.js中使用process.stdin
来读取标准输入的数据:
process.stdin.on('data', (buffer) =>{
const action = buffer.toString();
console.log(action,'------');
})
这段代码是使用Node.js编写的,它用于处理标准输入(stdin)的事件。在Node.js环境中,process
是一个全局对象,提供了与当前Node.js进程相关的各种属性和方法,其中包括对标准输入、输出的支持的作用是持续监听控制台的输入,一旦有输入内容,就将其打印出来,常用于构建需要接收用户命令行输入的简单交互式程序。
- 在理解输入部分后我们开始看看输入部分的代码
const game = (action) => {
const arr = ['rock', 'scissor', 'paper'];
console.log(action);
// 输入校验
if (arr.indexOf(action) == -1) {
throw new Error('用户输入错误');
}
这段代码定义了一个名为game
的函数,它接受一个参数action
,用于模拟实现石头、剪刀、布游戏中对用户输入的处理逻辑。
-
函数定义:
const game = (action) => { ... }
定义了一个箭头函数,名为game
,它接收一个参数action
,这个参数代表玩家的选择(石头、剪刀或布)。 -
定义选项数组:
const arr = ['rock', 'scissor', 'paper'];
创建了一个数组arr
,其中包含了游戏的所有有效选项——石头(rock)、剪刀(scissor)和布(paper)。 -
输入校验:
if (arr.indexOf(action) == -1) { ... }
通过检查action
在数组arr
中的索引来判断玩家的输入是否有效。arr.indexOf(action)
返回action
在数组中的索引,如果不存在则返回-1。- 如果
action
不在arr
中(即indexOf
结果为-1),则执行throw new Error('用户输入错误');
抛出一个错误,错误信息是'用户输入错误',意味着玩家输入了无效的选项,比如"lizard"或"spock",或者拼写错误等。
然后我们就可以在控制台看见我们输入的'rock', 'scissor', 'paper'都能被打印出来。那么我们就要进行到下一步,如何让电脑来判定胜负呢?
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 computerAction;
声明一个变量用于存储电脑的选择。 -
随机选择:
let random = Math.floor(Math.random() * 3);
这行代码生成一个0到2之间的随机整数,用于从arr
数组中随机选择一个动作。Math.random()
生成0到1之间的随机数,乘以3后范围变为0到3之间,但不包括3。Math.floor()
函数则向下取整,确保结果为0、1或2。computerAction = arr[random];
根据随机数从数组arr
中选择电脑的动作。
-
判断胜负逻辑:
- 平局: 如果
computerAction
和action
相等,即玩家和电脑出的一样,输出'平局',函数返回0。 - 玩家输: 通过一系列条件判断(例如:电脑出石头玩家出剪刀,电脑出剪刀玩家出布,电脑出布玩家出石头),如果玩家输,输出'你输了',函数返回-1。
- 平局: 如果
-
- 在完成判定胜负代码后,我们如何对胜利次数进行记录并累计,最后通过3局两胜来判定输赢呢?
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();
}
}
})
-
初始化胜利计数器:
let winCount = 0;
初始化一个变量用于记录玩家获胜的次数。 -
监听标准输入:
process.stdin.on('data', ...)
监听来自标准输入(通常是键盘输入)的数据事件。当用户在命令行输入内容并按下回车键时,这段代码会执行。 -
处理用户输入:
const action = buffer.toString().trim();
将接收到的二进制数据转换为字符串,并去除首尾空白字符。这里假设用户输入的是游戏中的一个合法动作:"rock"、"paper"或"scissor"。- 紧接着调用
game(action)
函数来处理这一轮的游戏逻辑,这个函数应该就是您之前提供的那段代码所定义的,它接收用户的选择作为参数,然后根据游戏规则返回游戏结果(-1表示输,0表示平局,1表示赢)。
-
根据游戏结果更新胜利计数并判断是否结束游戏:
- 如果
result == 1
,说明玩家赢得了这一轮,于是增加winCount
的值。 - 当
winCount
达到3时,输出'不玩了',并调用process.exit();
结束当前进程,也就是结束了整个游戏。
- 如果
这个程序构建了一个简单的交互式"石头、剪刀、布"游戏,用户通过命令行输入他们的选择,程序会根据游戏规则判断结果,并在用户连续赢得三场后自动结束游戏。
结语
通过本篇文章的逐步解析与实践,我们不仅重温了冯·诺依曼架构这一计算机科学基石的重要性,还亲手构建了一个趣味横生的石头、剪刀、布游戏。在这个过程中,从玩家输入的捕获、游戏逻辑的精密判断,到胜利条件的追踪与游戏终止的自动化处理,每一步都直观映射了计算机系统的基本组成部分及其协作方式。
更重要的是,这个简短的编程之旅揭示了技术背后的人文情怀——即使是最基本的架构原则,也能激发无限创意,带来欢乐与思考。