查看: 97  |  回复: 0
  js 一个简单的麻将
楼主
发表于 2024年11月17日 22:34
<!doctype html><html lang="zh"><head>    
<meta http-equiv="X-UA-Compatible" content="IE=edge" />    
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />    
<title>麻将</title>    
<style type="text/css">    
body{ background-color: #123456; margin: 0mm }    
.desk{ width: 100vmin; height: 100vmin; background-color: #fff; display: flex; flex-direction: column }    
.card{ font: 5.5vmin/7vmin arial }    
.droped{ flex: 1 }    
.player1{ background-color: #abcdef; text-align: center; padding: 1.5vmin 0mm }    
.player1 .card{ cursor: pointer }    
.player1 .card:hover{ transform: translateY(-0.5vmin); display: inline-block }    
.hule{ border: 2vmin ridge #abcdef; padding: 2vmin 3vmin; text-align: center; background-color: green; text-align: center }    
.hule .card{ box-shadow: 0mm 0mm 7vmin yellow }    
.hule .b{ font: bold 5.5vmin/7vmin arial; color: red; text-shadow: 0mm 0mm 5vmin yellow; }    
</style></head><body>    
<div class="desk" popover="manual">    
	<div class="droped"></div>    
	<div class="player1"></div>    
</div>    
<div popover="manual" class="hule">    
	<div class="b">和了</div>    
	<p class="card"></p>    
	<div>    
		<input type="button" value="接着打" onclick="majiang.buhu()" />    
		<input type="button" value="再来一局" onclick="majiang.newGame()" />    
	</div>    
</div>    
</body><script type="text/javascript">    
var majiang = new function() {    
	this.newGame = function() {    
		droped.innerHTML = "";    
		// 洗牌    
		this.xipai();    
		// 发牌    
		this.player1.fapai();    
		win.hidePopover();    
	};    
	// 洗牌    
	this.xipai = function() {    
		this.cards = new Array;    
		for(var i = 0; i < cards.length; i++) {    
			cards[i].rand = Math.random();    
			this.cards.push(cards[i]);    
		}    
		this.cards.sort(function(a, b) { return a.rand - b.rand; });    
	};    
	// 发牌    
	this.fapai = function() {    
		var card = this.cards.pop();    
		if(!card) return alert("牌已发完");    
		return card;    
	};    
	// 和了    
	this.hule = function() {    
		hule.innerHTML = hupai.ables.map(function(x) {    
			return x.map(function(y){ return y[1]; }).join(" ");    
		}).join("<br />");    
		win.showPopover();    
	};    
	// 不和    
	this.buhu = function() {    
		this.player1.canDrop = true;    
		win.hidePopover();    
	};    
	// 丢牌    
	this.drop = function(card) { droped.appendChild(card.tag); };    
	var droped = document.querySelector(".droped");    
	var cards = initCards();    
	this.player1 = new Player(".player1");    
	var win = document.querySelector(".hule");    
	var hule = win.querySelector(".card");    
};    
// 玩家对象    
function Player(css) {    
	// 摸1张牌    
	this.mopai = function(num, sort) {    
		var card = majiang.fapai();    
		if(!card) return;	// 没摸到    
		card.inPlayerId = this.cards.length;    
		card.player = this;    
		this.cards.push(card);    
		div.appendChild(card.tag);    
		if(!--num) return this.hupai(sort);    
		setTimeout(function() { me.mopai(num, sort); }, 100);    
	};    
	this.hupai = function(sort) {    
		// 开局发牌后重新排序    
		if(sort) return setTimeout(function() { me.sort(); }, 500);    
		// 摸到牌后判断是否和牌    
		if(!hupai.check(this)) return;    
		majiang.hule(); console.log(hupai.ables);    
		setTimeout(function() { me.canDrop = false; }, 1);    
	};    
	// 重新排序    
	this.sort = function() {    
		this.cards.sort(function(a, b) { return a.id - b.id; });    
		div.innerHTML = "";    
		for(var i = 0; i < this.cards.length; i++) {    
			var card = this.cards[i];    
			card.inPlayerId = i;    
			div.appendChild(this.cards[i].tag);    
		}    
		div.appendChild(mo);    
		this.canDrop = false;    
	};    
	// 重新发牌    
	this.fapai = function() {    
		div.innerHTML = "";    
		this.cards.length = 0;    
		this.mopai(13, 1);    
	};    
	// 丢牌    
	this.drop = function(id) {    
		if(!this.canDrop) return;    
		var card = this.cards[id];    
		if(!card) return;    
		majiang.drop(card);    
		this.cards.splice(id, 1);    
		this.sort();    
		delete card.player;    
	};    
	this.cards = new Array;    
	var div = document.querySelector(css);    
	var mo = document.createElement("span");    
	mo.innerHTML = "\ud83c\udc2b";    
	mo.className = "card";    
	mo.style.userSelect = "none";    
	mo.title = "摸牌";    
	mo.onclick = function() {    
		div.removeChild(mo);    
		me.mopai(1);    
		me.canDrop = true;    
	};    
	var me = this;    
}    
// 和牌检测    
var hupai = new function() {    
	var ables = this.ables = new Array;    
	this.check = function(player) {    
		ables.length = 0;    
		var cards = new Array; hasJiang = false;    
		player.cards.forEach(function(x) { cards.push({ num: x.num, kind: x.kind, id: x.id, text: x.tag.innerHTML }); });    
		cards.sort(function(a, b){ return a.id - b.id; });    
		check(cards, new Array);    
		return ables.length > 0;    
	};    
	// 递归检测    
	function check(cards, logs) {    
		var card = cards.shift();    
		// “刻、顺、将”三种可能性,看哪组 logs 能递归走到最后    
		ke(card, cards.slice(0), logs.slice(0));    
		shun(card, cards.slice(0), logs.slice(0));    
		jiang(card, cards.slice(0), logs.slice(0));    
	}    
	// 检测刻子    
	function ke(card, cards, logs) {    
		if(cards.length < 2) return false;    
		if(card.num != cards[0].num) return false;    
		if(card.num != cards[1].num) return false;    
		logs.push([ "刻子", card.text + cards[0].text + cards[1].text ]);    
		if(cards.length < 3) return ables.push(logs);	// 检测完成    
		check(cards.slice(2), logs);    
	}    
	// 检测顺子    
	function shun(card, cards, logs) {    
		if(cards.length < 2) return false;    
		var next = card.num + 2, arr = new Array;    
		for(var i = cards.length - 1; i >= 0; i--) {    
			var x = cards[i];    
			if(x.kind != card.kind) continue;	// 不同色    
			if(cards[i].num != next) continue;    
			cards.splice(i, 1); next--;    
			arr.unshift(x);    
			if(arr.length > 1) break;    
		}    
		if(arr.length < 2) return false;    
		logs.push([ "顺子", card.text + arr[0].text + arr[1].text ]);    
		return !cards.length ? ables.push(logs) : check(cards, logs);    
	}    
	// 检测将牌    
	function jiang(card, cards, logs) {    
		if(logs.some(function(x) { return x[0] == "将牌"; })) return false;    
		if(card.num != cards[0].num) return false;    
		logs.push([ "将牌", card.text + cards[0].text ]);    
		if(cards.length < 2) return ables.push(logs);    
		check(cards.slice(1), logs);    
	}    
	var me = this;    
};    
// 初始化卡牌    
function initCards() {    
	var cards = new Array, snum = 56327, pre = "\ud83c", idx = 0;    
	var newCard = function(i) {    
		var card = { id: ++idx, num: i };    
		card.kind = Math.floor(i / 9);	// 万,条,筒    
		var tag = document.createElement("span");    
		tag.innerHTML = pre + String.fromCharCode(snum + i);    
		tag.className = "card"; card.tag = tag;    
		card.tag.onclick = function() {    
			if(!card.player) return;    
			card.player.drop(card.inPlayerId);    
		};    
		cards.push(card);    
	};    
	for(var i = 0; i < 27; i++) {    
		newCard(i); newCard(i); newCard(i); newCard(i);    
	}    
	return cards;    
}    
majiang.newGame();    
document.querySelector(".desk").showPopover();    
</script></html>


您需要登录后才可以回帖 登录 | 立即注册
【本版规则】请勿发表违反国家法律的内容,否则会被冻结账号和删贴。
用户名: 立即注册
密码:
2020-2024 MaNongKu.com