使用冯诺依曼原理,编写一个石头剪刀布小游戏
前言
今天我们将讲解冯诺依曼原理,然后基于这个原理去从零开始编写一个石头剪刀布小游戏
欢迎大家和我一起去尝试!!!
效果展示
冯诺依曼原理
-
存储程序概念:
- 程序和数据都存储在计算机的存储器中,它们被同等对待,都可以被读取和修改。
- 这意味着计算机可以自动地从存储器中读取程序并执行,而无需人工干预。
-
程序控制:
- 计算机的执行流程是由存储在存储器中的程序控制的,程序是一系列指令的集合。
- 计算机能够自动地从存储器中取出指令并执行,然后继续执行下一条指令,直到程序结束或遇到特定的控制指令。
-
二进制系统:
- 所有的信息,无论是程序还是数据,都被表示为二进制数字(0和1),这是计算机硬件层面的基础。
-
计算机的主要组成部分:
- 运算器(Arithmetic Logic Unit, ALU) :负责执行算术和逻辑运算。
- 控制器(Control Unit, CU) :管理指令的执行顺序,控制数据的流动。
- 存储器(Memory) :存储程序和数据,可以快速访问。
- 输入设备(Input Devices) :如键盘、鼠标,用于向计算机输入数据。
- 输出设备(Output Devices) :如显示器、打印机,用于显示或输出数据。
-
指令格式:
- 指令通常由操作码(表明要执行的操作类型)和地址码(指出操作数的位置)组成。
冯诺依曼原理描述的计算机架构至今仍然是大多数通用计算机的基础
游戏实现
既然是使用冯诺依曼原理做游戏
- 输入设备
我们肯定是需要通过输入设备去获取我们的输入内容
这我们就需要借助node去访问输入设备
在后端,进程是程序运行的最小单元,进程为程序的运行提供了独立的内存空间和资源环境
每个进程都可以包含一个或多个线程
线程是进程中的一个执行单元。线程共享所属进程的资源,包括内存、文件描述符等。线程之间的切换开销通常比进程切换小,因此能更高效地利用系统资源
当程序运行时,我们就能process拿到他的进程运行对象
process.stdin.on('data', (buffer) =>{
const action = buffer.toString()
console.log(action,'------');
})
可以看到运行这段代码,程序将会等待用户的输入

在用户输入以后就会打印出来用户输入的内容
process进程对象是运行在冯诺依曼计算设备的,stdin可以访问在这个进程对象的输入设备
.on data就是去监听输入事件,当你去enter以后就会去调用回调函数
可以知道我们写的代码就是需要放到进程里面去运行的
在代码中的buffer其实是一个二进制数据,通过buffer.toString(),就可以将二进制变为更加高级的字符串
在计算机的世界里,存储和通信都是二进制的
- 输出设备
我们还需要一个输出设备,输出设备将内容输出到命令行中
console.log('输出')
- 运算、存储、控制都是交给计算机
接下来我们就开始去编写业务逻辑了
在我们拿到用户输入的数据以后,我们就需要将这个数据交给一个方法,让他去判断我们是否战胜电脑
所以我们单独的去封装一个函数用于处理这方面的逻辑处理,这里体现了一个封装的思想
具体流程为:
- 初始化游戏选项数组:
const arr = ['rock', 'paper', 'scissors'];
这个数组包含了游戏的三个可能选项。 - 验证输入: 使用
indexOf
方法检查action
是否是arr
数组中的有效选项。如果不是,抛出一个错误。 - 生成电脑选择: 使用
Math.random()
生成一个介于0到1之间的随机数,然后将其乘以3,并向下取整得到0, 1, 或者2这三个可能的结果之一。这个结果用作arr
数组的索引,从而决定电脑的选择。 - 比较玩家和电脑的选择: 根据“石头、剪刀、布”的规则判断胜负。如果两者相同,则返回
0
表示平局;如果玩家赢了,返回1
;如果电脑赢了,返回-1
。
const game = (action) => {
const arr = ['rock', 'paper', 'scissors'];
// 判断输入是否合法
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) {
return 0; //平局
} else if (
(action == 'rock' && computerAction == 'scissors')
|| (action == 'paper' && computerAction == 'rock')
|| (action == 'scissors' && computerAction == 'paper')) {
return 1; // 你赢了
} else {
return -1;// 你输了
}
}
主方法通过调用这个歌函数就可以得到结果,0为平局、1为胜利、2为失败
接下来我们就需要通过这个返回结果去向用户输出对应的结果了
-
初始化胜局和败局计数器:
let winCount = 0; let loseCount = 0;
这里声明了两个变量
winCount
和loseCount
,分别用来记录玩家的胜利次数和失败次数。 -
监听标准输入流:
process.stdin.on('data', (buffer) => { // ... });
这段代码监听
process.stdin
(标准输入流),当有数据输入时,会触发回调函数。通常,这可以接收从用户键盘输入的数据。 -
解析输入缓冲区并调用游戏函数:
const action = buffer.toString().trim(); const result = game(action);
当有数据输入时,
buffer
是一个Buffer对象,需要转换成字符串并通过trim()
方法去除两端空白字符。然后,将玩家的选择传递给game
函数,获取游戏结果。 -
处理游戏结果:
if (result == 0) { console.log('平局'); } else if (result == 1) { console.log('你赢了'); winCount++; } else { console.log('你输了'); loseCount++; }
根据游戏函数返回的结果,输出相应的信息,并更新胜局和败局计数器。
-
检查胜败条件:
if (winCount == 3) { console.log('恭喜你,你先赢了3局,获得胜利!'); process.exit(); } if (loseCount == 3) { console.log('很遗憾,电脑先赢了3局,你失败了!'); process.exit(); }
如果玩家或电脑赢得三局,游戏结束,并输出相应的消息,然后使用
process.exit()
终止程序执行。
主函数完整代码:
let winCount = 0;
let loseCount = 0;
process.stdin.on('data', (buffer) => {
const action = buffer.toString().trim()
const result = game(action)
if (result == 0) {
console.log('平局');
} else if (result == 1) {
console.log('你赢了');
} else {
console.log('你输了');
}
if (result == 1) {
winCount++;
}
if (result == -1) {
loseCount++;
}
if (winCount == 3) {
console.log('恭喜你,你先赢了3局,获得胜利!');
process.exit();
}
if (loseCount == 3) {
console.log('很遗憾,电脑先赢了3局,你失败了!');
process.exit();
}
})
总结
本文基于冯诺依曼原理,从输出设备,输入设备,运算、存储、控制器讲解,从零编写一个石头剪刀布小游戏 希望看到这里的你能够有所收获!!!!
转载自:https://juejin.cn/post/7390629662835998772