User:コルモラン/blackjack.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:コルモラン/blackjack and an accompanying .css page at User:コルモラン/blackjack.css. |
//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:"[[User:コルモラン/blackjack|ブロックジャック]]の残高を更新"};
}
).done(function ()
{
location.reload(true);
}
);
}
else
{
api.create("User:" + mw.config.get("wgUserName") + "/blackjackBalance.js",
{summary: "[[User:コルモラン/blackjack|ブラックジャック]]の残高を更新"},
"" + currentBalance).done(function ()
{
location.reload(true);
}
).fail(function ()
{
api.edit("User:" + mw.config.get("wgUserName") + "/blackjackBalance.js", function ()
{
return {minor:true,text:currentBalance,summary:"[[User:コルモラン/blackjack|ブラックジャック]]の残高を更新"};
}
).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 = '<div class="cardContainer cardFaceDown newCard"><div class="cardFace"> </div></div>';
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);
}