位置: IT常识 - 正文

微信小程序 |做一款跟ChatGPT下五指棋的小程序(微信小程序做ppt)

编辑:rootadmin
原力计划微信小程序 |做一款跟ChatGPT下五指棋的小程序

推荐整理分享微信小程序 |做一款跟ChatGPT下五指棋的小程序(微信小程序做ppt),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:微信小程序做一个多少钱,微信小程序做什么项目好,微信小程序做图软件,微信小程序做一个多少钱,微信小程序做题软件,微信小程序做什么项目好,微信小程序做什么项目好,微信小程序做一个多少钱,内容如对您有帮助,希望把文章链接给更多的朋友!

一、写在前面

敢问世间万物,何以解忧?

时下最为火爆的ChatGPT想必够资格来回答一下这个问题。

要想当年AlphaGO打败世界围棋高手李世石,就展露出AI的惊人实力,时隔多年,AI领域在憋了这么多年之后,现如今,ChatGPT 4大杀四方,各行各业无不为之震撼!

借用刚召开的新程序员大会中的模型发展架构,我们可以很清晰的看到大模型现阶段的研究进展以及商业化现状。

在ChatGPT问世以来的这么几个月里,这种大模型在市场中的应用还是主要围绕在AI绘图``AI聊天以及一些AI文本类型的工作。就截至到目前,市面上对于大模型的实际生产应用仍然处在一个不断摸索的模糊地带。

回望2006-2009年的移动互联网的爆发年代,此时的跨时代的风口已经跃然纸上,要如何抓住机会逆天改命?毋庸置疑,贴近时代脉搏,疯狂尝试!

为此,我们来做一个酷炫的东西,我们做一个可以跟GPT下棋的小程序!一起来感受一下GPT的棋艺如何! 😁😪🙄😏😥😮

二、项目原理与架构2.1方案原理

要让ChatGPT遵从我们所设计的表盘五指棋的规则,首先个一个要点就是要让其知道我们的棋盘的底层设计是如何的?

那这就要说回到五指棋棋盘的实现原理了:五指棋棋盘从代码实现的角度来说就是一个二维数组,用户在棋盘的每一步操作都是在这个二维数组中对相应的元素坐标中的值进行设置(如我们在棋盘的第一个位置下了一个棋子,然后这个棋盘数组元素赋值就会变成: arr [1][1] = 1 )在明确了棋盘落子的基础之上,接下来还需要处理的就是让ChatGPT明白这个规则。通过借助ChatGPT所提供的API接口,我们将数组的边界值以及用户所进行的落子操作传递给模型,然后再实时地将模型所返回的值进行渲染到前端即可。操作数据API数据发送用户棋盘小程序ChatGPT数据处理ChatPGT如何下棋?

要跟ChatGPT下棋,其实就是跟它进行对话,让他在五指棋的规则约定下跟他对话:

首先,我们先指定话题背景:我们现在开始采用传统的黑白棋子来下一盘五指棋,棋盘的大小是20*20。我是黑方,我将用坐标的形式来表示我下的位置。你需要采取进攻型的策略快速赢我,告诉我你的落子位置。然后,我们只需要输入我们的落子坐标:如:(10,10)。GPT就会根据五指棋的规则以及我们的落子坐标对棋盘进行分析,从而得出最佳的落子选择。

2.2 技术架构(1)技术栈介绍模块语言及框架涉及的技术要点小程序前端基于VUE 2.0语法+Uni-app跨平台开发框架Http接口通信、Flex布局方式、uView样式库的使用、JSON数据解析、定时器的使用小程序接口服务端Python + Flask WEB框架rest接口的开发、 ChatGPT API接口的数据对接 、 前后端websocket实时通信(2)数据流转解析

从系统中的数据流向梳理整体的功能开发流程,进而把握开发重点🙄。

用户

五指棋小程序

微信小程序 |做一款跟ChatGPT下五指棋的小程序(微信小程序做ppt)

小程序后台服务

ChatGPT服务

发送落子操作

同步用户的下棋位置

