首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOP Blackjack游戏

OOP Blackjack游戏
EN

Code Review用户
提问于 2015-03-01 09:00:45
回答 1查看 4.9K关注 0票数 4

我制作这个Blackjack游戏是为了帮助我学习JavaScript类和对象的语法。

当我在写游戏的时候,我觉得我在滥用OOP的思想。我的意思是,我觉得类的一些变量/方法可能与类无关,而且仍然在工作。

让我知道我怎样才能改善这一切。

代码语言:javascript
复制
<script>
window.addEventListener("load", start, false);

function start()
{
	play();
}

function play()
{
	var deck1 = new Deck();
	deck1.createDeck();
	deck1.shuffle();
	deck1.deal21();
	document.getElementById("hit").addEventListener("click", function(){deck1.hit();},false);
	document.getElementById("stand").addEventListener("click", function(){deck1.stand();},false);
	document.getElementById("replay").addEventListener("click", function(){deck1.deal21();}, false);
}

function Deck()
{
	this.deck = new Array();
	this.userTotal;
	this.dealerTotal;
	this.money = 100;
	this.userBust;
	this.dealerBust;
	this.curusrHand;
	this.curdlrHand;
	var userHand = document.getElementById("user-hand");
	var dealerHand = document.getElementById("dealer-hand");
	var userScore = document.getElementById("user-score");
	var dealerScore = document.getElementById("dealer-score");
	var status = document.getElementById("game-status");
	var moneyDiv = document.getElementById("money");

	this.newDeck = function newDeck()
	{
		this.createDeck();
		this.shuffle();
		status.innerHTML="NEW DECK IN PLAY!";
	}

	this.createDeck = function createDeck()
	{
		var numCards=0;
		var suit, symbol, name;
		for(var k=1; k<=4; k++)
		{
			switch(k)
			{
				case 1: suit ="hearts";
				break;
				case 2: suit ="diamonds";
				break;
				case 3: suit ="spades";
				break;
				case 4: suit ="clubs";
				break;
			}

			for(var i=1; i<=13; i++)
			{
				symbol = i;
				switch(i)
				{
					case 1: name= "Ace";
					symbol = "A";
					break;
					case 2: name= "two";
					break;
					case 3: name= "three";
					break;
					case 4: name= "four";
					break;
					case 5: name= "five";
					break;
					case 6: name= "six";
					break;
					case 7: name= "seven";
					break;
					case 8: name= "eight";
					break;
					case 9: name= "nine";
					break;
					case 10: name= "ten";
					break;
					case 11: name= "jack";
					symbol = "J";
					break;
					case 12: name= "queen";
					symbol = "Q";
					break;
					case 13: name= "king";
					symbol = "K";
					break;
				}
				this.deck[numCards] = new Card(suit, i, name, symbol);
				numCards++;
			}
		}
	}

	this.shuffle = function shuffle()
	{
		var randomDeck = new Array();
		var empty = false;
		while(!empty)
		{
		var randomIndex = Math.floor(Math.random()*this.deck.length);
		randomDeck.push(this.deck[randomIndex]);
		this.deck.splice(randomIndex, 1);
		if(this.deck.length <=0) empty = true;
		}
		for(var i=0; i<randomDeck.length; i++)
		{
			this.deck[i] = randomDeck[i];
		}
	};


	this.calcValue = function calcValue(hand)
	{
		var val = 0;
		var tempArr = hand;
		tempArr.sort(function(a,b) { return parseFloat(a.val) - parseFloat(b.val) } );
		for(var i=tempArr.length-1; i>=0; i--)
		{
			var temp = tempArr[i];
			if(temp.val === 1 && val <=10)temp.val = 11;
			else if(temp.val >=10) temp.val = 10;
			val += temp.val;
		}
		return val;
	};

	this.emptyDeck = function emptyDeck()
	{
		if(this.deck.length < 1) return true;
		else return false;
	}

	this.deal21 = function deal21()
	{
		status.innerHTML="";
		this.money--;
		
		//reset all the stuff that needs to be reset if the game is being replayed
		money.innerHTML= "Money: " + this.money;
		dealerHand.innerHTML="<h2>Dealer Hand</h2>";
		userHand.innerHTML="<h2>User Hand</h2>";
		this.userTotal=0;
		this.dealerTotal=0;
		this.userBust=false;
		this.dealerBust=false;
		hit.setAttribute("style", "");
		stand.setAttribute("style", "");
		dealerScore.setAttribute("style", "");
		this.curusrHand = new Array();
		this.curdlrHand = new Array();


		for(i=0; i<2; i++)
		{
			if(this.emptyDeck())this.newDeck();
			this.curusrHand.push(this.deck.pop());
			userHand.innerHTML+=this.curusrHand[i].showCard();
		}
		this.userTotal = this.calcValue(this.curusrHand);
		userScore.innerHTML=this.userTotal;

		for(i=0; i<2; i++)
		{
			if(this.emptyDeck())this.newDeck();
			this.curdlrHand.push(this.deck.pop());
			dealerHand.innerHTML+=this.curdlrHand[i].showCard();
		}
		this.dealerTotal = this.calcValue(this.curdlrHand);
		dealerScore.innerHTML=this.dealerTotal;
		//hide dealers first card
		var firstCard = dealerHand.getElementsByClassName("card")[0];
		firstCard.setAttribute("id", "hidden-card");
		var blackjack =true;
		if(this.userTotal === 21 && this.dealerTotal < 21) this.gameOver(blackjack);
		else if(this.dealerTotal === 21) this.gameOver();
	};

	this.hit = function hit()
	{
		if(this.emptyDeck())this.newDeck();
		this.curusrHand.push(this.deck.pop());
		userHand.innerHTML+=this.curusrHand[this.curusrHand.length-1].showCard();
		this.userTotal = this.calcValue(this.curusrHand);
		userScore.innerHTML=this.userTotal;
		if(this.userTotal >21) 
			{
				userScore.innerHTML+=" <span style='color:red; font-weight: bold;'> BUST</span>";
				this.userBust = true;
				this.gameOver();
			}
	};

	this.stand = function stand()
	{
		while(this.dealerTotal < 17)
		{
			if(this.emptyDeck())this.newDeck();
			this.curdlrHand.push(this.deck.pop());
			dealerHand.innerHTML+=this.curdlrHand[this.curdlrHand.length-1].showCard();
			this.dealerTotal = this.calcValue(this.curdlrHand);
			dealerScore.innerHTML=this.dealerTotal;
			if(this.dealerTotal > 21) 
				{
					dealerScore.innerHTML+=" <span style='color:red; font-weight: bold;'> BUST</span>";
					this.dealerBust = true;
				}
		}
		this.gameOver();
	}

	this.gameOver = function gameOver(blackjack)
	{
		document.getElementById("hidden-card").setAttribute("id","");
		dealerScore.setAttribute("style", "visibility: visible;");
		hit.setAttribute("style", "visibility:hidden;");
		stand.setAttribute("style", "visibility:hidden;");

		if(blackjack) 
		{
			this.money +=3;
			status.innerHTML ="BLACKJACK!!!!!!!!!";
		}

		else if(this.userTotal > this.dealerTotal && this.userBust === false || this.dealerBust ===true)
		{
			//user wins
			this.money+=2;
			status.innerHTML ="YOU WIN!";
		}
		else if(this.userTotal === this.dealerTotal && this.userBust === false)
		{
			//push
			this.money++;
			status.innerHTML="PUSH :o";
		}

		else status.innerHTML="YOU LOSE!";

		money.innerHTML="Money: "+this.money;

	}

	this.dump = function dump()
	{
		for(var i=0; i<this.deck.length; i++)
		{
			this.deck[i].showCard();
		}
	};
}

