文档章节

JavaScript学习:21点游戏

北风其凉
 北风其凉
发布于 2016/02/02 22:46
字数 2006
阅读 782
收藏 6
点赞 1
评论 0

一、游戏规则

21点游戏的规则有很多种,我在写这个21点游戏的时候,选取了一种规则,描述如下:

1、游戏共有两名玩家,玩家1(庄家)和玩家2,在我编写的这个21点中,玩家1是电脑,玩家2是你,电脑坐庄。

2、一开始,给你和庄家各发两张牌,你可以看到你的两张牌,庄家的牌一张是明牌,一张是暗牌(暗牌是扣过来的牌,你不知道具体点数是多少)。

3、你和庄家的牌都是从一副牌里发出来的,共计52张(不要大小Joker)。

4、A可以当做1点和11点用,J、Q、K当做10点用,其他牌按面值计算点数。

5、发牌后,你可以选择要或不要牌,选择要牌后,如果你的点数大于21点,你就输了,否则你还可以选择要或不要牌,如果你选择不要牌,则轮到庄家要牌。

6、轮到庄家时,如果庄家的点数小于17点,则庄家必须要牌,当庄家点数大于或等于17时,庄家有权继续选择要或不要。如果庄家点数大于21点,则判定庄家输。

7、如果你和庄家都不要了,且双方都没有爆掉,则双方摊牌,计算双方点数,以点数大者胜,若双方点数一致则为平局。

二、目录结构

游戏的目录结构如下:

1、resource目录下,存储了游戏需要使用的图片。

2、bgm.ogg是游戏的背景音乐(我把QQ斗地主的背景音乐放进来了╮(╯▽╰)╭)

3、black_jack.html是一个网页,使用浏览器打开它就可以开始进行游戏了

4、black_jack.js存储了JavaScript代码

resource目录下的图片,包括纸牌图案、玩家头像等内容:

三、页面代码

black_jack.html页面代码如下:

<html>
    <head>
        <title>JS学习 - 21点 (black jack)</title>
    <meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
    </head>
    <style type="text/css">
        table th
        {
            text-align: center;
            text-decoration: none;
            font-weight: normal;
            padding: 3px 6px 3px 6px;
            width:200px;
        }
        table td
        {
            vertical-align: center;
            text-align: center;
            padding: 3px 6px 3px 6px;
            margin: 0px;
        }
    </style> 
    <body>
    <table width="100%">
      <tr> 
        <td>
          <div align="left">
            21点游戏 (Black Jack)
          </div>
        </td>
        <td>
          <div align="right">
            <audio width="300" height="10" controls autoplay="true" loop="true">
            <source src="bgm.ogg" type="video/ogg"/>
          </audio>
          </div> 
        </td>
      </tr>
    </table>
      <hr>
        <table id="tableboard">
      <tr>
        <td id="player1"><img src="resource\computer.png" /></td>
        <td/><td/><td/><td/><td/><td/><td/><td/><td/><td/><td/><td/><td/>
      </tr>
      <tr>
        <td id="player2"><img src="resource\player.jpg" /></td>
        <td/><td/><td/><td/><td/><td/><td/><td/><td/><td/><td/><td/><td/>
      </tr>
    </table>
    <hr>
    <table>
      <tr> 
        <td>
          <div id="score"></div>
        </td>
        <td>
          <div id="bulletin">请做出选择 (Please make a choice.)</div>
        </td>
      </tr>
    </table>
    <hr>
    <input type="button" id="hit" value="加一张牌 (HIT)" onclick="hit();" />
    <input type="button" id="stand" value="我不要了 (STAND)" onclick="stand();" />
    <!--<input type="button" id="restart" value="再玩一局 (FIGHT AGAIN)" onclick="location.reload();" />-->
    <input type="button" id="restart" value="再玩一局 (FIGHT AGAIN)" onclick="restart();" />
    <script src="black_jack.js"></script>
    </body>
</html>

black_jack.js页面代码如下:

//Firefox44.0,如果再来一局功能用location.reload()实现,则必须带上这两句话
//document.getElementById("hit").disabled = false;
//document.getElementById("stand").disabled = false;

