User:コルモラン/blackjack.js

//only do anything if on the blackjack homepage if (mw.config.get("wgPageName") == "User:コルモラン/blackjack") {	//Global state variables var currentBalance = 500; var currentBetSetting = 10; var splitBetValue = 10; var playerHand = {count:0,softAce:false,container:"#playerGroup",value:currentBetSetting}; var dealerHand = {count:0,softAce:false,container:"#cardTableDealer"}; var splitHand = {count:0,softAce:false,container:"#splitGroup",value:0}; var previousBalanceExists = true; var faceDownCard = null; var isSplit = false; var splitWinnings = 0; var numDecks = 6; var shoe = null; var nextCard = -1; function shuffleDeck {		var rng = window.crypto || window.msCrypto; var shoeSize = 52*numDecks; var rngArray = new Uint16Array(shoeSize); var rejectArray = new Uint16Array(1); var maxInt = 65536; shoe = new Array(shoeSize); for(i = 0; i < shoe.length; i++) {			shoe[i] = i;		} rng.getRandomValues(rngArray); for(i=(shoe.length - 1); i >= 0; i--) {			//discard values greater than the maximum multiple of shoeSize below maxInt; these values would skew the distribution while(rngArray[i] >= Math.floor(maxInt/shoeSize) * shoeSize) {				rng.getRandomValues(rejectArray); rngArray[i] = rejectArray[0]; }			var tempStorage = shoe[i]; shoe[i] = shoe[(rngArray[i]%shoeSize)]; shoe[(rngArray[i]%shoeSize)] = tempStorage; shoeSize--; }		nextCard = 0; $("#cardsDealt").width("0%"); return shoe; }	function changeButton(gameButton, clickFunction, label) {		gameButton.off("click"); gameButton.click(clickFunction); gameButton.find(".mw-ui-button").html(label); gameButton.show; }	function changeActionButton(gameButton, clickFunction, gameHand, label) {		gameButton.off("click"); gameButton.click({hand:gameHand},clickFunction); gameButton.find(".mw-ui-button").html(label); gameButton.show; }	function changeBet {		var rawResponse = prompt("ここに賭け金を入力してね！ (1 - " + currentBalance + "):"); if(rawResponse == null) {			return; }		var userResponse = parseInt(rawResponse); if (isNaN(userResponse)) {			alert("それ数字じゃないから.."); return; }		if (userResponse > currentBalance) {			alert("そんなにあなたの手元にありませんけど？"); return; }		if (userResponse < 1) {			alert("寄付じゃあるまいし、1文くらい賭けたら？"); return; }		currentBetSetting = userResponse; playerHand.value = currentBetSetting; $("#betAmount").html(currentBetSetting); }	function peaceOut {		var userResponse = confirm("残高記録のために編集を行います. \n\nよろしいでしょうか？"); if (userResponse) {			mw.loader.using("mediawiki.api.edit").done(function 			{				var api = new mw.Api;				if (previousBalanceExists)				{					api.edit("User:" + mw.config.get("wgUserName") + "/blackjackBalance.js", function {						return {minor:true,text:currentBalance,summary:"ブロックジャックの残高を更新"}; }					).done(function {						location.reload(true); }					);				}				else				{					api.create("User:" + mw.config.get("wgUserName") + "/blackjackBalance.js", {summary: "ブラックジャックの残高を更新"}, "" + currentBalance).done(function {						location.reload(true); }					).fail(function {						api.edit("User:" + mw.config.get("wgUserName") + "/blackjackBalance.js", function 						{							return {minor:true,text:currentBalance,summary:"ブラックジャックの残高を更新"};						}						).done(function 						{							location.reload(true);						}						); }					);				}			}			);		}	}	function randomCard {		var cardIndex = shoe[nextCard]; nextCard++; $("#cardsDealt").width("" + ((nextCard/(numDecks*26))*100) + "%"); return {"suit": ((Math.floor(cardIndex/13)%4)+1),"rank":(cardIndex%13 + 1)}; }	function getCardBackground(card) {		var cardBackground = {"x":0,"y":0}; switch (card.rank) {			case 1: cardBackground.x = -1; break; case 2: cardBackground.x = -100; break; case 3: cardBackground.x = -199; break; case 4: cardBackground.x = -298; break; case 5: cardBackground.x = -396; break; case 6: cardBackground.x = -495; break; case 7: cardBackground.x = -593; break; case 8: cardBackground.x = -691; break; case 9: cardBackground.x = -790; break; case 10: cardBackground.x = -888; break; case 11: cardBackground.x = -987; break; case 12: cardBackground.x = -1085; break; case 13: cardBackground.x = -1184; break; default: cardBackground.x = -199; }		switch (card.suit) {			case 1: case 2: case 3: case 4: cardBackground.y = (-2+-143*(card.suit-1)); break; default: cardBackground.y = -574; }		return cardBackground; }	function addToCount(card, currentTotal) {		switch(card.rank) {			case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: if(currentTotal.count + card.rank > 21 && currentTotal.softAce == true) {					currentTotal.softAce = false; currentTotal.count = currentTotal.count - 10 + card.rank ; }				else currentTotal.count += card.rank ; break; case 10: case 11: case 12: case 13: if(currentTotal.count + 10 > 21 && currentTotal.softAce == true) {					currentTotal.softAce = false; }				else currentTotal.count += 10; break; case 1: if(currentTotal.count + 11 > 21) {					currentTotal.count += 1; }				else {					currentTotal.count += 11; currentTotal.softAce = true; }		}	}	function addCard(card, cardContainer, isFaceDown) {		var newCard = '  '; var lastCard = $(cardContainer).children(".cardContainer").last; $(cardContainer).append(newCard); $("#verticalSpacer").hide; newCardDom = $(".newCard"); newCardDom.removeClass("newCard"); if(lastCard.length != 0) {			lastCard.removeClass("cardFaceUp"); lastCard.addClass("cardCovered"); }		if(!isFaceDown) {			newCardDom.removeClass("cardFaceDown"); var coords = getCardBackground(card); newCardDom.find(".cardFace").css("background-position", ""+ coords.x + "px " + coords.y + "px"); newCardDom.addClass("cardFaceUp"); }	}	function dealCard(hand, isFaceDown) {		var nextCard = randomCard; addToCount(nextCard, hand); addCard(nextCard, hand.container, isFaceDown); if(isFaceDown) {			faceDownCard = nextCard; }		return nextCard; }	function flipCard {		var lastCard = $(".cardFaceDown"); lastCard.removeClass("cardFaceDown"); var coords = getCardBackground(faceDownCard); lastCard.find(".cardFace").css("background-position", ""+ coords.x + "px " + coords.y + "px"); lastCard.addClass("cardFaceUp"); }	function endHand(isBlackjack) {		isSplit = false; $("#splitGroup").removeClass("selectedSplit"); $("#playerGroup").removeClass("selectedSplit"); var resultValue = (splitHand.value + playerHand.value) currentBalance += resultValue; var resultString = ""; if(isBlackjack) {			resultString = "ブラックジャック! "; }		if(resultValue > 0) {			resultString += "やったね！" + resultValue + "文獲得だよ! "; }		else if(resultValue == 0) {			resultString += "引き分けです. "; }		else {			resultString += "あなたの負けです. " + Math.abs(resultValue) + "文失いました. "; }		playerHand.count = 0; playerHand.softAce = false; dealerHand.count = 0; dealerHand.softAce = false; splitHand.count = 0 splitHand.softAce = false; playerHand.value = currentBetSetting; splitHand.value = 0; faceDownCard = null; if(currentBalance >= 1) {			resultString += "もう一度遊びますか？"; $("#gameStatus").html(resultString); $("#bankAmount").html(currentBalance.toFixed(2)); if(currentBalance < currentBetSetting) {				currentBetSetting = Math.floor(currentBalance); playerHand.value = currentBetSetting; $("#betAmount").html(currentBetSetting); }			changeButton($("#gameOption1"), cleanAndDeal, "やる"); changeButton($("#gameOption2"), changeBet, "賭け金の金額変更"); changeButton($("#gameOption3"), peaceOut, "やめる"); $("#gameOption4").hide; }		else {			resultString += "お疲れ様でした. なんで負けたか明日までに考えといてください. "; $("#gameStatus").html(resultString); $("#bankAmount").html(currentBalance.toFixed(2)); currentBetSetting = 0; playerHand.value = currentBetSetting; splitHand.value = 0; $("#betAmount").html("0"); changeButton($("#gameOption1"), peaceOut, "やり直す"); $("#gameOption2").hide; $("#gameOption3").hide; $("#gameOption4").hide; }	}	function playDealer {		flipCard; while(dealerHand.count < 17) {			dealCard(dealerHand, false); }		resolveHand(splitHand); resolveHand(playerHand); endHand(false); }	function resolveHand(hand) {		if(dealerHand.count <= 21 && hand.count > 0 && dealerHand.count > hand.count) {			hand.value = -(hand.value); }		else if(dealerHand.count == hand.count) {			hand.value = 0; }		return hand.value; }	function cleanAndDeal {		$("#cardTableDealer").html(""); $("#playerGroup").html(""); $("#splitGroup").html(""); $("#splitGroup").hide; dealHand; }	function dealHand {		if(nextCard < 0 || nextCard > 26*numDecks) {			shuffleDeck; }		var firstCard = dealCard(playerHand, false); dealCard(dealerHand, false); var secondCard = dealCard(playerHand, false); dealCard(dealerHand, true); if(playerHand.count == 21) {			flipCard; if(dealerHand.count == 21) {				playerHand.value = 0; endHand(true); return; }			playerHand.value = currentBetSetting*3/2; endHand(true); return; }		if(dealerHand.count == 21) {			flipCard; playerHand.value = -(currentBetSetting); endHand(false); return; }		$("#gameStatus").html("あなたのカードの合計点数は" + playerHand.count + "点です. どうしますか？"); changeActionButton($("#gameOption1"), hitMe, playerHand, "ヒット"); changeActionButton($("#gameOption2"), standDown, playerHand, "スタンド"); if(currentBalance >= 2*currentBetSetting) {			changeActionButton($("#gameOption3"), doubleDown, playerHand, "ダブルダウン"); }		else {			$("#gameOption3").hide; }		if(firstCard.rank == secondCard.rank && currentBalance >= 2*currentBetSetting) {			changeButton($("#gameOption4"), splitIt, "スプリット"); }		else {			$("#gameOption4").hide; }	}	function hitMe(e) {		var currentHand; if(e.data != null && e.data.hand != null) {			currentHand = e.data.hand; }		else {			currentHand = playerHand; }		dealCard(currentHand, false); if(currentHand.count > 21) {			currentHand.value = -(currentBetSetting); currentHand.count = 0; standDown; return; }		else if(currentHand.count == 21) {			standDown; return; }		else {			$("#gameOption3").hide; $("#gameOption4").hide; $("#gameStatus").html("あなたのカードの合計点数は" + currentHand.count + "点です. どうしますか？ "); }	}	function standDown {		if(playerHand.count == 0 && splitHand.count == 0) {			endHand(false); return; }		else if(isSplit) {			isSplit = false; $("#splitGroup").removeClass("selectedSplit"); $("#playerGroup").addClass("selectedSplit"); changeActionButton($("#gameOption1"), hitMe, playerHand, "Hit"); changeActionButton($("#gameOption2"), standDown, playerHand, "Stand"); if(currentBalance >= (2*currentBetSetting + Math.abs(splitBetValue))) {				changeActionButton($("#gameOption3"), doubleDown, playerHand, "Double"); }			else {				$("#gameOption3").hide; }			$("#gameStatus").html("あなたの2つ目のカードの合計点数は " + playerHand.count + "点です. どうしますか？"); }		else {			playDealer; }	}	function doubleDown(e) {		var currentHand; if(e.data != null && e.data.hand != null) {			currentHand = e.data.hand; }		else {			currentHand = playerHand; }		currentHand.value = currentBetSetting * 2; dealCard(currentHand, false); if(isSplit && playerHand.count < 21) {			if(currentHand.count > 21) {				currentHand.value = -(currentHand.value); currentHand.count = 0; }			standDown; return; }		else if(currentHand.count > 21) {			currentHand.count = 0; currentHand.value = -(currentHand.value); endHand; return; }		else {			playDealer; }	}	function splitIt {		isSplit = true; splitHand.value = currentBetSetting; $("#gameOption4").hide; var firstCard = $("#playerGroup").find(".cardContainer")[0]; $(firstCard).appendTo($("#splitGroup")); $("#splitGroup").show; if(playerHand.softAce) {			splitHand.count = 11; splitHand.softAce = true; playerHand.count = 11; dealCard(splitHand, false); dealCard(playerHand, false); playDealer; return; }		else {			splitHand.count = playerHand.count / 2; splitHand.softAce = false; playerHand.count = splitHand.count; dealCard(splitHand, false); dealCard(playerHand, false); $("#splitGroup").addClass("selectedSplit"); }		changeActionButton($("#gameOption1"), hitMe, splitHand, "ヒット"); changeActionButton($("#gameOption2"), standDown, splitHand, "スタンド"); if(currentBalance >= (3*currentBetSetting)) {			changeActionButton($("#gameOption3"), doubleDown, splitHand, "ダブルダウン"); }		else {			$("#gameOption3").hide; }		$("#gameStatus").html("スプリット！あなたの1番目のカードの合計点数は " + splitHand.count + "点です. どうしますか？"); }	function runTheNumbers {		$("#bankAmount").html(currentBalance.toFixed(2)); $("#betAmount").html(currentBetSetting); $("#gameStatus").html("用意はできていますか？"); changeButton($("#gameOption1"), dealHand, "やる"); changeButton($("#gameOption2"), changeBet, "賭け金の金額変更"); changeButton($("#gameOption3"), peaceOut, "やめる"); $("#gameOption4").hide; }	function loadSave {		var loadRequestData = {			"action": "raw", "title": "User:" + mw.config.get("wgUserName") + "/blackjackBalance.js" };		$.post("/w/index.php", loadRequestData, function (response)		{			var retrievedValue = parseFloat(response);			if (!(isNaN(retrievedValue)) && retrievedValue >= 1)			{				currentBalance = retrievedValue;				if (Math.floor(currentBalance / 10) < 10)				{					currentBetSetting = Math.floor(currentBalance / 10);					if (currentBetSetting < 1)					{						currentBetSetting = 1;					}				}				else				{					currentBetSetting = 10;				}			}			else			{				alert("お疲れ様でした. 文字通り一文無しになっちゃいましたね. ここに500文あるので、なんで負けたか明日までに考えといてください. ");				currentBalance = 500;				currentBetSetting = 10;			}			runTheNumbers;		}		).fail(function 		{			alert("見かけない顔ですね. 初めてのようですし、500文を贈呈します. ");			currentBalance = 500;			currentBetSetting = 10;			previousBalanceExists = false;			runTheNumbers;		}); }	function prepareBlackjack {		$("#gameStatus").html("ブラックジャックへようこそ！"); changeButton($("#gameOption1"), loadSave, "始める"); $("#splitGroup").hide; $("#gameOption2").hide; $("#gameOption3").hide; $("#gameOption4").hide; }	$(document).ready(prepareBlackjack); }