function Card(suit, val, name, symbol)
{
		this.suit = suit;
		this.val = val;
		this.name = name;
		this.symbol = symbol;

	this.showCard =function showCard()
	{
		var html="";
		switch(this.suit)
		{
			case "hearts": suit_text = "♥";
			break;
			case "diamonds": suit_text = "♦";
			break;
			case "spades": suit_text = "♠";
			break;
			case "clubs": suit_text = "♣";
			break;
		}
		html="<div class='card " + this.suit + "'><div class='card-value'>" + this.symbol + "</div><div class='suit'>" + suit_text + "</div><div class='main-number'>"+this.symbol +"</div><div class='invert card-value'>"+this.symbol+"</div><div class='invert suit'>"+suit_text+"</div></div>";
		return html;
	}
}
</script>
代码语言:javascript
复制
div.card
{
	display: inline-block;
	width: 100px;
	height: 150px;
	border: solid 1px #333;
	border-radius: 5px 5px 5px 5px;
	float: left;
	margin-right: 10px;
	position: relative;
}

div.card.hearts, div.card.diamonds
{
	color: red;
}

div.card div.main-number
{
	font-size: 36px;
	font-weight: bold;
	text-align: center;
	margin: 0px auto;
	margin-top: 50px;
}

div.card-value, div.suit
{
	position: absolute;
	left: 5px;
}