var counter = 0; //发牌次数
var winner = ""; //胜利者 player1 - 电脑/player2 - 玩家
var hasStood = false; //标记玩家是否已经不要牌

//所有的牌
var cards = [
"club01", "club02", "club03", "club04", "club05", "club06", "club07", 
"club08", "club09", "club10", "club11", "club12", "club13", "diamond01", 
"diamond02", "diamond03", "diamond04", "diamond05", "diamond06", "diamond07",
"diamond08", "diamond09", "diamond10", "diamond11", "diamond12", "diamond13", 
"heart01", "heart02", "heart03", "heart04", "heart05", "heart06", "heart07", 
"heart08", "heart09", "heart10", "heart11", "heart12", "heart13", 
"spade01", "spade02", "spade03", "spade04", "spade05", "spade06", "spade07", 
"spade08", "spade09", "spade10", "spade11", "spade12", "spade13"];

//生成随机数
var getRand = function (begin, end) {
    return Math.floor(Math.random() * (end - begin)) + begin;
}

//洗牌
var rand, tmp;
for (var i = 0; i < 1000; i++) {
    rand = getRand(1, 52);
    tmp = cards[0];
    cards[0] = cards[rand];
    cards[rand] = tmp;
}

//玩家手牌
var cards1 = [getNewCard(), getNewCard()];
var cards2 = [getNewCard(), getNewCard()];

var table = document.getElementById("tableboard");
table.rows[0].cells[1].innerHTML = "<img src=\"resource\\cardback.png\" />";
table.rows[0].cells[2].innerHTML = "<img src=\"resource\\" + cards1[1] + ".jpg\" />";
table.rows[1].cells[1].innerHTML = "<img src=\"resource\\" + cards2[0] + ".jpg\" />";
table.rows[1].cells[2].innerHTML = "<img src=\"resource\\" + cards2[1] + ".jpg\" />";
showScore();

//玩家再要一张牌
function hit() {
    getNewCard("player2");
    if(checkIfBust("player2")) {
        document.getElementById("bulletin").innerHTML = "你爆了 (You BUST!)";
        document.getElementById("hit").disabled = true;
        document.getElementById("stand").disabled = true;
        winner = "player1";
    }
    showScore();
}

//玩家选择不要了
function stand() {
    hasStood = true;
    document.getElementById("hit").disabled = true;
    document.getElementById("stand").disabled = true;
    table.rows[0].cells[1].innerHTML = "<img src=\"resource\\" + cards1[0] + ".jpg\" />";
    //电脑开始要牌
    while (calcResult("player1") < 17) {
        getNewCard("player1");
        if(checkIfBust("player1")) {
            document.getElementById("bulletin").innerHTML = "电脑爆了 (Computer BUST!)";
            document.getElementById("hit").disabled = true;
            document.getElementById("stand").disabled = true;
            winner = "player2";
        }
    }
    //如两名玩家都未爆掉,则以分数高者为胜
    if (winner == "") {
        var result1 = calcResult("player1");
        var result2 = calcResult("player2");
        if (result1 == result2) {
            document.getElementById("bulletin").innerHTML = "平局 (PUSH!)";
        } else if (result1 > result2) {
            document.getElementById("bulletin").innerHTML = "你输了 (You LOSE)";
        } else if (result1 < result2) {
            document.getElementById("bulletin").innerHTML = "你赢了 (You WIN!)";
        }
    }
    showScore();
}

//获取一张新牌
function getNewCard(player) {
    var card = cards[counter++];
    if (player == "player1") {
        var len = cards1.length;
        cards1[len] = card;
        table.rows[0].cells[len + 1].innerHTML = 
            "<img src=\"resource\\" + cards1[len] + ".jpg\" />";
    } else if (player == "player2") {
        var len = cards2.length;
        cards2[len] = card;
        table.rows[1].cells[len + 1].innerHTML = 
            "<img src=\"resource\\" + cards2[len] + ".jpg\" />";
    }
    return card;
}

