跑的快扑克游戏技术方案设计
demo:http://json.lcache.tech/paodekuai/#/
用户点击开始游戏,加入到分配的房间,建立消息池MessagePool,心跳包轮训消息池
1、48张扑克随机打乱,每人16张分给3人,peopleA、B、C,前端监听发牌消息
2、判断黑桃3先出,上一把先出,还是随机先出,前端监听先出消息
3、出牌提示功能,A根据规则出牌,客户端发送A出牌消息,后端放入消息池,前端监听A出牌消息
4、前端收到A出牌消息后,B、C显示A出牌,然后B发送出牌消息、或者要不起,后端放入消息池,前端监听B出牌消息
5、前端收到B出牌消息后,A、C显示B出牌,然后C发送出牌消息、或者要不起,后端放入消息池,前端监听C出牌消息
6、后端判断是否出完,发送结算消息,前端监听结算消息
服务器选择用php
有点:够便宜,搭建快
缺点:一个接口对应一个php,没有共享数据,共享数据都是存放mysql
3月26日做了些ui和交互
Poker.js

Array.prototype.shuffle = function () { var array = this; for (var i = array.length - 1; i >= 0; i--) { var randomIndex = Math.floor(Math.random() * (i + 1)); var itemAtIndex = array[randomIndex]; array[randomIndex] = array[i]; array[i] = itemAtIndex; } return array; }; Array.prototype.sortMin = function () { return this.sort(function (a,b){ return a-b; }) }; Array.prototype.remove = function (d) { const n=this.indexOf(d) if(n>-1){ this.splice(n,1) } }; //生成一副扑克,移除3个2,一个A console.log('跑得快出牌提示,移除3个2,一个A') const data=[] const rArr=['HA','H2','R2','M2',] const word=['2','A','K','Q','J','10','9','8','7','6','5','4','3'] const type=['H','R','M','F'] //黑红梅方 const StrToIndex={ '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'J':11, 'Q':12, 'K':13, 'A':14, '2':16, } const IndexArr=[] const strArr=[] word.forEach(function (w){ type.forEach(function (t){ const str=t+w if(rArr.indexOf(str)===-1){ IndexArr.push(data.length) data.push(StrToIndex[w]) strArr.push(str) } }) }) console.log(strArr) const list=IndexArr.shuffle().slice(0,16).sortMin().map(function (d){ return data[d] }) const gameObj={ IndexToStr:['','','','3','4','5','6','7','8','9','10','J','Q','K','A','','2'], data:[], preData:[], nextData:[], init(){ }, isAble(preList){ console.log(preList) const curData=this.curData const btList=[].concat(preList) const list=new Array(17).fill(0) btList.forEach(function (d){ list[d]++ }) const list4=[]//炸弹 const list3=[]//三带二 const list2=[]//对子 const list1=[]//单张 const list3More=[]//飞机 const list2More=[]//连队 const list1More=[]//顺子 let len1=0,len2=0,len3=0 let pred=-1 for(let i=0;i<list.length;i++){ const d=list[i] if(d>0){ list1.push(i) } if(d>1){ list2.push(i) } if(d>2){ list3.push(i) } if(d>3){ list4.push(i) } if(pred>0&&d>0){ len1++ }else{ //顺子 if(len1>3){ const temp=[] for(let j=i-len1-1;j<i;j++){ temp.push(j) } list1More.push(temp) } len1=0 } if(pred>1&&d>1){ len2++ }else{ //连队 if(len2>0){ const temp=[] for(let j=i-len2-1;j<i;j++){ temp.push(j) } list2More.push(temp) } len2=0 } if(pred>2&&d>2){ len3++ }else{ //飞机 if(len3>0){ const temp=[] for(let j=i-len3-1;j<i;j++){ temp.push(j) } list3More.push(temp) } len3=0 } pred=d } if(list3More.length===1&&list3More[0].length*5>=preList.length){ if(list3More[0].length*5>preList.length){ if(preList.length===curData.length){ return true }else{ return false } }else{ return true; } }else if(list2More.length===1&&list2More[0].length*2===preList.length){ return true; }else if(list1More.length===1&&list1More[0].length===preList.length){ return true; }else if(list4.length===1&&4===preList.length){//炸弹 return true; }else if(list3.length===1&&5>=preList.length){//三张 if(5>preList.length){ if(preList.length===curData.length){ return true }else{ return false } } return true; }else if(list2.length===1&&2===preList.length){//一对 return true; }else if(list1.length===1&&1===preList.length){//单张 return true; } }, tip(){ const preList=[4,5,6,7,8] // const preList=[] const preData=this.preData const nextData=this.nextData const curData=this.curData console.log(curData) const btList=[].concat(curData) const list=new Array(17).fill(0) btList.forEach(function (d){ list[d]++ }) const list4=[]//炸弹 const list3=[]//三带二 const list2=[]//对子 const list1=[]//单张 const list3More=[]//飞机 const list2More=[]//连队 const list1More=[]//顺子 let len1=0,len2=0,len3=0 let pred=-1 for(let i=0;i<list.length;i++){ const d=list[i] if(d>0){ list1.push(i) } if(d>1){ list2.push(i) } if(d>2){ list3.push(i) } if(d>3){ list4.push(i) } if(pred>0&&d>0){ len1++ }else{ //顺子 if(len1>3){ const temp=[] for(let j=i-len1-1;j<i;j++){ temp.push(j) } list1More.push(temp) } len1=0 } if(pred>1&&d>1){ len2++ }else{ //连队 if(len2>0){ const temp=[] for(let j=i-len2-1;j<i;j++){ temp.push(j) } list2More.push(temp) } len2=0 } if(pred>2&&d>2){ len3++ }else{ //飞机 if(len3>0){ const temp=[] for(let j=i-len3-1;j<i;j++){ temp.push(j) } list3More.push(temp) } len3=0 } pred=d } btList.sort(function (a,b){ if(b>13&&list[a]===2){return 1} return list[b]-list[a] }) const rList=[] //先出与后出 if(preList.length>0){ if(preList.length===4&&preList[0]===preList[3]){//炸弹 list4.forEach(function (d){ if(d>preList[0]){ const temp=[] temp.push(d) temp.push(d) temp.push(d) temp.push(d) rList.push(temp) } }) }else if(list4.length===1){ list4.forEach(function (d){//对面不是炸弹 rList.push([d,d,d,d]) }) }else if(preList.length===1){ list1.forEach(function (d){//单张 if(d>preList[0]){ rList.push([d]) } }) }else if(preList.length===2){//对子 list2.forEach(function (d){ if(d>preList[0]){ rList.push([d,d]) } }) }else if(preList.length===5&&preList[0]===preList[2]){//三带二 list3.forEach(function (d){ if(d>preList[0]){ const temp=[] const tbtList=[].concat(btList) temp.push(d) temp.push(d) temp.push(d) tbtList.remove(d) tbtList.remove(d) tbtList.remove(d) for(let k=Math.max(0,tbtList.length-2);k<tbtList.length;k++){ temp.push(tbtList[k]) } rList.push(temp) } }) }else if(preList.length===10||preList.length===15){//飞机 const dLen=preList.length/5 list3More.forEach(function (arr){ if(arr.length>=dLen&&arr[arr.length-dLen]>preList[0]){ for(let i=0;i<=arr.length-dLen;i++){ const d=arr[i] if(d>preList[0]){ const tbtList=[].concat(btList) const temp=[] for(let k=d;k<d+dLen;k++){ temp.push(k) temp.push(k) temp.push(k) tbtList.remove(k) tbtList.remove(k) tbtList.remove(k) } for(let k=Math.max(0,tbtList.length-dLen*2);k<tbtList.length;k++){ temp.push(tbtList[k]) } rList.push(temp) } } } }) }else if(preList.length%2===0&&preList[0]===preList[1]){//连对 const dLen=preList.length/2 list2More.forEach(function (arr){ if(arr.length>=dLen&&arr[arr.length-dLen]>preList[0]){ for(let i=0;i<=arr.length-dLen;i++){ const d=arr[i] if(d>preList[0]){ const temp=[] for(let k=d;k<d+dLen;k++){ temp.push(k) temp.push(k) } rList.push(temp) } } } }) }else if(preList.length>4&&preList[0]+3===preList[3]){//顺子 const dLen=preList.length list1More.forEach(function (arr){ if(arr.length>=dLen&&arr[arr.length-dLen]>preList[0]){ for(let i=0;i<=arr.length-dLen;i++){ const d=arr[i] if(d>preList[0]){ const temp=[] for(let k=d;k<d+dLen;k++){ temp.push(k) } rList.push(temp) } } } }) } }else{ if(list3More.length>0){ const arr=list3More[0] const tbtList=[].concat(btList) const temp=[] arr.forEach(function (d){ temp.push(d) temp.push(d) temp.push(d) tbtList.remove(d) tbtList.remove(d) tbtList.remove(d) }) for(let k=Math.max(0,tbtList.length-arr.length*2);k<tbtList.length;k++){ temp.push(tbtList[k]) } rList.push(temp) } if(list2More.length>0){ const arr=list2More[0] const temp=[] arr.forEach(function (d){ temp.push(d) temp.push(d) }) rList.push(temp) } if(list1More.length>0){ const arr=list1More[0] const temp=[] arr.forEach(function (d){ temp.push(d) }) rList.push(temp) } if(list4.length>0){ list4.forEach(function (d){ const temp=[] temp.push(d) temp.push(d) temp.push(d) temp.push(d) rList.push(temp) }) list4.forEach(function (d){ const temp=[] const tbtList=[].concat(btList) temp.push(d) temp.push(d) temp.push(d) temp.push(d) tbtList.remove(d) tbtList.remove(d) tbtList.remove(d) tbtList.remove(d) for(let k=Math.max(0,tbtList.length-3);k<tbtList.length;k++){ temp.push(tbtList[k]) } rList.push(temp) }) } if(list3.length>0){ list3.forEach(function (d){ const temp=[] const tbtList=[].concat(btList) temp.push(d) temp.push(d) temp.push(d) tbtList.remove(d) tbtList.remove(d) tbtList.remove(d) for(let k=Math.max(0,tbtList.length-2);k<tbtList.length;k++){ temp.push(tbtList[k]) } rList.push(temp) }) } if(list2.length>0){ const temp=[] temp.push(list2[0]) temp.push(list2[0]) rList.push(temp) } if(list1.length>0){ //下家是否报单 if(nextData.length===1){ rList.push([list1[list1.length-1]]) }else{ rList.push([list1[0]]) } } rList.sort(function (p1,p2){ return p2.length-p1.length }) console.log('先出牌提示',rList) } return rList } } gameObj.curData=[ 16, 14, 14, 13,13, 13,13,12, 12, 12, 11,11,11, 10, 9, 8, 7, 6, 6, 5, 4 ] console.log(gameObj.tip()) console.log(gameObj.isAble([3])) console.log(gameObj.isAble([3,3])) console.log(gameObj.isAble([3,3,3,5,6])) console.log(gameObj.isAble([3,4,5,6,7])) console.log(gameObj.isAble([3,3,4,4])) console.log(gameObj.isAble([3,3,3,4,4,4,5,5,6,6])) console.log(gameObj.isAble([3,3,3,4,4,4,5,5,5,6,6,8,9,7,7])) console.log(gameObj.isAble([4,4,4,4]))
vstatus:访问者状态表
`vid` VARCHAR(50) NOT NULL COMMENT '访客id',
`status` VARCHAR(50) DEFAULT 'see' COMMENT '状态see、wait、play',
`roomId` INT DEFAULT 0 COMMENT '房间id',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
room:游戏房间表
`id` INT AUTO_INCREMENT COMMENT '房间id',
`step` INT default 0 COMMENT '谁出牌0,1,2,3',
`vids` VARCHAR(200) COMMENT '访客顺序',
`pokers` VARCHAR(200) COMMENT '扑克顺序',
`message` TEXT COMMENT '存放消息队列',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
4月5日
完成功能:出牌提示、判断是否可以出牌、不可出牌设置灰度、要不起自动出牌
待完成功能:托管自动出牌
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构