为什么21点拿到相同两张牌比点数叫什么的牌不算平局?

主机专题:
     
掌机专题:
     
您的当前位置:>
《荒野大镖客 赎罪》BlackJack21点玩法规则+基本战术
发布时间: 14:00:02 条|
  作者:a9vg --tekkenman--
  今天有人发站内信给我问我玩Blackjack的玩法,我就介绍下
  BlackJack也叫21点,这个属于输得快,赢得也快的游戏,特别如果去赌场,建议和荷官玩不要和机器玩,机器的软件都是人设计的,说没有作弊暗算你是不可能的。荷官和机器差不多,也会作弊暗算,但是他总有懒惰和疲倦的时候,所谓赌博要和人赌不要和机器赌,就是这个道理。
  21点规则
  & 每个玩家都是和庄家对赌。21点的目的就是要拿到好过庄家牌的同时不超过21点。每张牌都有自己的点数,把牌的点数加在一起就得到了你这一手的点数。
  & 牌的点数如下:花面牌(国王/King,王后/Queen,和杰克/Jack)是10点,A是1点或者11点。你可以自己选择A是1点或者11点来组成你最好的牌,这是没有规定限制的。所有其它的牌(2-10)的点数和牌面点数相同。牌的花样在这个游戏里没有意义。
  & 一手有A的牌里有&soft total&,这里A可以被认为1点或者11点,只要不超过21点。玩家可以要另外一张牌同时A还是1点来避免爆点。如果你必须使用一个点数或者另一个点数,这叫&hard total& 。
  & 正规赌场的21点是用8副牌来玩的,每一手后都会洗牌。
  玩21点
  & 当下注后,玩家和庄家都会收到2张牌。
  & 庄家会显示其中一张牌,其它的牌则会正面朝下知道游戏结束。
  & 游戏会在玩家告诉庄家他在轮到他行动时将如何进行这手牌而继续。
  & 在所有玩家完成这手牌的行动后,庄家也将会完成牌的行动并且计算输赢。
  & 如果你在你最开始得到的2张牌上得到21点(A&10),那么你就得到一个blackjack/黑杰克.得到blackjack你可以赢取你所下赌注的1.5倍。
  & 如果玩家和庄家同时都得到blackjack,那么这手牌为平局。
  & 如果你这手牌的点数超过21点,那么你就爆点,庄家会赢得注金和不显示他的牌。
  玩21点的基本战术
  在左边的部分解释了你在见到庄家牌和得到自己牌时理论上应该hit/加牌,stand/保持,double/加倍或者split/分拆。这是一个很有用的战术工具,在你玩在线21点时应该参考。这对新的玩家也是很有帮助的。以下就是战术图:
  YOUR HAND: 你的牌
  Dealer's CARD: 庄家的牌
  hit/加牌,
  stand/保持,
  double/加倍,
  split/分拆,
  doublestand/加倍保持,
  splitHIT/分拆加牌,
  SurrenderSplit/投降分拆,
  SurrenderHit/投降加牌,
  SurrenderStand/投降保持
  Surrender/投降
  & 在surrender时,你会损失初始赌注的一半。
  & 只可以在其它动作像hit,split,double之前的刚刚开始游戏时选择surrender。
  & 只在只有低于等于25%的赢得游戏的机会时选择serrender。
  Hitting/加牌 或 Standing/保持
  & Hit就是要多一张牌来增加自己这手牌的点数。
  & Stand就是保持现有的牌然后结束回合。
  & 为了得到最好的结果,请参考上边的21点战术图。