//判断当前情况是否爆掉
function checkIfBust(player) {
    var result = 0;
    if (player == "player1") {
        for (var i = 0; i < cards1.length; i++) {
            //parseInt一定要指定10进制,否则IE8下报错
            var c = parseInt(cards1[i].substr(cards1[i].length - 2), "10");
            if (c > 10) {
                c = 10;
            }
            result += c;
        }
        if (result > 21) {
            return true;
        } else {
            return false;
        }
    } else if (player == "player2") {
        for (var i = 0; i < cards2.length; i++) {
            var c = parseInt(cards2[i].substr(cards2[i].length - 2), "10");
            if (c > 10) {
                c = 10;
            }
            result += c;
        }
        if (result > 21) {
            return true;
        } else {
            return false;
        }
    }
}

//计算一名玩家的得分分数
function calcResult(player) {
    var result = 0;
    var countOfA = 0;
    if (player == "player1") {
        for (var i = 0; i < cards1.length; i++) {
            var c = parseInt(cards1[i].substr(cards1[i].length - 2), "10");
            if (c > 10) {
                c = 10;
            } else if (c == 1) {
                countOfA++;
            }
            result += c;
        }
        for (var i = 0; i < countOfA; i++) {
            if (result + 10 <= 21) {
                result += 10;
            } else {
                break;
            }
        }
    } else {
        for (var i = 0; i < cards2.length; i++) {
            var c = parseInt(cards2[i].substr(cards2[i].length - 2), "10");
            if (c > 10) {
                c = 10;
            } else if (c == 1) {
                countOfA++;
            }
            result += c;
        }
        for (var i = 0; i < countOfA; i++) {
            if (result + 10 <= 21) {
                result += 10;
            } else {
                break;
            }
        }
    }
    return result;
}

function showScore() {
    var result1 = calcResult("player1");
    var result2 = calcResult("player2");
    document.getElementById("score").innerHTML = 
        "[Computer : You = " + (hasStood == true ? result1 : "?") + " : " + result2 + "]";
}

function restart() {
    document.getElementById("hit").disabled = false;
    document.getElementById("stand").disabled = false;
    counter = 0; //发牌次数
    winner = ""; //胜利者 player1 - 电脑/player2 - 玩家
    hasStood = false; //标记玩家是否已经不要牌
    cards = [
    "club01", "club02", "club03", "club04", "club05", "club06", "club07", 
    "club08", "club09", "club10", "club11", "club12", "club13", "diamond01", 
    "diamond02", "diamond03", "diamond04", "diamond05", "diamond06", "diamond07",
    "diamond08", "diamond09", "diamond10", "diamond11", "diamond12", "diamond13", 
    "heart01", "heart02", "heart03", "heart04", "heart05", "heart06", "heart07", 
    "heart08", "heart09", "heart10", "heart11", "heart12", "heart13", 
    "spade01", "spade02", "spade03", "spade04", "spade05", "spade06", "spade07", 
    "spade08", "spade09", "spade10", "spade11", "spade12", "spade13"];
    //洗牌
    for (var i = 0; i < 1000; i++) {
        rand = getRand(1, 52);
        tmp = cards[0];
        cards[0] = cards[rand];
        cards[rand] = tmp;
    }
    //玩家手牌
    cards1 = [getNewCard(), getNewCard()];
    cards2 = [getNewCard(), getNewCard()];
    table.rows[0].cells[1].innerHTML = "<img src=\"resource\\cardback.png\" />";
    table.rows[0].cells[2].innerHTML = "<img src=\"resource\\" + cards1[1] + ".jpg\" />";
    table.rows[1].cells[1].innerHTML = "<img src=\"resource\\" + cards2[0] + ".jpg\" />";
    table.rows[1].cells[2].innerHTML = "<img src=\"resource\\" + cards2[1] + ".jpg\" />";
    //清空牌桌
    for (var i = 3; i < table.rows[0].cells.length; i++) {
        table.rows[0].cells[i].innerHTML = "";
        table.rows[1].cells[i].innerHTML = "";
    }
    showScore();
    document.getElementById("bulletin").innerHTML = "请做出选择 (Please make a choice.)";
}