包装prompts语句,告诉GPT用户的下棋坐标

根据规则返回模型的下棋坐标

对返回的数据进行处理,封装小程序端的数据

对返回的数据进行处理,封装小程序端的数据

根据用户的下棋坐标以及前置的规则

直接返回模型的决策结果.

用户

五指棋小程序

小程序后台服务

ChatGPT服务

三、项目实现3.1 ChatGPT API的接入

要接入ChatGPT API,需要按照以下步骤进行操作:

注册一个账号并登录到OpenAI的官网:https://openai.com/在Dashboard页面上,创建一个API密钥。在“API Keys”选项卡下,点击“Generate New Key”按钮。将生成的密钥保存好,以备后续使用。选择所需的API服务,例如“Completion” API,以使用OpenAI的文本生成功能。

使用Python调用ChatGPT API实现代码如下:

方法一:使用request库import requestsimport json# 构建API请求url = "https://api.openai.com/v1/engines/davinci-codex/completions"headers = {"Content-Type": "application/json", "Authorization": "Bearer YOUR_API_KEY"}data = { "prompt": "Hello, my name is", "max_tokens": 5}# 发送API请求response = requests.post(url, headers=headers, data=json.dumps(data))# 解析API响应response_data = json.loads(response.text)generated_text = response_data["choices"][0]["text"]print(generated_text)方式二:使用openAI库from flask import Flask, requestimport openaiapp = Flask(__name__)openai.api_key = "YOUR_API_KEY_HERE"@app.route("/")def home(): return "Hello, World!"@app.route("/chat", methods=["POST"])def chat(): data = request.json response = openai.Completion.create( engine="davinci", prompt=data["message"], max_tokens=60 ) return response.choices[0].textif __name__ == "__main__": app.run()3.2 小程序端棋盘功能实现主页正在下棋用户卡片等待下棋用户卡片小程序界面实现代码如下: <template><view class="chat-room"><gpt-card :show="showGPT"></gpt-card><view class="box" ><view class="centent"><canvas @touchend="syncAction" canvas-id="canvas" class="canvas" style="width: 730rpx;height: 730rpx;"></canvas></view><view><view:class="value.class":style="{ left: value.left, top: value.top, transform: value.transform, boxShadow: value.boxShadow }"v-for="(value, index) in game.h":key="index">{{ value.text }}</view></view><view class="winner"><view class="state-chess Bchess"></view><view class="chessName"></view></view></view><user-card :show="showUser"></user-card></view></template><script>import userCard from '@/components/infoCard/index.vue'import gptCard from '@/components/gptCard/index.vue'let goEasy = getApp().globalData.goEasy;let pubSub = goEasy.pubsub;export default {data() {return {showGPT: false,showUser: true,userInfo:{chessRole:1, // 1为白棋,2为黑棋roundFlag:true, // 表示是否为自己的回合enemy:'',name:''},chessMassage:{body:'',playerA:'',playerB:'',chessRole:1,mode:1},MoveMode:{a2b:1,b2a:2},game: {ctx: null,e: 0,chess_Board: [],chess_Name: ['黑棋', '白棋'],h: [],um: 0,lianz: [],winXY: [[1, 0], [0, 1], [1, 1], [1, -1]],chessOff: true},cName: '黑棋走',sChesee: 'Bchess',currentRoom: null,// 道具展示propDisplay: {showPropType: 0,play: false,timer: null},newMessageContent: "",// 道具类型Prop: {HEART: 0,//桃心ROCKET: 1//火箭},// 消息类型MessageType: {CHAT: 0,//文字聊天PROP: 1,//道具CHESS:2 // 下棋}}},components:{userCard, gptCard},onLoad(options) {//获取数据let roomToken = JSON.parse(options.roomToken);// 初始化roomthis.currentRoom = {roomId: roomToken.roomId,roomName: roomToken.roomName,onlineUsers: {count: 0,users: []},messages: [],currentUser: {id: roomToken.userId,nickname: roomToken.nickname,avatar: roomToken.avatar}};this.userInfo.name = roomToken.nickname// 设置导航标题uni.setNavigationBarTitle({title: roomToken.roomName});// 连接goEasythis.connectGoEasy(); // 监听用户上下线 this.listenUsersOnlineOffline(); // 加载最后10条消息历史 this.loadHistory(); // 监听新消息 this.listenNewMessage(); },onReady() {this.game.ctx = uni.createCanvasContext('canvas');this.drawLine();},onUnload() {// 断开连接goEasy.disconnect({onSuccess(){console.log("GoEasy disconnect successfully");},onFailed(error){console.log("GoEasy disconnect failed"+JSON.stringify(error));}});},methods: {// 连接goEasyconnectGoEasy(){let self = this;let userData = {avatar: this.currentRoom.currentUser.avatar,nickname: this.currentRoom.currentUser.nickname}goEasy.connect({id : this.currentRoom.currentUser.id,data : userData,onSuccess: function(){console.log("GoEasy connect successfully.") // 加载在线用户列表 self.loadOnlineUsers();},onFailed: function(error){console.log("Failed to connect GoEasy, code:"+error.code+ ",error:"+error.content);},onProgress: function(attempts){console.log("GoEasy is connecting", attempts);}});},// 监听用户上下线listenUsersOnlineOffline(){let self = this;let roomId = this.currentRoom.roomId;pubSub.subscribePresence({channel: roomId,onPresence: function (presenceEvents) {self.currentRoom.onlineUsers.count = presenceEvents.clientAmount;presenceEvents.events.forEach(function (event) {let userData = event.data;if (event.action === "join" || event.action === "online") {//进入房间let userId = event.id;let avatar = userData.avatar;let nickname = userData.nickname;let user = {id: userId,avatar: avatar,nickname: nickname};//添加新用户self.currentRoom.onlineUsers.users.push(user);//添加进入房间的消息let message = {content: " 进入房间",senderUserId: userId,senderNickname: nickname,type: self.MessageType.CHAT};self.currentRoom.messages.push(message);} else {//退出房间self.currentRoom.onlineUsers.users.forEach((user, index) => {if (event.id === user.id) {// 删除当前聊天室列表中离线的用户let offlineUser = self.currentRoom.onlineUsers.users.splice(index, 1);let message = {content: " 退出房间",senderUserId: offlineUser[0].id,senderNickname: offlineUser[0].nickname,type: self.MessageType.CHAT};self.currentRoom.messages.push(message);}});}self.scrollToBottom();});},onSuccess : function () {console.log("用户上下线监听成功")},onFailed : function (error) {console.log("监听用户上下线失败, code:"+error.code+ ",content:"+error.content); }})},switchRound(){this.showGPT = !this.showGPTthis.showUser = !this.showUser},// 监听新消息listenNewMessage(){// 监听当前聊天室的消息let self = this;let roomId = this.currentRoom.roomId;pubSub.subscribe({channel: roomId,onMessage : function (message) {let messageContent = "";let content = JSON.parse(message.content);//聊天消息if(content.type === self.MessageType.CHAT) {messageContent = content.content;}//道具消息if(content.type === self.MessageType.PROP) {if (content.content === self.Prop.ROCKET) {messageContent = "送出了一枚大火箭";}if (content.content === self.Prop.HEART) {messageContent = "送出了一个大大的比心";}} console.log("监听消息成功==",content)if(content.type === self.MessageType.CHESS){self.canvasClick(content.body,content.chessRole)self.userInfo.roundFlag = trueself.switchRound()}//添加消息let newMessage = {content: messageContent,senderUserId: content.senderUserId,senderNickname: content.senderNickname,type: self.MessageType.CHAT};self.currentRoom.messages.push(newMessage);if (content.type === self.MessageType.PROP) {self.propAnimation(parseInt(content.content))}self.scrollToBottom();},onSuccess : function () { console.log("监听新消息成功")},onFailed : function(error) {console.log("订阅消息失败, code:"+error.code+ ",错误信息:"+error.content);}})},// 加载在线用户列表loadOnlineUsers(){let self = this;let roomId = this.currentRoom.roomId;pubSub.hereNow({channels : [roomId],includeUsers : true,distinct : true,onSuccess: function (result) {let users = [];let currentRoomOnlineUsers = result.content.channels[roomId];currentRoomOnlineUsers.users.forEach(function (onlineUser) {let userData = onlineUser.data;let user = {id: onlineUser.id,nickname: userData.nickname,avatar: userData.avatar};users.push(user);});self.currentRoom.onlineUsers = {users: users,count: currentRoomOnlineUsers.clientAmount};// 如果是第一个进房的就自动设为白棋// 如果是第二个进房的就是设为黑棋if(users.length==1){self.userInfo.chessRole = 1self.userInfo.name = users[0].nickname}if(users.length==2){self.userInfo.chessRole = 2self.userInfo.name = users[1].nickname}},onFailed: function (error) {//获取失败 console.log("获取在线用户失败, code:" + error.code + ",错误信息:" + error.content);}});},// 加载最后10条消息历史loadHistory(){let self = this;let roomId = this.currentRoom.roomId;pubSub.history({channel: roomId, //必需项limit: 10, //可选项,返回的消息条数onSuccess:function(response){let messages = [];response.content.messages.map(message => {let historyMessage = JSON.parse(message.content);//道具消息if (historyMessage.type === self.MessageType.PROP) {if (historyMessage.content === self.Prop.ROCKET) {historyMessage.content = "送出了一枚大火箭";}if (historyMessage.content === self.Prop.HEART) {historyMessage.content = "送出了一个大大的比心";}}messages.push(historyMessage);});self.currentRoom.messages = messages;},onFailed: function (error) { console.log("获取历史消息失败, code:" + error.code + ",错误信息:" + error.content);}});},onInputMessage(event) {//双向绑定消息 兼容this.newMessageContent = event.target.value;},sendMessage(messageType, content) {//发送消息if (content === "" && messageType === this.MessageType.CHAT) {return;}var message = {senderNickname: this.currentRoom.currentUser.nickname,senderUserId: this.currentRoom.currentUser.id,type: messageType,content: content};if(messageType === this.MessageType.CHESS){this.chessMassage.body = contentthis.chessMassage.chessRole = this.userInfo.chessRolelet userNum=this.currentRoom.onlineUsers.users.lengthmessage = {senderNickname: this.currentRoom.currentUser.nickname,senderUserId: this.currentRoom.currentUser.id,type: messageType,body:content,playerA:'',playerB:'',chessRole:this.userInfo.chessRole,mode:1,userNum:userNum}}console.log("发送==",message);pubSub.publish({channel : this.currentRoom.roomId,message : JSON.stringify(message),onSuccess : function () {console.log("发送成功");},onFailed : function (error) {console.log("消息发送失败,错误编码:" + error.code + " 错误信息:" + error.content);}});this.newMessageContent = "";},propAnimation(type) {//道具动画//动画的实现if (this.propDisplay.timer) {return;}this.propDisplay.showPropType = type;this.propDisplay.play = true;this.propDisplay.timer = setTimeout(() => {this.propDisplay.play = false;this.propDisplay.timer = null;}, 2000)},scrollToBottom () {this.$nextTick(function(){uni.pageScrollTo({scrollTop: 2000000,duration : 10})})},// ==== 五指棋控制逻辑 ===drawLine() {let s = uni.upx2px(730);let dis = Math.floor(s / 15);let w = dis * 14;for (let i = 1; i <= 14; i++) {this.game.ctx.moveTo(i * dis + 0.5, w);this.game.ctx.lineTo(i * dis + 0.5, dis);this.game.ctx.moveTo(dis, i * dis + 0.5);this.game.ctx.lineTo(w, i * dis + 0.5);this.game.ctx.setStrokeStyle('#a5aa6b');this.game.ctx.stroke();}this.game.ctx.draw();for (let i = 0; i <= 13; i++) {this.game.chess_Board[i] = [];this.game.lianz[i] = [];for (let j = 0; j <= 13; j++) {this.game.chess_Board[i][j] = 0;this.game.lianz[i][j] = 0;}}},syncAction(e){if(this.userInfo.roundFlag){this.sendMessage(this.MessageType.CHESS,e)this.canvasClick(e,this.userInfo.cheeRole)this.userInfo.roundFlag = false}else{uni.showModal({content: '还未到你的回合!'});}},canvasClick(e,chessRole) {console.log(JSON.stringify(e));let s = uni.upx2px(730);let dis = Math.floor(s / 15);let dx = parseInt(Math.floor(e.changedTouches[0].x + dis / 2) / dis);let dy = parseInt(Math.floor(e.changedTouches[0].y + dis / 2) / dis);let WBobj = {ox: dx * dis - dis / 2 + 10,oy: dy * dis - dis / 2 + 10,left: dx * dis - dis / 2 + 10 + 'px',top: dy * dis - dis / 2 + 10 + 'px',transform: '',boxShadow: '',text: '',mz: this.game.chess_Name[this.game.e % 2],class: this.game.e % 2 == 1 ? 'Wchess' : 'Bchess',list: this.game.um++};if (dx < 1 || (dx > dis - 1) | (dy < 1) || dy > dis - 1) return;if (this.game.chess_Board[dx - 1][dy - 1] == 0) {this.game.h.push(WBobj);this.game.chess_Board[dx - 1][dy - 1] = this.game.chess_Name[this.game.e % 2];this.game.lianz[dx - 1][dy - 1] = WBobj;this.win(dx - 1, dy - 1, this.game.chess_Name[this.game.e % 2], this.game.winXY[0], this.game.e % 2);this.win(dx - 1, dy - 1, this.game.chess_Name[this.game.e % 2], this.game.winXY[1], this.game.e % 2);this.win(dx - 1, dy - 1, this.game.chess_Name[this.game.e % 2], this.game.winXY[2], this.game.e % 2);this.win(dx - 1, dy - 1, this.game.chess_Name[this.game.e % 2], this.game.winXY[3], this.game.e % 2);this.cName = this.game.e % 2 == 0 ? this.game.chess_Name[1] + '走' : this.game.chess_Name[0] + '走';this.sChesee = chessRole==2? 'Bchess' : 'Wchess';this.game.e++;}},win(x, y, c, m, li) {let ms = 1;var continuity = [];for (let i = 1; i < 5; i++) {if (this.game.chess_Board[x + i * m[0]]) {if (this.game.chess_Board[x + i * m[0]][y + i * m[1]] === c) {continuity.push([x + i * m[0], y + i * m[1]]);ms++;} else {break;}}}for (let i = 1; i < 5; i++) {if (this.game.chess_Board[x - i * m[0]]) {if (this.game.chess_Board[x - i * m[0]][y - i * m[1]] === c) {continuity.push([x - i * m[0], y - i * m[1]]);ms++;} else {break;}}}if (ms >= 5) {setTimeout(function() {console.log(c + '赢了');}, 600);continuity.push([x, y]);this.game.chessOff = false;let s = 5;let ls = [270, 300, 330, 360, 390];let ls1 = [390, 420, 450, 480, 510];let _this = this;continuity.forEach(function(value, index) {let time = setInterval(function() {_this.game.lianz[value[0]][value[1]].transform = 'scale(0.9)';_this.game.lianz[value[0]][value[1]].boxShadow = '0px 0px 2px 2px #ffd507';s--;s <= 0 ? clearInterval(time) : clearInterval(time);}, ls[index]);let time2 = setInterval(function() {_this.game.lianz[value[0]][value[1]].transform = 'scale(1)';_this.game.lianz[value[0]][value[1]].boxShadow = '0px 0px 2px 2px #ffd507';s++;s >= 5 ? clearInterval(time2) : clearInterval(time2);}, ls1[index]);});for (var i = 0; i < this.game.chess_Board.length; i++) {for (var j = 0; j < this.game.chess_Board.length; j++) {if (this.game.chess_Board[i][j] === 0) {this.game.chess_Board[i][j] = 'null';}}}this.game.h.forEach(function(value, index) {value.text = value.list;});uni.showModal({content: c + '赢了'});}},regret() {if (this.game.chessOff) {if (this.game.h.length > 0) {let s = uni.upx2px(730);let dis = Math.floor(s / 15);let obj = this.game.h.pop();this.cName = this.game.e % 2 == 0 ? this.game.chess_Name[1] + '走' : this.game.chess_Name[0] + '走';this.sChesee = this.game.e % 2 == 1 ? 'Bchess' : 'Wchess';this.game.e -= 1;this.game.um -= 1;this.game.chess_Board[parseInt(obj.ox / dis)][parseInt(obj.oy / dis)] = 0;} else {return;}} else {return;}},anewClick() {this.game.h = [];this.game.um = 0;this.game.chessOff = true;for (let i = 0; i <= 13; i++) {this.game.chess_Board[i] = [];this.game.lianz[i] = [];for (let j = 0; j <= 13; j++) {this.game.chess_Board[i][j] = 0;this.game.lianz[i][j] = 0;}}}}}</script><style>page {height: 100%;;}uni-page-body {height: 100%;;}.chat-room {display: flex;flex-direction: column;height: 100%;}.online-avatar-container {position: fixed;right: 0;width: 100%;height: 80rpx;display: flex;justify-content: flex-end;padding: 28rpx;box-shadow: 10rpx 30rpx 50rpx #fff;z-index: 40;background: #ffffff;}.online-avatar-item {width: 80rpx;height: 80rpx;border-radius: 40rpx;text-align: center;line-height: 80rpx;background: rgba(51, 51, 51, 0.3);color: #fff;font-size: 18rpx 28rpx;}.online-count {width: 80rpx;height: 80rpx;border-radius: 40rpx;text-align: center;line-height: 80rpx;background: rgba(51, 51, 51, 0.3);color: #fff;font-size: 28rpx;}.online-avatar-item image {width: 80rpx;height: 80rpx;}.chat-room-container {/* padding-top: 100rpx; */}.scroll-view {overflow-y: auto;padding: 20rpx 38rpx 130rpx 38rpx;box-sizing: border-box;-webkit-overflow-scrolling: touch;}.message-box {margin-top: 16rpx;}.message-item {box-sizing: border-box;height: 72rpx;background-color: rgba(196, 196, 196, 0.2);display: inline-block;font-size: 28rpx;border-radius: 100rpx;padding: 18rpx 30rpx;font-family: Microsoft YaHei UI;}.user-name {color: #D02129;font-family: Microsoft YaHei UI;}.user-message {color: #333;font-family: Microsoft YaHei UI;}.chat-room-input {position: fixed;bottom: 0;height: 92rpx;line-height: 92rpx;padding: 10rpx 28rpx 20rpx 28rpx;display: flex;background: #ffffff;}.uni-input {width: 528rpx;background-color: rgba(51, 51, 51, 0.1);height: 92rpx;border-radius: 100rpx;box-sizing: border-box;padding: 26rpx 40rpx;font-size: 28rpx;}.uni-btn {position: absolute;z-index: 1000;width: 72rpx;height: 72rpx;background: #D02129;right: 10rpx;top: 10rpx;border-radius: 72rpx;text-align: center;line-height: 72rpx;color: #fff;font-weight: bold;font-size: 32rpx;}.heart {width: 80rpx;height: 92rpx;padding: 0 15rpx;}.rocket {width: 40rpx;height: 92rpx;}.self {color: #D02129;}.show-animation {width: 80rpx;height: 320rpx;position: fixed;z-index: 44;left: 50%;bottom: 80rpx;margin: 0 -40rpx;justify-content: flex-end;animation: myanimation 2s linear;}.prop-heart {height: 80rpx;width: 80rpx;}.prop-rocket {height: 160rpx;width: 80rpx;}@keyframes myanimation {from {bottom: 80rpx;}to {bottom: 600rpx;}}.box {position: relative;margin: 50rpx auto;width: 750rpx;height: 810rpx;background: #e6e7ec;}.centent {position: absolute;width: 730rpx;height: 730rpx;border: 1px solid #9e9e9e;overflow: hidden;border-radius: 8rpx;box-shadow: 0rpx 0rpx 5rpx 0rpx #9e9e9e;left: 10rpx;top: 20rpx;}.canvas {background: #f7e6b7;}.button,.anew,.state,.winner {position: absolute;display: block;width: 100rpx;height: 55rpx;border-radius: 10rpx;outline: none;font-size: 22rpx;box-sizing: border-box;color: #00bcd4;background: #fff;border: none;box-shadow: 1rpx 1rpx 3rpx 1rpx #9e9e9e;top: 760rpx;left: 270rpx;user-select: none;}.anew {left: 150rpx;}.state {left: 400rpx;width: 140rpx;}.state .state-chess,.winner .state-chess {position: absolute;width: 30rpx;height: 30rpx;top: 11rpx;left: 10rpx;}.state .chessName,.winner .chessName {position: absolute;width: 80rpx;height: 30rpx;top: 12rpx;left: 45rpx;text-align: center;line-height: 30rpx;font-size: 15rpx;}.button:active,.anew:active {transition-property: all;transition-duration: 1s;transition-timing-function: ease;transition-delay: 0s;transform: scale(0.8);}.Bchess {position: absolute;width: 40rpx;height: 40rpx;border-radius: 40rpx;background: radial-gradient(#9e9e9e -100%, #000000 100%);box-shadow: 1rpx 1rpx 2rpx 0rpx #000000;font-size: 10rpx;line-height: 50rpx;text-align: center;color: #fff;}.Wchess {position: absolute;width: 40rpx;height: 40rpx;border-radius: 40rpx;background: radial-gradient(#e4e4e4 10%, #b7aaaa);box-shadow: 1rpx 1rpx 2rpx 0rpx #0000006e;font-size: 10rpx;line-height: 50rpx;text-align: center;color: #000000;}.winner {width: 120rpx;left: 12rpx;display: none;}</style>3.3 下棋的实时同步功能实现