div.card-value{top: 5px;}
div.card-value{top: 20px;}

div.card-value.invert, div.suit.invert
{
	transform: rotate(180deg);
	right: 5px;
	text-align: right;
	top: auto;
	left: auto;
}

div.card-value.invert{bottom: 5px;}
div.suit.invert{bottom: 20px;}

div.dealer-area{}

div.user-area{float: left;}

div#user-score, div#dealer-score
{
	display: inline-block;
}

div.score-parent
{
	width: 100%;
	display: inline-block;
}

div.score-parent p
{
	display: inline-block;
}

div#dealer-score
{
	visibility: hidden;
}

div.card#hidden-card
{
	background-color: #CBE0FD;
}

div.card#hidden-card div
{
	visibility: hidden;
}

div.controls input
{
	margin-left: 20px;
	width: 200px;
}
代码语言:javascript
复制
<html>
<head>
<title>Cards</title>
<link rel="stylesheet" type="text/css" href="cards.css">
<script type="text/javascript" src="classes.js"></script>
</head>
<body>
<div id="game-status"></div>
	<div class="user-area">
	<div id="money"></div>
	<div id="user-buttons" class="controls">
	<input type="button" id="hit" value="Hit">
	<input type="button" id="stand" value="Stand">
	<input type="button" id="replay" value="Play Again">
	</div>
	<div class="score-parent">
		<p>Score</p>
			<div id="user-score"class="score">
			</div>
		</div>
	<div id="user-hand" class="hand">
	<h2>User Hand</h2>
	</div>
	</div>
	<div class="dealer-area">
	<div class="score-parent">
		<p>Score</p>
			<div id="dealer-score"class="score">
			</div>
		</div>
	<div id="dealer-hand" class="hand">
	<h2>Dealer Hand</h2>
	</div>
	</div>
</body>
</html
EN

回答 1

Code Review用户

发布于 2015-03-01 10:36:43

您的calcValue()函数在决定是否将ace计算为1或11时,会出现错误。例如,它会将{A,7,5}报告为半身像。

Deck对象做的太多了。这不仅是一个高度黑杰克特有的甲板,它也同时充当模型和控制器。可能应该有一个单独的BlackjackDealer对象或其他东西。

应避免出现在switch中的巨大createDeck()。可以用数组或哈希查找替换它。但是我不明白为什么这张卡的英文名字是必要的。

方法,特别是Card.showCard(),应该在原型上定义。您不希望52张卡中的每一张都有自己的showCard()函数。

您应该设计用户界面,使按钮处于可预测的位置。调整大小或倾向于在页面周围移动的按钮会导致糟糕的用户体验。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/82895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档