/*
//播放背景音乐 - Chrome46.0.2490.80m有效,Firefox44.0无效
var mp3snd = "./bgm.ogg";
var bkcolor = "000000";
if (navigator.userAgent.toLowerCase().indexOf("msie") != -1) {
    document.write('<bgsound src="' + mp3snd + '" loop="-1">');
} else if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1) {
    document.write('<object data="' + mp3snd + '" type="application/x-mplayer2" width="0" height="0">');
    document.write('<param name="filename" value="' + mp3snd + '">');
    document.write('<param name="autostart" value="1">');
    document.write('<param name="playcount" value="infinite">');
    document.write('</object>');
} else {
    document.write('<audio src="' + mp3snd + '" autoplay="autoplay" loop="loop">');
    document.write('<object data="' + mp3snd + '" type="application/x-mplayer2" width="0" height="0">');
    document.write('<param name="filename" value="' + mp3snd + '">');
    document.write('<param name="autostart" value="1">');
    document.write('<embed height="2" width="2" src="' + mp3snd + '" pluginspage="http://www.apple.com/quicktime/download/" type="video/quicktime" controller="false" controls="false" autoplay="true" autostart="true" loop="true" bgcolor="#' + bkcolor + '"><br>');
    document.write('</embed></object>');
    document.write('</audio>');
}*/

 

四、效果演示

使用Firefox浏览器(版本号44.0)打开black_jack.html后,效果如下图所示:

游戏代码可以从这个链接下载到:http://pan.baidu.com/s/1c1v2MQk 

五、几点感受

1、我在IE8(版本8.0.7601.17514)、Chrome(版本46.0.2490.80 m)、Firefox(44.0)三个浏览器上测试了效果,除IE8中无法播放音乐外,其他功能都是正常的。

2、浏览器兼容性问题确实是个令人头疼的问题,就以parseInt函数来说,传入参数为"08"时,IE8返回0,Chrome和Firefox返回8。后来查了下才知道,原来IE8把字符串第一个字符为0的数字自动解析为八进制数了,需要在parseInt的第二个参数中强制指定使用十进制规则转换,才能让三个浏览器返回同样的结果。

3、说句题外话,这个游戏里,电脑赢的概率比你大,毕竟赌博游戏永远是庄家占便宜╭(╯^╰)╮。

END

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 114
博文 497
码字总数 462457
作品 4
朝阳
程序员
用于学习编程和 AI 的教学游戏 - WarriorJS

WarriorJS 是一个采用 JavaScript 开发的教学类游戏,用于学习 JavaScript 编程和人工智能。 简单地说,WarriorJS 是一个需要靠编写 JS 来玩的小游戏,启动后你需要不断攀爬 JS 世界,最终爬...

匿名
2015/05/26
0
0
如何入门微信小游戏开发,有哪些学习资料?