温馨提示:玩家可通过手机登陆阅读多玩TVG新闻。
看完本文后有何评价?
已有0人评价,点选表情后可看到其他玩家的表态。
极限、恶搞
杂谈图集精选
特色专区: |
PSP游戏: |
3DS游戏: |
家机游戏: |
综合主区: |推荐这篇日记的豆列
······4098人阅读
大三了,刚学JAVA这门课,老师留了一道课后习题:
·&完成一个变形版的纸牌21点游戏。该游戏来源于21点游戏,实现人机对战。
游戏说明如下:
(1)该游戏需要两副牌,没有Joker,共104张。每张“纸牌”应具有花色与数字两个属性。
(2)游戏在机器与人类玩家之间进行。游戏一开始应先洗牌(将104张牌打乱)。
(3)机器永远是庄家,所以永远先给机器发牌,机器的牌不可见,只能看到机器要了几张牌。机器停止要牌后,再给人类玩家发牌。
(4)游戏胜利与失败的条件与普通21相同;除此以外,一方在当前牌没有爆掉的前提下,如果下一张牌使得手中有两张完全一样的牌(同数字、同花色)则立刻胜利。
(5)游戏结束时机器的牌要全部显示,并提示谁胜利了。
程序设计要求如下:
(1)程序中应至少有Card类和CardGame类。
(2)Card类需要重写Object类的equals(Object o)函数,用于比较两张牌是否完全一样;重写toString函数,用于输出牌时直接显示牌的花色与数字。
(3)CardGame类应具有shuffle(洗牌)、deal(发牌)、win(胜利判别)等函数。
(4)选择适当的java集合类来实现“发牌牌堆”和“手牌”(不允许都使用数组)。
看完题目之后,我是无从下手啊。对于我这种初学JAVA的菜鸟(大一C++又没有学好),估计花个三天三夜都不一定能编出来。有句话说:“高手都是从模仿开始的。”我就上网搜罗到了下面的代码并加以修改,对不懂的地方逐一进行了学习。
* To change this template, choose Tools | Templates
* and open the template in the editor.
package 21
import java.util.ArrayL
import java.util.S
* @author Soledad
public class Main {
* @param args the command line arguments
public static void main(String[] args) {
CardGame cg = new CardGame();
cg.startGame();
// TODO code application logic here
enum Color{
HEARTS, DIAMOND, SPADE, CLUB
//红桃,方块,黑桃,梅花
}//***************学习点之一***************
class Card {
private Color cardC
//牌的花色
//牌的面值
public Card(){
public Card(Color c, int num) {
cardColor =
} //相当于C++中的赋值构造函数
public boolean equals(Object obj) {
if (obj == null)
if (obj instanceof Card){
return ((Card)obj).cardColor == this.cardColor &&((Card)obj).number == this.
}//***************学习点之二***************
public int hashCode() {
int hash = 7;
hash = 59 * hash + (this.cardColor != null ? this.cardColor.hashCode() : 0);
hash = 59 * hash + this.
}//****************学习点之三***************
public String toString() {
String numberString = &&;
if (cardColor == Color.HEARTS)
symbol = &红心&;
else if (cardColor == Color.DIAMOND)
symbol = &方块&;
else if (cardColor == Color.SPADE)
symbol = &黑桃&;
symbol = &梅花&;
if (number == 11) {
numberString += &J&;
} else if (number == 12) {
numberString += &Q&;
} else if (number == 13) {
numberString += &K&;
} else if (number == 1){
numberString += &A&;
numberString +=
return symbol + &
& + numberString + &
}//****************学习点之四****************
public Color getCardColor() {
return cardC
public void setCardColor(Color cardColor) {
this.cardColor = cardC
public int getNumber() {
public void setNumber(int number) {
this.number =
class CardGame{
private Card[] cardH
private int cardHeapP
//发到第几张牌了
private ArrayList&Card&
//玩家手牌
private ArrayList&Card&
//电脑手牌
//***************学习点之五***************
public CardGame() {
cardHeap = new Card[104];
playerCards = new ArrayList&Card&();
computerCards = new ArrayList&Card&();
for(int i = 0; i & 104; i += 4 ) {
for(int j = 0; j & 4; j ++) {
switch(j){
cardHeap[i + j] = new Card(Color.HEARTS, i % 13 + 1);
cardHeap[i + j] = new Card(Color.DIAMOND, i % 13 + 1);
cardHeap[i + j] = new Card(Color.CLUB, i % 13 + 1);
cardHeap[i + j] = new Card(Color.SPADE, i % 13 + 1);
}//通过两个循环分配给牌组两副牌(去除Jokers)
void showCards(ArrayList&Card& cards) {
for(Card element:cards) {
System.out.print(element);
}//****************学习点之六***************
System.out.println();
void shuffle(){
cardHeapPos = 0; //归零
Card[] tempHeap = new Card[104];
for(int i = 0 ; i & 104; i ++) {
pos = (int)(Math.random() * 104);//**************学习点之七****************
for(int j = 0; j & 104; j ++){
if(null == tempHeap[pos]) { //表示该空位没有分配值
tempHeap[pos] = new Card( cardHeap[i].getCardColor(), cardHeap[i].getNumber());
pos = (pos + 1) % 104;
}//随机发牌堆到tempHeap中
for(int i = 0; i & 104; i ++) {
cardHeap[i].setCardColor(tempHeap[i].getCardColor());
cardHeap[i].setNumber(tempHeap[i].getNumber());
}//复制回原数组
void deal(ArrayList&Card& cards) {
cards.add(cardHeap[++cardHeapPos]);
void gameOver(){
System.out.println(&庄家的牌&);
showCards(computerCards);
System.out.println(&庄家的总点数为 :& + getValue(computerCards));
System.out.println(&你的牌&);
showCards(playerCards);
System.out.println(&你的总点数为 :& + getValue(playerCards));
int getValue(ArrayList&Card& cards) {
int value = 0;
for(Card e:cards) {
if (e.getNumber() &= 10)
value += 10;
else if (e.getNumber() == 1)
value += 11;
//抽到“A”的时候是加1或加11, 这里先把加11
value += e.getNumber();
if(value & 21) {
for(Card e:cards) {
if (e.getNumber() == 1){
value -= 10;
if (value & 21)
//如果小于21就跳出了
if(value & 21)
return -1;
boolean haveSame(ArrayList&Card& cards) {
for(int i = 0; i & cards.size(); i ++) {
for(int j = i + 1; j & cards.size(); j ++) {
if (cards.get(i).equals(cards.get(j))) {
}//return true表示cards中出现完全重复的牌
void startGame() {
boolean finish =
Scanner in = new Scanner(System.in);//****************学习点之八****************
String playerInput = &&;
while(!finish) {
playerCards.clear();
computerCards.clear();
shuffle();
//庄家摸牌
System.out.println(&庄家摸牌...&);
int computerValue = 0;
boolean getWinner =
Thread.sleep(3000);
catch(InterruptedException e) {
e.printStackTrace();
//如果庄家的总点数等于或少于16点,则必须拿牌,否则停牌
while(computerValue &= 16) {
deal(computerCards);
getWinner = haveSame(computerCards);
if (getWinner) {
System.out.println(&庄家摸到了完全相同的牌,赢得了胜利!!!&);
gameOver();
computerValue = getValue(computerCards);
if (computerValue == -1) {
System.out.println(&你赢了, 庄家牌摸爆了!!!&);
gameOver();
getWinner =
if(!getWinner) {
System.out.println(&庄家共有 & + computerCards.size() + & 张牌&);
while(!playerInput.equals(&n&)) {
deal(playerCards);
getWinner = haveSame(playerCards);
if (getWinner) {
System.out.println(&你摸到了完全相同的牌,赢得了胜利!!!&);
gameOver();
System.out.println(&你的牌:&);
showCards(playerCards);
int playerValue = getValue(playerCards);
if (playerValue == -1) {
System.out.println(&庄家赢了, 你牌摸爆了!!!&);
gameOver();
getWinner =
System.out.println(&总点数为 & + getValue(playerCards));
System.out.println(&是否继续要牌(y/n)?&);
playerInput = in.nextLine();
if(!getWinner) {
switch(win()) {
case 1: //玩家胜利
System.out.println(&你胜利了!!!&);
gameOver();
System.out.println(&平局!!!&);
gameOver();
System.out.println(&庄家获胜!!!&);
gameOver();
System.out.println(&是否继续游戏(y/n)?&);
playerInput = in.nextLine();
if(playerInput.equals(&n&))
//如果是用户不再摸牌而调用win, 则finish 设置为ture
//返回1,说明玩家胜利
//返回2,说明平局
//返回3,说明电脑胜利
int win() {
//havaSame和双方是否爆牌已经在之前判断了(一旦有相同牌则获胜,一旦爆牌则失败,可见这两种情形优先级较高)
int playerValue = getValue(playerCards);
int computerValue = getValue(computerCards);//获取玩家和电脑的总点数
if (playerValue & computerValue)
else if (playerValue == computerValue)
· 学习点之一:用enum枚举
enum一般用来枚举一组相同类型的常量。如性别、日期、月份、颜色等。对这些属性用常量的好处是显而易见的,不仅可以保证单例,且要作比较的时候可以用”== ”来替换”equals”,是一种好的习惯(如本例中第45行)。
用法:如:
publicenum SexEnum {
本例中的花色:
enum Color{
HEARTS, DIAMOND, SPADE, CLUB
//红桃,方块,黑桃,梅花
需要注意的是,枚举对象里面的值都必须是唯一的,特别的,我们可以还通过enum类型名直接引用该常量,比如本例中的121,124,127等行通过类型名直接引用。
除此之外,我们还可以往enum中添加新方法,这里就不加介绍了。
· 学习点之二:重写equals函数进行比较
&&&&& equals(Object o)函数原本是Object类下面的函数,我查了一下JAVA的API,截图如下:
简而言之,如果JAVA中默认的equals方法跟实际不符的话,就需要重写equals方法。我们这里要对牌是否相同作比较,因此需要重写该方法(第40~50行):
public boolean equals(Object obj) {
if (obj == null)
//如果参数为空直接返回false
if (obj instanceof Card){
return ((Card)obj).cardColor == this.cardColor &&((Card)obj).number == this.//如果花色数字均相同则返回true否则false
//类型不一致返回false
另外我们注意到API里面写着:
“注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。”这也就是我们下面要学习的第三点。
· 学习点之三:重写hashcode()
问:也许上面的话有些晦涩难懂啊,我们为什么要重写hashcode()方法呢?
答: object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() ==obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址。
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
总而言之,这样如果我们对一个对象重写了equals,意思是只要对象的成员变量值都相等那么equals就等于true,但不重写hashcode,那么我们再new一个新的对象,当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,导致混淆,因此,就也需要重写hashcode()。
更通俗的说:
Object中的hashcode()方法在我们创建对象的时候为每个对象计算一个散列码,这个散列码是唯一的,所以如果2个对象的散列码相同,那他们一定是同一个对象。
自己定义的类也可以重写hashCode()方法,按照自己定义的算法计算散列码的生成。
Object中的equals()方法,比较的是2个对象的引用地址,包括他们各自的散列码,如果不同,就认为是不同的对象。
String类中重写了equals方法,比较的是他们字符串的内容。
在我们这里自己定义的算法是(第53~58行):
public int hashCode() {
int hash = 7;
hash = 59 * hash + (this.cardColor != null ? this.cardColor.hashCode() : 0);
hash = 59 * hash + this.
· 学习点之四:重写toString()函数
因为它是Object里面已经有了的方法,而所有类都是继承Object,所以“所有对象都有这个方法”。
它通常只是为了方便输出,比如System.out.println(xx),括号里面的“xx”如果不是String类型的话,就自动调用xx的toString()方法。然而对于默认的toString()方法往往不能满足需求,需要重写覆盖这个方法。
比较易懂,就不具体说明了,见代码60~86行。
·学习点之五:动态数组ArrayList
&&&&& 动态数组,即可以将 ArrayList想象成一种“会自动扩增容量的Array”。它的优点是可以动态地插入和删除元素,但牺牲效率。
有关使用ArrayList的例子,参考,里面介绍的很详细。在我们这题中,由于电脑和玩家的手牌都会因为抽牌而增加,因此将二者均设为ArrarList(第114,115行),方便动态插入。
· 学习点之六:增强for循环
&&&&& 见代码138~140行,很多人没看懂for(Card element:cards) 这段,其实这是JDK5.0的新特性,作用是遍历数组元素。其语法如下:
for(type element: array){
System.out.println(element);
· 学习点之七:善于使用随机数
&&&&& 直接调用Math.random()可以产生一个[0,1)之间的随机数,注意区间是前闭后开的。本题当中因为共有104张牌,那么我们直接用(int)Math.random()*104即可以产生[0,104)之间的随机数,对应一下数组的下标前闭后开刚好满足。
· 学习点之八:利用Scanner进行输入
&&&&& 我们都知道,JAVA里输入输出函数十分的麻烦,尤其是输入。可喜的是,从SDK1.5开始,新增了Scanner类,简化了输入函数。如本题的221行:Scanner in=new Scanner(System.in) 首先创建了一个in对象,然后in对象可以调用下列方法,读取用户在命令行输入的各种数据类型: nextDouble(), nextFloat, nextInt(),nextLine(),nextLong()等,上述方法执行时都会造成堵塞,等待用户在命令行输入数据回车确认,例如本题中的第279行,在系统问询是否继续要牌(y/n)后,用in.nextLine()来接受玩家输入的值。
说了这么多,我们来运行下程序:
e….我什么都没干 输了- -;
再来一次。。。
平局。。。行,就这样了,不要欺负电脑了。
我们再回到题目和代码:
·&完成一个变形版的纸牌21点游戏。该游戏来源于21点游戏,实现人机对战。
游戏说明如下:
(1)该游戏需要两副牌,没有Joker,共104张。每张“纸牌”应具有花色与数字两个属性。--直接对应代码24~37,60~102,117~134行
(2)游戏在机器与人类玩家之间进行。游戏一开始应先洗牌(将104张牌打乱)。--直接对应代码144~166行
(3)机器永远是庄家,所以永远先给机器发牌,机器的牌不可见,只能看到机器要了几张牌。机器停止要牌后,再给人类玩家发牌。--直接对应代码224~280行
(4)游戏胜利与失败的条件与普通21相同;除此以外,一方在当前牌没有爆掉的前提下,如果下一张牌使得手中有两张完全一样的牌(同数字、同花色)则立刻胜利。--直接对应代码181~205,208~217,311~323行
(5)游戏结束时机器的牌要全部显示,并提示谁胜利了。--直接对应代码172~179,283~297行
程序设计要求如下:
(1)程序中应至少有Card类和CardGame类。
(2)Card类需要重写Object类的equals(Object o)函数,用于比较两张牌是否完全一样;重写toString函数,用于输出牌时直接显示牌的花色与数字。
(3)CardGame类应具有shuffle(洗牌)、deal(发牌)、win(胜利判别)等函数。
(4)选择适当的java集合类来实现“发牌牌堆”和“手牌”(不允许都使用数组)。
总结:这还只是JAVA的初级阶段,作为初学者还希望大家多多指教。
(有疑问的在下面评论交流)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11892次
排名:千里之外天堂鸟国际官网_天堂鸟国际官网官网21点游戏 - 开源中国社区
当前访客身份:游客 [
当前位置:
发布于 日 21时,
那次在贴吧看见有人求代码,就写了一个。
水平有限,写的不好。
GCC编译通过
代码片段(2)
1.&[代码][C/C++]代码&&&&
#include &iostream&
int pai[4][13] = {0};
int pc[7] = {0};
int ren[7] = {0};
int pcs = 0;
int rens = 0;
//洗牌函数
void xipai()
for(int i = 0; i & 13; ++i)
for(int j = 0; j & 4; ++j)
pai[j][i] = i+1;
//发牌函数,z张数,p谁,x p发了第几张了
void fapai(int z, int *p, int &x)
srand((unsigned)time(NULL));//随机初始化
for(int i = 0; i & ++i)
int a = rand() % 4;
int b = rand() % 13;
if(pai[a][b] &0)
p[x] = pai[a][b];
pai[a][b] = -1;
cout && "黑桃 ";
cout && "红桃 ";
cout && "方块 ";
cout && "梅花 ";
cout && p[x];
//判断21点
int pd(int *p, int x)
int sum = 0;
for(int i = 0; i & ++i)
sum += p[i];
//判断输赢
enum shuying{lose,level,win,other};
shuying pdsy(int *p,int ps,int *r,int rs)
int rss=pd(r,rs);
int pss=pd(p,ps);
if(rss&21&&pss&21)
if(rss&21&&pss&21)
if(rss&21&&pss&21)
if(rss&pss)
if(rss&pss)
//输出输赢
void scsy()
switch(pdsy(pc,pcs,ren,rens))
case level:cout&&"\n平局哦!\n";
case win:cout&&"\n电脑赢了哦!\n";
case lose:cout&&"\n恭喜,你赢了!\n";
case other:cout&&"两个都超过21点了,算平局吧!\n";
//人是否发牌
cout&&"\n是否继续发牌?(Y or N)";
if(ch=='y'||ch=='Y')
{cout&&"\n人发一张牌:\n";
fapai(1,ren,rens);
return 1;}
else return 0;
//电脑是否发牌
void pfp()
if((pdsy(pc,pcs,ren,rens)&1))
cout&&"\n电脑发一张牌:\n";
fapai(1,pc,pcs);
//结束看牌
cout&&"电脑的牌是\n" ;
for(int i=0;i&++i)
cout&&pc[i]&&'\t';
cout&&"\n人的牌是"&&
for(int j=0;j&++j)
cout&&ren[j]&&'\t';
int main( )
cout && "开始发牌\n";
cout && "电脑的两张是:\n";
fapai(2, pc, pcs);
if(pd(pc,pcs)&21)
cout&&"\n发牌就输了,真失败!\n";
cout && "\n人的两张是:\n";
fapai(2, ren, rens);
if(pd(ren,rens)&21)
cout&&"\n发牌就输了,真失败!\n";
while( rfp())
//人要牌,就继续
//人不要牌了,电脑还算算要不要
cout&&"\n\n\n";
system("pause");
2.&[图片] QQ截图16.jpg&&&&
开源中国-程序员在线工具:
可以做个GUI的 那样会友善点。
2楼:perfectup 发表于
用vc6.0编译时出现
f:\21dian\21.cpp(152) : fatal error C1010: unexpected end of file while looking for precompiled header directive
3楼:乌合之众 发表于
使用mingw编译
开源从代码分享开始
乌合之众的其它代码

我要回帖

更多关于 扑克牌点数是什么 的文章

 

随机推荐