Minesweeper.sk

Created by LimeGlass

Just so you know, we don't know the file format for every file. If it's just a bunch of random characters, it's probably a .zip or .jar.


# Minesweeper by LimeGlass

# XXX
# X0X
# XXX
function getSurrounding(slot: number, inventory: inventory) :: numbers:
	# Left edge
	if {_slot} mod 9 is not 0:
		add {_slot} - 1 to {_slots::*}
		add (({_slot} - 1) + 9) to {_slots::*}
		add (({_slot} - 1) - 9) to {_slots::*}
	if {_slot} mod 9 is not 8:
		add {_slot} + 1 to {_slots::*}
		add (({_slot} + 1) + 9) to {_slots::*}
		add (({_slot} + 1) - 9) to {_slots::*}
	add {_slot} + 9 to {_slots::*}
	add {_slot} - 9 to {_slots::*}
	loop {_slots::*}:
		if loop-value is not between 0 and inventory size of {_inventory}:
			remove loop-value from {_slots::*}
	return {_slots::*}

# #X#
# X0X
# #X#
function getNextTo(slot: number, inventory: inventory) :: numbers:
	# Left edge
	if {_slot} mod 9 is not 0:
		add {_slot} - 1 to {_slots::*}
	if {_slot} mod 9 is not 8:
		add {_slot} + 1 to {_slots::*}
	add {_slot} + 9 to {_slots::*}
	add {_slot} - 9 to {_slots::*}
	loop {_slots::*}:
		if loop-value is not between 0 and inventory size of {_inventory}:
			remove loop-value from {_slots::*}
	return {_slots::*}

# Concurrent determining system.
function handle(player: player, slot: number, inventory: inventory):
	# Cut off random digs, and display a single hint on clicked slot.
	loop getNextTo({_slot}, {_inventory}):
		if {minesweeper::temp::%{_player}%::bombs::*} contains loop-number:
			loop getSurrounding({_slot}, {_inventory}):
				if {minesweeper::temp::%{_player}%::bombs::*} contains loop-number-2:
					add 1 to {_count}
			if {_count} is set:
				set {_item} to blue stained glass pane
				if {_count} is 2:
					set {_item} to light green stained glass pane
				if {_count} is 3:
					set {_item} to yellow stained glass pane
				if {_count} is 4:
					set {_item} to orange stained glass pane
				if {_count} is 5:
					set {_item} to red stained glass pane
				set slot {_slot} of {_inventory} to {_count} of {_item} named "&fThere are &l%{_count}% &fbomb(s) near."
			stop
	# Click was not directly next to a bomb.
	loop getSurrounding({_slot}, {_inventory}):
		slot loop-number of {_inventory} is white stained glass pane
		# Calculate the count for the hint.
		loop getSurrounding(loop-number, {_inventory}):
			if {minesweeper::temp::%{_player}%::bombs::*} contains loop-number-2:
				add 1 to {_count}
		# The area is air.
		if {_count} is not set:
			if {minesweeper::temp::%{_player}%::bombs::*} doesn't contain loop-number:
				set slot loop-number of {_inventory} to air
				# Open up all the air pockets connected to this air pocket.
				handle({_player}, loop-number, {_inventory})
		# Determine the colour glass to display for the hint.
		else if {minesweeper::temp::%{_player}%::bombs::*} doesn't contain loop-number:
			set {_item} to blue stained glass pane
			if {_count} is 2:
				set {_item} to light green stained glass pane
			if {_count} is 3:
				set {_item} to yellow stained glass pane
			if {_count} is 4:
				set {_item} to orange stained glass pane
			if {_count} is 5:
				set {_item} to red stained glass pane
			set slot loop-number of {_inventory} to {_count} of {_item} named "&fThere are &l%{_count}% &fbomb(s) near."
		clear {_count}

# Command for the game. Customize to your liking.
command /minesweeper <string>:
	permission: minesweeper.use
	usage: /minesweeper <difficulty between 1 and 10>
	trigger:
		clear {minesweeper::temp::%player%::*}
		# Show highscores.
		if argument is "highscores", "highscore" or "hs":
			set {_uuid} to uuid of player
			if {minesweeper::%{_uuid}%::highscores::*} is not set:
				message "&7[&cMinesweeper&7] &cYou have no highscores set."
				stop
			set {_spot} to 1
			# Sorted Difficulty from hardest to easiest.
			loop integers between 10 and 1:
				loop {minesweeper::%{_uuid}%::highscores::%loop-number%::*}:
					# because Skript toVariableName for timeperiods is dumb.
					set {_date} to loop-index
					replace "object:" with "" in {_date}
					message "&f##&l%{_spot}% - &7Difficulty: &f%loop-number%&7, Time: &f%loop-value-2%&7, Date: &f%{_date}%"
			stop
		set {_difficulty} to argument parsed as a number
		if {_difficulty} is not set:
			set {_difficulty} to 6
			message "&7[&cMinesweeper&7] &c&l%argument% &cis not a number between 1 and 10, defaulting to 6 for difficulty."
		if {_difficulty} is not between 1 and 10:
			set {_difficulty} to 10
		set {_inventory} to a chest inventory with 6 rows named "           &4&lMinesweeper"
		set {minesweeper::temp::%player%::difficulty} to {_difficulty}
		loop numbers between 0 and inventory size of {_inventory}:
			set slot loop-number of {_inventory} to white stained glass pane named "&7Click to reveal"
		set {minesweeper::temp::%player%::inventory} to {_inventory}
		open {_inventory} to player
		play sound "ENTITY_EXPERIENCE_ORB_PICKUP" at volume 0.6 and pitch 2 to player