开发微信小游戏并非难事 1.首先,微信小游戏的开发方法 可以看到微信游戏的开发方式 答主有一些COCOS的开发经验,于是这里我们主要探讨COCOS制作小游戏的方法 2.需要学习什么 JS(JavaScrip...

qq_40126542
05/05
0
0
安利一个好玩的JS编程游戏—warriorjs

今天在Chrome的掘金插件上出现了一个好玩的项目—warriorjs。它的简介是这么写的: 官网&文档:https://warrior.js.org/ 安装十分简单,通过 npm 就行(前端的同学们一定会~) 剩下的只要写逻...

05/18
0
0
WarriorJS 0.4.0 发布,学习编程和 AI 的教学游戏

WarriorJS 是一个采用 JavaScript 开发的教学类游戏,用于学习 JavaScript 编程和人工智能。简单地说,WarriorJS 是一个需要靠编写 JS 来玩的小游戏,启动后你需要不断攀爬 JS 世界,最终爬上...

王练
05/22
0
0
宠物连连看2完整Android代码项目

宠物连连看2完整代码,该源码支持多种风格的连连看游戏的,如有国旗类的连连看,还有宠物连连看的等,基本的功能实现了无尽关卡挑战模式,还有催命倒计时,以及链接提示,暂停,多样图片集,...

tianlongbamu
2015/03/19
0
0
关于cocos2d-x VC模板的建立的问题

很早就听说过cocos2d-x这款开源2D游戏引擎,但最近才决定要学习下。我没有苹果电脑,也没有iphone和安卓智能手机,所以只能在windows平台学习它了。今天就碰到一个问题:按照网上的博客说双击...

熊友良
2012/07/19
0
0
开始征战CoffeeScript

最近在用clojurescript做游戏,感觉整个项目使用了很多工具来编程,但是在 效率及管理上都方便很多,整个项目的发布都是通过脚本自动实现的,降低了发布过程人为因素的影响。而在项目代码方便...

lav点搜
2012/11/08
0
0
thinkphp模型层Model、Logic、Service讲解

thinkphp模型层Model、Logic、Service讲解 时间:2014-08-24 15:54:56 编辑:一切随缘 文章来源:php教程网 已阅读:771 次 js特效源码,就从这里开始 我有疑问【PHP186论坛提问】 jS游戏桌球...

thinkyoung
2015/09/01
0
0
谷歌发布 Grasshopper,帮助用户学习 JavaScript

近日,谷歌内部孵化器发布了一款名为Grasshopper的应用程序,旨在帮助用户学习JavaScript语言。这款应用将JavaScript教学内容包含在一系列有趣的游戏中,其中包括调用函数,变量和字符串等内...

达尔文
04/21
0
0
cocos2d-x支持c++、js、lua开发

作者:左文 链接:https://www.zhihu.com/question/21130385/answer/21789568 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 纯属个人观点 1 Unity3d支...

壹峰
2017/10/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Tomcat内存设置

第一步骤: 1、路径是Tomcat目录下的/bin/catalina.bat文件 打开catalina.bat文件 加入下面这句代码: set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m 2、路径是...

一梦心草
10分钟前
0
0
IDEA 及 Gradle 使用总结

IDEA 及 Gradle 使用总结 自动编译组件 目前Android开发的主流开发工具是 Eclipse 和 IDEA 目前主流的自动化打包工具时 ant,maven,gradle。 maven工具中有自己的依赖仓库维护,很多开源支持...

舒文joven
10分钟前
0
0
lombok 引入后,测试类始终找不到get,set方法。

开发环境为idea,jdk1.7,maven3.5. 网上直接搜出来的方法有: 1、在setting里安装lombok的plugins; 2、如下图,勾选enable annocation processing选项 3、升级maven plugins插件 我尝试了以...

Kidult
11分钟前
0
0
Duang,HUAWEI DevEco IDE全面升级啦

想感受全新UI带来的视觉及交互体验、 HiKey970开发板调测、 HiAI API推荐和收藏、 深度AI模型分析等新功能, 体验高清晰度和流畅度的远程AI真机调测吗? 全新的UI设计 采用最优秀的视觉及交互...

华为终端开放实验室
20分钟前
0
0
阻止事件冒泡,阻止默认事件

1.event.stopPropagation()方法 这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开, 2.event....

闫亚亚
22分钟前
0
0
网络监控工具类

package com.guorentong.learn.organ.utils;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.net.ConnectivityManage......

王先森oO
22分钟前
0
0
命令

sudo nginx -s reload 重启nginx sudo lsof -i -P | grep -i "listen" 查看端口占用

那个猴子
26分钟前
0
0
用scrapy-redis爬去新浪-以及把数据存储到

需求:爬取新浪网导航页(http://news.sina.com.cn/guide/)所有下所有大类、小类、小类里的子链接,以及子链接页面的新闻内容。 准备工作: a.安装redis(windows或者linux) b.安装Redis Des...

丁典
26分钟前
0
0
PHP常用函数篇

1.为什么要使用函数? 除了内建的PHP函数,我们可以创建我们自己的函数。 函数是可以在程序中重复使用的语句块。 使代码逻辑更清晰 避免过多的全局变量 封装后避免相同逻辑重复代码,只需调用...

天地有涯风有信_大海无量不见人
27分钟前
0
0
对List分组

在日常工作中会遇到这样的情景,我们需要对List按照List中对象的一个值进行分组。比如一个Human的List,我们要根据性别分组,传统的方法是做双层循环,逐个对比,今天我要介绍一种详单简单的...

珂jack
29分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部