为了实现将ChatGPT的下棋操作实时同步到前端小程序界面,我们这里使用了WebSocket长连接技术。

使用Flask框架与前端建立WebSocket连接,可以采用flask-socketio库实现。下面是详细步骤:

安装flask-socketio库,可以使用pip命令进行安装:pip install flask-socketio在Flask应用中导入库并创建socketio实例Copy codefrom flask import Flaskfrom flask_socketio import SocketIOapp = Flask(__name__)socketio = SocketIO(app)编写路由函数,实现WebSocket连接建立和数据传输pythonCopy code@socketio.on('connect')def on_connect(): print('WebSocket连接已建立')@socketio.on('disconnect')def on_disconnect(): print('WebSocket连接已断开')@socketio.on('message')def handle_message(message): print('收到消息:', message) socketio.send('已收到消息:' + message)

以上代码中,on_connect函数是当WebSocket连接建立时会被调用,on_disconnect函数是当WebSocket连接断开时会被调用,handle_message函数是当接收到消息时会被调用。

获取下棋的实现代码如下:from flask import Flask, request, jsonifyfrom flask_socketio import SocketIO, emitimport openaiimport os# 设置OpenAI API密钥openai.api_key = os.getenv("OPENAI_API_KEY")# 初始化Flask应用和SocketIOapp = Flask(__name__)socketio = SocketIO(app)# 处理WebSocket连接事件@socketio.on('connect')def handle_connect(): print('Client connected')# 处理WebSocket断开连接事件@socketio.on('disconnect')def handle_disconnect(): print('Client disconnected')# 处理发送请求事件@socketio.on('send_request')def handle_request(request_text): # 调用OpenAI API获取回复 response = openai.Completion.create( engine="davinci", prompt=request_text, max_tokens=50, n=1, stop=None, temperature=0.7 ) # 从API响应中提取回复文本 response_text = response.choices[0].text.strip() # 将回复发送给前端 emit('response', {'text': response_text})if __name__ == '__main__': socketio.run(app, host='0.0.0.0', port=5000)四、推荐阅读

