//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);
}