User:Writ Keeper/Scripts/freecell.js

In today's world, User:Writ Keeper/Scripts/freecell.js has become a topic of constant interest and debate. Whether it's its impact on society, its historical relevance, or its influence on popular culture, User:Writ Keeper/Scripts/freecell.js attracts the attention of people of all ages, genders, and backgrounds. Over the years, User:Writ Keeper/Scripts/freecell.js has generated all kinds of opinions, theories and interpretations, becoming a central element in numerous areas. In this article, we will explore different aspects of User:Writ Keeper/Scripts/freecell.js and its meaning in the contemporary context. From its origin to its current repercussions, we will take an in-depth look at the importance of User:Writ Keeper/Scripts/freecell.js in our world today.
//only do anything if on the freecell homepage
if (mw.config.get("wgPageName") == "User:Writ_Keeper/freecell")
{
	//Global state variables
	var gameState = null;
	var pastGameStates = ;
	var selectedCards = {cards:,sourceIndex:null,sourceType:null};
	
	function deal() 
	{
		gameState = {freecells:,columns:, dirty:false},{cards:, dirty:false},{cards:, dirty:false},{cards:, dirty:false},{cards:, dirty:false},{cards:, dirty:false},{cards:, dirty:false},{cards:, dirty:false}],homecells:};
		pastGameStates = ;
		let rng = window.crypto || window.msCrypto;
		let deckSize = 52;
		let rngArray = new Uint16Array(deckSize);
		let rejectArray = new Uint16Array(1);
		let maxInt = 65536;
		deck = new Array(deckSize);
		for(i = 0; i < deck.length; i++)
		{
			deck = i;
		}
		rng.getRandomValues(rngArray);
		for(i=(deck.length - 1); i >= 1; i--)
		{
			//discard values greater than the maximum multiple of i+1 below maxInt; these values would skew the distribution
			while(rngArray >= Math.floor(maxInt/(i+1)) * (i+1))
			{
				rng.getRandomValues(rejectArray);
				rngArray = rejectArray;
			}
			let tempStorage = deck;
			let randomIndex = rngArray%(i+1);
			deck = deck;
			deck = tempStorage;
			deckSize--;
		}
		cardIndex = 0;
		//now deck is shuffled, deal
		for(i = 0; i < 4; i++)
		{
			for(j = 0; j < 7; j++)
			{
				addCardToColumn(getCardFromDeck(cardIndex), i);
				cardIndex++;
			}
		}
		for(i = 0; i < 4; i++)
		{
			for(j = 0; j < 6; j++)
			{
				addCardToColumn(getCardFromDeck(cardIndex), i);
				cardIndex++;
			}
		}
		for(columnIndex = 0; i < 8; i++)
		{
			let columnLength = gameState.columns.length;
			let previousCard = gameState.columns.cards;
			for(index = columnLength - 2; index >= 0; index--) 
			{
				let nextCard = gameState.columns.cards;
				if(allPrevInOrder && nextCard.rank == previousCard.rank + 1 && true /* TODO: make sure suits are alternating*/)
				{
					nextCard.inOrder = true;
					previousCard = nextCard;
				}
				else
				{
					nextCard.inOrder = false;
					allPrevInOrder = false;
				}
			}
		}
	}
	function updateGameDisplay(forceRefresh) 
	{
		for(let i = 0; i < 4; i++)
		{
			if(forceRefresh || gameState.freecells.dirty)
			{
				updateFreecell(i);
			}
		}
		for(let i = 0; i < 4; i++)
		{
			if(forceRefresh || gameState.homecells.dirty)
			{
				updateHomecell(i);
			}
		}
		for(let i = 0; i < 8; i++)
		{
			if(forceRefresh || gameState.columns.dirty)
			{
				updateColumn(i);
			}
		}
	}
	function updateFreecell(index)
	{
		updateCellVisual(gameState.freecells.card, index, "freecell");
		gameState.freecells.dirty = false;
	}
	function updateHomecell(index)
	{
		updateCellVisual(gameState.homecells.card, index, "homecell");
		gameState.homecells.dirty = false;		
	}
	function updateCellVisual(card, index, idName) 
	{
		if(card == null)
		{
			$("#" + idName + index).attr("class","emptySpace");
		}
		else
		{
			$("#" + idName + index).attr("class","fullCard");
			let coords = getCardBackground(card);
			$("#" + idName + index).css("background-position", ""+ coords.x + "px " + coords.y + "px");
		}
	}
	function updateColumn(index)
	{
		let column = gameState.columns;
		if(column.cards == null || column.cards.length == 0)
		{
			$("#column" + index).html('<div class="emptyCard" style="display:inline-block; width:97px; height:139px; border-radius:3px; background-color:#044905; border:1px dotted"></div>');
		}
		else 
		{
			$("column" + index).empty();
			let hiddenCards = column.cards.length - 1;
			let coords = null;
			for(let i = 0; i < hiddenCards; i++)
			{
				$("#column" + index).append('<div class="hiddenCard" id="col' + index + 'card'+i+'" style="display:inline-block; width:97px; height:139px; border-radius:3px; background-color:#044905; border:1px dotted"></div>');
				coords = getCardBackground(column.cards);
				$("#col"+index+"card"+i).css("background-position", ""+ coords.x + "px " + coords.y + "px");
			}
			$("#column" + index).append('<div class="fullCard" id="col' + index + 'card'+hiddenCards+'" style="display:inline-block; width:97px; height:139px; border-radius:3px; background-color:#044905; border:1px dotted"></div>');
			coords = getCardBackground(column.cards);
			$("#col"+index+"card"+hiddenCards).css("background-position", ""+ coords.x + "px " + coords.y + "px");
		}
		gameState.columns.dirty = false;
	}
	function AttemptCardMove(destIndex, destType) 
	{
		if(selectedCards == null || selectedCards.length == 0)
		{
			console.log("attempted to move zero cards");
			return false;
		}
		if(destType == "homecell" || destType == "freecell")
		{
			if(selectedCards.length > 1)
			{
				alert("Tried to move more than one card into a " + destType + "!");
				return false;
			}
			//special case; automatically send card to its proper homecell on doubleclick
			if(destIndex == null && destType == "homecell") 
			{
				let i = 0;
				
				//if it's an ace we're trying to move, search for an empty homecell
				if(selectedCards.rank == 1)
				{
					while(i < 4 && gameState.homecell.card != null)
					{
						i++;
					}
					if(i >= 4)
					{
						alert("No open homecells for ace (this shouldn't happen)");
						return false;
					}
					moveCards(i, "homecell");
					return true;
				}
				else
				{
				//otherwise, search for the homecell of correct suit and see if the ranks are correct
					let card = null;
					while(i < 4 && (card == null || card.suit != selectedCards.suit))
					{
						i++;
					}
					if(i >= 4)
					{
						//ran off the end, just deselect and return quietly
						deselectCards();
						return false;
					}
					else
					{
						if(
					}
				}
			}
		}
	}
	function addCardToColumn(card, columnIndex)
	{
		gameState.columns.push(card);
		card.inOrder = true;		
	}
	function removeCardFromColumn()
	{
	}
	function getCardFromDeck(index)
	{
		var cardIndex = deck;
		return {"suit": ((Math.floor(cardIndex/13)%4)+1),"rank":(cardIndex%13 + 1), "inOrder": true};
	}
	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;
				}
		}
		
	}
	$(document).ready(prepareBlackjack);
}