🥇入门和进阶小程序开发,不可错误的精彩内容🥇 :

《小程序开发必备功能的吐血整理【个人中心界面样式大全】》《微信小程序 | 借ChatGPT之手重构社交聊天小程序》《微信小程序 | 人脸识别的最终解决方案》《微信小程序 |基于百度AI从零实现人脸识别小程序》《吐血整理的几十款小程序登陆界面【附完整代码】》
本文链接地址:https://www.jiuchutong.com/zhishi/293004.html 转载请保留说明!

上一篇:阳光穿透加拉霍奈国家公园中的森林,西班牙戈梅拉岛 (© Martin Siepmann/Westend61/Offset by Shutterstock)(阳光穿透云层是什么效应)

下一篇:鸟瞰兰萨罗特岛的La Geria葡萄园,西班牙加那利群岛 (© Orbon Alija/Getty Images)(兰萨罗特岛的地理位置)

  • 航天信息金税盘未打开
  • 支付给员工的工资属于什么科目
  • 小商店如何纳税?
  • 申报增值税附加税减免项目选错了
  • 税务中的三费是指什么
  • 开了农民工资金专户必须使用吗
  • 软件服务费280抵扣申报
  • 公司电视机 摊销多少年
  • 个税反推税前工资速算
  • 控股股权转让
  • 免税企业收到增值税专用发票咋办
  • 营改增租金收入税率
  • 代扣代缴企业所得税申报期限
  • 别人的项目挂靠我公司怎么做账?
  • 理财收益高的产品
  • 小规模没有进项票可以开销项票吗
  • 个人所得税0申报操作流程
  • 税控盘基本信息设置
  • 个人申请税务局开技术服务发票如何收费
  • 其他综合收益影响净利润吗
  • 房屋修缮发票能补开吗
  • 勾选认证售票状态可以改吗
  • 公司收到个人投资款没有备注
  • 外挂项目跨年结转分录怎么做?
  • 发生的费用发票会计分录
  • 收到专用发票的会计分录
  • 利润表中的销售收入
  • 季度不含税收入30万以内免增值税
  • 华为mate50耳机孔和充电口一样吗
  • win10待机久了自动关机
  • macbookpro鼠标滚轮是反的
  • 企业间实物交易是指
  • win10 累积更新
  • 无形资产摊销是什么科目
  • igfxem.exe是什么进程
  • 小企业成本管理方法
  • php swoole websocket
  • 跨年度退货
  • 权利许可证照印花税优惠政策
  • laravel入门与实战:构建主流php应用开发框架
  • 使用ajax实现页面分页
  • 董事长报销应该是怎样的流程
  • 利润与所有者权益的区别
  • 会议费需要纳税调整吗
  • 个体工商户开普通发票需要交税吗
  • 合并报表为什么要抵消子公司所有者权益
  • 暂估入库结转成本税务规定
  • python locator
  • mysqldump -r
  • sqlserver2012完全卸载
  • 房屋消防工程
  • 社保由税局代收马上开始
  • 固定资产减少如何处理
  • 金税四期怎么监控个人账号
  • 辞退补偿的账务处理
  • 年终奖政策,提成怎么算
  • 认证固定资产发票如何入账
  • 企业要怎样才能用到便宜的天然气
  • sql语句的执行方式
  • nginx sbin目录
  • linux的防火墙配置文件
  • centos 做bond
  • mysql如何建立数据完整性约束
  • kernel-headers-2.2.1-4
  • 缺少系统操作怎么办
  • 剑指offter
  • 批处理有何限制
  • 批处理 ftp
  • JQuery和HTML5 Canvas实现弹幕效果
  • jq cookie
  • 深入python3
  • 举例讲解水生花卉栽培管理
  • nodejs如何安装
  • unity3d知乎
  • javascript常见的数据类型
  • android自定义ui
  • python遍历列表的两种方法
  • python二分查找非递归
  • 纪检委是干什么工作的能管理税务管理局吗
  • 广东地税电话客服电话
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设