简陋的斗地主,js实现
最近闲了两天没事做,用js写了个斗地主,练习练习。代码和功能都很简陋,还有bug,咋只是聊聊自己的思路。
这里说说斗地主主要包含的功能:洗牌,发牌,玩家出牌、电脑出牌,出牌规则的验证,输赢啥的没有判断,只是实现了这几个主要功能,下面依次说说几个功能的实现:
1.洗牌:
var pukes=this.manage.pukes;//存放扑克牌的数组
//洗牌
for(var i=0;i<pukes.length;i++){
var tmp=pukes[i];
var index=util.random(i,pukes.length);//随机交换两张牌
pukes[i]=pukes[index];
pukes[index]=tmp;
}
2.发牌(简版默认是玩家自己为地主,电脑为农民),由于前面洗牌时已经将牌的顺序打乱,所以发牌只是简单的循环把pukes中的元素添加到每个玩家实例中的pukes字段中。
//发牌
var start=0;
for(var i=0;i<this.manage.pukes.length-3;i++) {
if(start==this.manage.players.length){
start=0;
}
this.manage.pukes[i].status=true;
this.manage.players[start].pukesLen++;
this.manage.players[start++].pukes.push(this.manage.pukes[i]);
}
for(var i=this.manage.pukes.length-3;i<this.manage.pukes.length;i++){
//地主多三张
this.manage.pukes[i].status=true;
this.manage.players[this.manage.curPlayerIndex].pukesLen++;
this.manage.players[this.manage.curPlayerIndex].pukes.push(this.manage.pukes[i]);
}
3.玩家出牌,玩家出牌分为电脑和玩家自己两个步骤,电脑出牌是非常傻瓜的出牌方式(有牌就出):
//出牌
if(this.options.playerIndex==this.manage.curPlayerIndex) {
var spks = [],gz=false; if (this.manage.curMaxPlayerIndex == this.options.playerIndex) {
this.manage.deskPukes = [];
}
if (this.isCompute) {
//电脑自动出牌
var start = 0;
var len=this.manage.deskPukes.length||1;
while (start < this.pukes.length) {
spks = [];
for (var i = 0,j=start; i <len&&j<this.pukes.length; i++) {
//随便选一张 可以出就行
if(this.pukes[j].status) {
spks.push(this.pukes[j++]);
}
}
if(spks.length) {
if (rules.valids(spks, this.manage.deskPukes)) {
gz = true;
break;
}
}
start++;
}
}
else {
//玩家选择出牌
for (var i = 0; i < this.pukes.length; i++) {
if (this.pukes[i].selected && this.pukes[i].status) {
spks.push(this.pukes[i]);
}
}
if (rules.valids(spks, this.manage.deskPukes)) {
gz=true;
}
else{
alert("出牌不符合规则!");
}
}
if(gz){
this.manage.curMaxPlayerIndex=this.options.playerIndex;
this.manage.deskPukes = [];
for (var i = 0; i < spks.length; i++) {
this.pukesLen--;
this.manage.deskPukes.push(spks[i]);
spks[i].status = false;
}
}
this.manage.renderPukes();
this.manage.renderCurDiscard();
if(this.isCompute||gz) {
this.manage.nextPlayer();
}
}
else{
alert("没轮到你出牌!");
}
4.出牌规则的验证,是很多函数组合起来,然后循环调用,如果遇到返回ture的即为出牌符合规则:
//以下为出牌规则
var rules={
_rules:[
new danzRule(),
new duiRule(),
new sandRule(),
new zandRule(),
new shunzRule(),
new liandRule()
],
valids:function(_pukes,_curPukes){
for(var i=0;i<this._rules.length;i++){
if(this._rules[i].valid(_pukes,_curPukes)){
return true;
}
}
return false;
}
}; function danzRule(){
//单张规则
}
danzRule.prototype.valid=function(_pukes,_curPukes){
//校验
var pukes=_pukes;//玩家的牌
var curPukes=_curPukes;//左面的牌
if(pukes&&pukes.length==1){
//比较牌面值
if(!curPukes||!curPukes.length){
return true;
}
if(curPukes[0].dians==2&&pukes[0].dians<15){
//2特殊处理
return false;
}
if(pukes[0].dians==2&&curPukes[0].dians<15){
//2特殊处理
return true;
}
return pukes[0].dians>curPukes[0].dians;
}
return false;
} function duiRule(_pukes,_curPukes){
//两张规则 }
duiRule.prototype.valid=function(_pukes,_curPukes){
//校验
var pukes=_pukes;//玩家的牌
var curPukes=_curPukes;//左面的牌
if(pukes&&pukes.length==2){
//比较牌面值
if(pukes[0].dians>14&&pukes[1].dians>14){
return true;
}
if(pukes[0].dians!=pukes[1].dians){
return false;
}
if(!curPukes||!curPukes.length){
return true;
}else {
if(curPukes.length!=2){
return false;
}
if (curPukes[0].dians > 14 && curPukes[1].dians > 14) {
return false;
}
if (curPukes[0].dians != curPukes[1].dians) {
return false;
}
if (curPukes[0].dians == 2) {
return false;
}
}
if(pukes[0].dians==2){
return true;
}
return pukes[0].dians>curPukes[0].dians;
}
return false;
} function sandRule(){
//三带
}
sandRule.prototype.valid=function(_pukes,_curPukes){
//校验 var pukes=_pukes;//玩家的牌
var curPukes=_curPukes;//左面的牌
if(pukes&&(pukes.length>=3)){
//比较牌面值
var books=getBooks(pukes);
if(!valid(books))return false;
if(!curPukes||!curPukes.length)return true;
if(curPukes.length!=books.length)return false;
var books2=getBooks(curPukes);
if(!valid(books2))return false;
return getSum(books)>getSum(books2);
}
return false; function getSum(books){
var sum=0;
for(var i=0;i<books.length;i++) {
if(books[i]==3){
if(i==2)return 9999;
sum+=i;
}
}
return sum;
}
function valid(books){
//验证三带是否有效
var counts3= 0,countsd= 0,d2=true,start=false,startIndex=-1; for(var i=0;i<books.length;i++) {
if(start&&books[i]==3&&startIndex!=(i-1)){
return false;
}else{
startIndex=i;
}
if(books[i]==3){
if(!start) {
start = true;
startIndex = i;
}
counts3++;
}
if(books[i]==1){
d2=false;
}
} for(var i=0;i<books.length;i++) {
if(d2&&books[i]==2){
countsd++;
}
else if(!d2&&books[i]==1){
countsd++;
}
}
return counts3>0&&counts3==countsd;
} function getBooks(pukes){
//返回三带的每个点数的个数
var books=[];
for(var i=0;i<pukes.length;i++){
if(!books[pukes[i].dians]){
books[pukes[i].dians]=1;
}else{
books[pukes[i].dians]++;
}
}
return books;
}
} function zandRule(){
//炸弹
}
zandRule.prototype.valid=function(_pukes,_curPukes){
var pukes=_pukes;//玩家的牌
var curPukes=_curPukes;//左面的牌
if(pukes&&pukes.length==4) {
if(!allEqual(pukes)){
return false;
}
if(!curPukes||(curPukes.length>0&&curPukes.length!=4)||!allEqual(curPukes)){
return true;
}
else{
if(pukes[0].dians==2){
return true;
}
if(curPukes[0].dians==2){
return false;
}
return pukes[0].dians>curPukes[0].dians;
} }
return false; function allEqual(pukes){
if(!pukes||!pukes.length)return false;
var base=pukes[0].dians;
for(var i=1;i<pukes.length;i++){
if(base!=pukes[i].dians){
return false;
}
}
return true;
} } function liandRule(){
//连对
}
liandRule.prototype.valid=function(_pukes,_curPukes) {
var pukes=_pukes;//玩家的牌
var curPukes=_curPukes;//左面的牌
if(pukes&&pukes.length>=6) {
if(!verificationCoherence(pukes)){
return false;
}
if(!curPukes||curPukes.length<=0){
return true;
}
if(!verificationCoherence(curPukes)){
return false;
}
if(pukes.length!=curPukes.length){
return false;
}
return getSumDians(pukes)>getSumDians(curPukes);
}
return false;
function getSumDians(pukes){
var sum=0;
for(var i=0;i<pukes.length;i++) {
sum+=pukes[i].dians;
}
return sum;
} function verificationCoherence(pukes){
//验证连贯性
if(!pukes||!pukes.length)return false;
var books=[];
for(var i=0;i<pukes.length;i++){
if(pukes[i].dians==2||pukes[i].dians>14){
return false;
}
if(!books[pukes[i].dians]){
books[pukes[i].dians]=1;
}else{
books[pukes[i].dians]++;
}
if(books[pukes[i].dians]>2){
return false;
}
}
var start=false; for(var i=0;i<books.length;i++) {
if(books[i]&&books[i]!=2){
return false;
}
if(books[i]==2&&!start){
start=true;
}
if(start&&books[i]!=2){
return false;
}
} return true;
}
}
function shunzRule(){
//顺子
}
shunzRule.prototype.valid=function(_pukes,_curPukes){
var pukes=_pukes;//玩家的牌
var curPukes=_curPukes;//左面的牌
if(pukes&&pukes.length>=5) {
if(!verificationCoherence(pukes)){
return false;
}
if(!curPukes||curPukes.length<=0){
return true;
}
if(!verificationCoherence(curPukes)){
return false;
}
if(pukes.length!=curPukes.length){
return false;
}
return getSumDians(pukes)>getSumDians(curPukes);
}
return false; function getSumDians(pukes){
var sum=0;
for(var i=0;i<pukes.length;i++) {
sum+=pukes[i].dians;
}
return sum;
} function verificationCoherence(pukes){
//验证连贯性
if(!pukes||!pukes.length)return false;
var books=[];
for(var i=0;i<pukes.length;i++){
if(pukes[i].dians==2||pukes[i].dians>14){
return false;
}
if(!books[pukes[i].dians]){
books[pukes[i].dians]=1;
}else{
return false;
}
}
var start=false;
for(var i=0;i<books.length;i++) {
if(books[i]==1&&!start){
start=true;
}
if(start&&!books[i]){
return false;
}
}
return true;
} }
以上4步,是我认为的主要的4个函数,其他的函数,如初始化,事件注册等,在源码已有注释,写的不好勿喷。
附上源码:http://files.cnblogs.com/files/csbt/DDZ.zip
简陋的斗地主,js实现的更多相关文章
- 基于node.js+socket.io+html5实现的斗地主游戏(1)概述
一.游戏描述 说是斗地主游戏,其实是寝室自创的"捉双A",跟很多地方的捉红10.打红A差不多,大概规则是: 1.基础牌型和斗地主一样,但没有大小王,共52张牌,每人13张,这也是为 ...
- 用JS实现一个斗地主发牌器
//调用随机数,在我上一篇博文讲过这一个函数. function roundNum(min = 0, max = 0) { if (!isNaN(min) && !isNaN(max) ...
- JS实现简单斗地主效果
let play = document.querySelectorAll(".play"); let dizhupai = document.getElementById(&quo ...
- Vue.js——60分钟组件快速入门(下篇)
概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:"嘿,老哥,我开 ...
- Vue.JS 对比其他框架
Angular 选择 Vue 而不选择 Angular,有下面几个原因,当然不是对每个人都适合: 在 API 与设计两方面上 Vue.js 都比 Angular 简单得多,因此你可以快速地掌握它的全部 ...
- Knockout.js随手记(4)
动态绑定下拉列表 在<select> data-bind的options选项如果绑定到ko.observableArray(),就可以动态新增选项效果,也就是可以利用其完成常见的级联效果的 ...
- 使用three.js创建3D机房模型-分享一
序:前段时间公司一次研讨会上,一市场部同事展现了同行业其他公司的3D机房,我司领导觉得这个可以研究研究,为了节约成本,我们在网上大量检索,最后找到一位前辈的博文[TWaver的技术博客],在那篇博文的 ...
- paip.php 与js 的相似性以及为什么它们这么烂还很流行。。
paip.php 与js 的相似性以及为什么它们这么烂还很流行.. php与js异常的流行,web 90%都被他们统治了.发现了他们有意思的一些共性.. 结构一番总结,得出了它们共有的特点.特性: = ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)
这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...
随机推荐
- MySQL-client-5.6.36-1.linux_glibc2.5.x86_64.rpm安装详解
centos6.8已经安装了mysql,所以要卸载掉 查看命令 rpm -qa | grep mysql 注意:MySQL区分大小写 grep mysql 和grep MySQL 是不一样的!! 卸载 ...
- Python pip 下载速度慢? Windows 设置 国内源,用 阿里云 国内镜像 加速
pip 提供了对 Python 包的查找.下载.安装.卸载的功能,是非常方便的 Python 包管理工具.但是,令人苦恼的是 pip 在国内的下载速度非常慢,速度常常只有每秒几十 K,甚至才几 K,小 ...
- Matrix 矩阵
CSS3中的矩阵指的是一个方法,书写为matrix()和matrix3d(),前者是元素2D平面的移动变换(transform),后者则是3D变换.2D变换矩阵为3*3, 如上面矩阵示意图:3D变换则 ...
- mac链接linux终端,shell脚本发布代码
项目的业务需求:从mac端直接连上linux服务终端,并发布相关的代码 一.使用ssh链接上linux服务端 1.cd ~/.ssh 2.vi config,按照下面的内容配置config文件,然后: ...
- DNA序列对齐问题
问题描述: 该问题在算法导论中引申自求解两个DNA序列相似度的问题. 可以从很多角度定义两个DNA序列的相似度,其中有一种定义方法就是通过序列对齐的方式来定义其相似度. 给定两个DNA序列A和B,对齐 ...
- 分页查询时,使用cookie保存上次的查询条件。jQuery实现方法以及中间遇到的坑
今天做分页查询时需要在跳转页面时保存上次查询的条件,如下: 实现的大致思路就是用cookie本地保存. 其中需要用到jQuery.Cookie插件. 使用方法很简单: 存数据:$.cookie(“ke ...
- C#编写的艺术字类方法
代码如下: using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing ...
- 使用Dropwizard(2)-配置分类ConfiguredBundle
前言 不可避免的要用dropwizard作为service框架.持续学习.上次在dropwizard中使用feign,使用hystrix, 算是基本入门了.接下来就是基于此的优化. 把需要使用Conf ...
- CSS样式命名整理(非原创)
非原创,具体出自哪里忘了,如果侵害您的利益,请联系我. CSS样式命名整理 页面结构 容器: container/wrap 整体宽度:wrapper 页头:header 内容:content 页面主体 ...
- CentOS6.9编译安装Nginx1.12
1:安装必要的库 Bash yum install gc gcc gcc-c++ pcre-devel zlib-devel openssl-devel 2:创建Nginx用户和组 Bash grou ...