on inventory click:
	{minesweeper::temp::%player%::inventory} is set
	event-inventory is {minesweeper::temp::%player%::inventory}
	cancel event
	if {minesweeper::temp::%player%::finished} is set:
		stop
	# Handle flags
	if clicked type is right mouse button:
		if clicked item is a redstone torch:
			set clicked item to {minesweeper::temp::%player%::past::%clicked slot%}
			play sound "ENTITY_VILLAGER_NO" at volume 0.6 and pitch 2 to player
			clear {minesweeper::temp::%player%::past::%clicked slot%}
		else:
			# Important to remember past item.
			set {minesweeper::temp::%player%::past::%clicked slot%} to clicked item
			set clicked item to redstone torch
			play sound "ENTITY_ENDER_DRAGON_FLAP" at volume 0.5 and pitch 2 to player
		stop
	# Handle digging
	clicked type is left mouse button
	play sound "BLOCK_GRASS_STEP" at volume 0.7 and pitch 0 to player
	# calculate the game on first click, because it's no fun clicking your first slot on a bomb.
	if {minesweeper::temp::%player%::start} is not set:
		set {minesweeper::temp::%player%::start} to now
		# Amount of random bombs based on difficulty.
		loop random number between 5 and 2 * {minesweeper::temp::%player%::difficulty} times:
			add random integer between 0 and inventory size of event-inventory - 1 to {minesweeper::temp::%player%::bombs::*}
		# Remove all surrounding bombs so it's a fair start.
		loop getSurrounding(clicked slot, event-inventory):
			remove loop-number from {minesweeper::temp::%player%::bombs::*}
		remove clicked slot from {minesweeper::temp::%player%::bombs::*}
		set clicked item to air
		handle(player, clicked slot, event-inventory)
		# Winning checker
		while {minesweeper::temp::%player%::inventory} is set:
			wait a second
			# Only bomb clickables left
			loop items in player's current inventory:
				loop-item is white stained glass pane
				if {minesweeper::temp::%player%::bombs::*} contains index of loop-item:
					add 1 to {_bombs}
			if amount of white stained glass pane in player's current inventory is less than or equal to {_bombs}:
				set {_time} to difference between now and {minesweeper::temp::%player%::start}
				set {_uuid} to uuid of player
				set {minesweeper::%{_uuid}%::highscores::%{minesweeper::temp::%player%::difficulty}%::%now%} to {_time}
				message "&7[&cMinesweeper&7] &fYou have found all the bombs! Game took %{_time}%, Good game!"
				set {minesweeper::temp::%player%::finished} to true
				wait 15 ticks
				loop {minesweeper::temp::%player%::bombs::*}:
					slot loop-value of event-inventory is not tnt
					wait 5 ticks
					{minesweeper::temp::%player%::finished} is set
					set slot loop-value of event-inventory to tnt named "&4&lBOMB"
					play sound "BLOCK_GRAVEL_PLACE" at volume 0.4 to player
				wait 3 seconds
				# Make sure the player is still viewing the game gui.
				if {minesweeper::temp::%player%::finished} is set:
					close player's inventory
			clear {_bombs}
			# When all bombs are flagged
			loop {minesweeper::temp::%player%::bombs::*}:
				if slot loop-value of event-inventory is redstone torch:
					add 1 to {_bombs}
			if size of {minesweeper::temp::%player%::bombs::*} is {_bombs}:
				# Play animation and message player.
				set {_time} to difference between now and {minesweeper::temp::%player%::start}
				set {_uuid} to uuid of player
				set {minesweeper::%{_uuid}%::highscores::%{minesweeper::temp::%player%::difficulty}%::%now%} to {_time}
				message "&7[&cMinesweeper&7] &fYou have flagged all the bombs! Game took %{_time}%, Good game!"
				set {minesweeper::temp::%player%::finished} to true
				wait 15 ticks
				loop {minesweeper::temp::%player%::bombs::*}:
					slot loop-value of event-inventory is not tnt
					wait 5 ticks
					{minesweeper::temp::%player%::finished} is set
					set slot loop-value of event-inventory to tnt named "&4&lBOMB"
					play sound "BLOCK_GRAVEL_PLACE" at volume 0.4 to player
				wait 3 seconds
				# Make sure the player is still viewing the game gui.
				if {minesweeper::temp::%player%::finished} is set:
					close player's inventory
			clear {_bombs}
		stop
	# Check if the player clicks a bomb. :(
	if {minesweeper::temp::%player%::bombs::*} contains clicked slot:
		# Play animation and message player.
		message "&7[&cMinesweeper&7] &cOh no! You found a bomb! Better luck next time."
		set {minesweeper::temp::%player%::finished} to true
		play sound "ENTITY_TNT_PRIMED" at pitch 2 to player
		set clicked item to tnt named "&4&lBOMB"
		wait 15 ticks
		loop {minesweeper::temp::%player%::bombs::*}:
			slot loop-value of event-inventory is not tnt
			wait 5 ticks
			{minesweeper::temp::%player%::finished} is set
			set slot loop-value of event-inventory to tnt named "&4&lBOMB"
			play sound "BLOCK_GRAVEL_BREAK" at volume 0.4 to player
		wait 3 seconds
		# Make sure the player is still viewing the game gui.
		if {minesweeper::temp::%player%::finished} is set:
			close player's inventory
		stop
	clicked item is white stained glass pane
	set clicked item to air
	handle(player, clicked slot, event-inventory)

on inventory close:
	{minesweeper::temp::%player%::inventory} is set
	event-inventory is {minesweeper::temp::%player%::inventory}
	clear {minesweeper::temp::%player%::*}

on quit:
	clear {minesweeper::temp::%player%::*}

on script unload:
	delete {minesweeper::temp::*}