- 首页
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
button {
display: inline-block;
}
</style>
</head>
<body>
<div id="output" style="height: 400px;width:600px;background:#eee;"></div>
<button id="rock" style="height: 40px; width:180px">石头</button>
<button id="scissor" style="height: 40px; width:180px">剪刀</button>
<button id="paper" style="height: 40px; width:180px">布</button>
<script>
const $button = {
rock: document.getElementById('rock'),
scissor: document.getElementById('scissor'),
paper: document.getElementById('paper'),
}
const $output = document.getElementById('output');
Object.keys($button).forEach(key => {
$button[key].addEventListener('click', function() {
fetch(`http://${location.host}/game?action=${key}`)
.then((res) => {
return res.text()
})
.then((text) => {
$output.innerHTML += text + '<br />'
})
})
})
</script>
</body>
</html>
- 游戏逻辑
//game.js
module.exports = function(playerAction) {
var random = Math.random() * 3;
if(random < 1) {
var computerAction = 'rock';
} else if (random > 2) {
var computerAction = 'scissor';
} else {
var computerAction = 'paper'
}
if (computerAction === playerAction) {
return 0;
} else if (
(computerAction === 'rock' && playerAction === 'paper') ||
(computerAction === 'scissor' && playerAction === 'rock') ||
(computerAction === 'paper' && playerAction === 'scissor')
) {
return -1;
} else {
return 1;
}
}
首页与游戏逻辑game.js中不需要任何改动,主要改变还是在index.js中
- 服务端
const fs = require('fs'); //文件操作
const game = require('./game.js') //导入游戏逻辑
const express = require('express') //导入express框架
let playerWonCount = 0; //记录用户赢的次数
let playerLastAction = null; //统计用户上次一出拳
let sameCount = 0; //统计连续出拳次数
const app = express();
app.get('/favicon.icon', function(req, res){
res.status(200);
return;
})
app.get(
'/game',
//获胜三次退出
function(req, res, next) {
//当用户赢了三次退出
if (playerWonCount >= 3 || sameCount == 9) {
res.status(500);
res.send('我再也不和你玩了!');
return;
}
next();
if(res.playerWon) {
playerWonCount++;
}
},
//操作行为
function(req, res, next) {
const query = req.query; //获取请求参数
const playerAction = query.action; //获取对应参数
if (!playerAction) {
res.status(400);
res.send();
return;
}
//当用户连续出同样券三次 提示用户作弊
if (playerLastAction == playerAction) {
sameCount++;
if (sameCount >= 3) {
res.status(400);
res.send('你作弊!');
sameCount = 9;
return;
}
} else {
sameCount = 0;
}
playerLastAction = playerAction; //记录上一次操作
res.playerAction = playerAction; //挂在用户操作到res上
next();
},
//结果返回
function(req, res, next) {
const playerAction = res.playerAction;
const gameResult = game(playerAction);
res.status(200);
//根据用户行为返回对应结果
if (gameResult == 0) {
res.send('平局')
} else if (gameResult == 1) {
res.send('你赢了!')
res.playerWon = true; //判断玩家是否获胜
} else if (gameResult == -1) {
res.send('你输了')
}
}
)
app.get('/', function(req, res){
res.send(fs.readFileSync(__dirname + '/index.html', 'utf-8'))
})
app.listen(3000);
- 首先需要导入游戏逻辑以及安装
express - 创建
express服务并监听3000端口 - 获取请求路由返回对应信息
- 用户操作需求
- 获取用户操作行为
- 返回用户操作结果
- 统计用户获胜次数
这里对代码进行了优化,把每个功能都划分出来通过
next进行后续操作
注意: 由于express对异步支持不太好所以社区推出koa框架
当在返回结果进行延时加载,由于事件机制会导致统计用户获胜时无法准确获取
//结果返回
function(req, res, next) {
const playerAction = res.playerAction;
const gameResult = game(playerAction);
res.status(200);
//根据用户行为返回对应结果
setTimeout(() => {
if (gameResult == 0) {
res.send('平局')
} else if (gameResult == 1) {
res.send('你赢了!')
res.playerWon = true; //判断玩家是否获胜
} else if (gameResult == -1) {
res.send('你输了')
}
}, 500)
},
//获胜三次退出
function(req, res, next) {
//当用户赢了三次退出
if (playerWonCount >= 3 || sameCount == 9) {
res.status(500);
res.send('我再也不和你玩了!');
return;
}
next();
if(res.playerWon) {
playerWonCount++;
}
},
上面代码中在返回结果时添加一个延时效果,统计获胜次数时无法获取res.playerWon的状态导致功能失效