Jump to content
Rpg²S Forum

*Sudoku


Omega Ciccio
 Share

Recommended Posts

Descrizione
Un semplice script che permette di implementare il minigioco "Sudoku" nel proprio gioco.

Autore
SephirothSpawn

Allegati
n/d

Istruzioni
(All'interno dello Script ^_^)


 

#==============================================================================
# ** Sudoku Puzzles
#------------------------------------------------------------------------------
# SephirothSpawn
# Version 1
# 2006-08-06
#------------------------------------------------------------------------------
# * Description:
#
#  ~ Creates Randomized Sudoku Puzzles and Allows the Player to Solve Them
#  ~ This Script will create a data file for all solutions the engine will
#	come up with. Make sure you run the solution maker enough times for 
#	random solutions
#------------------------------------------------------------------------------
# * Controls:
#
#  ~ Direction Keys : Moves Cursor From Cell to Cell
#  ~ L & R : Increase and Decrease Cell Number
#------------------------------------------------------------------------------
# * Installation:
#
#  ~ Place the Script below the RMXP SDK and above main
#  ~ Customize the Sudoku_Puzzles module for puzzle data (Customization Below)
#------------------------------------------------------------------------------
# * Instructions:
#
#  ~ To Create A Solution File, use a Call script with:
#	Call Script : SudokuPuzzles.generate_solution
#
# ** Note that the game can crash. This is normal. Just run it again.
#	It happens because it retries too many times to create a table without
#	success.
#
#  ~ To Open a Puzzle, use the syntax:
#	$scene.open_sudokupuzzle(puzzle_id, numbers_given)
#	numbers_given is the number of cells maker gives you
#
#  ~ To Reset a Puzzle, use the syntax:
#	$game_sudokupuzzles.reset_puzzle_data(puzzle_id)
#
#  ~ To Test for solved puzzle, use the syntax:
#	$game_sudokupuzzles[puzzle_id].solved?
#------------------------------------------------------------------------------
# * Customization:
#   (refer to module SudokuPuzzles)
#
#  ~ To Create a Solution File in the Game Folder:
#	Create_Solution_File = true (ON) or false (OFF)
#
#  ~ Sound Effects
#	Puzzle_Solved_SE = RPG::AudioFile
#	Puzzle_Unsolved_SE = RPG::AudioFile
#
#  ~ Default Number of Cells Given
#	Default_Difficulty = N
#------------------------------------------------------------------------------
# * Thanks To Zeriab for bug fix
#==============================================================================

#------------------------------------------------------------------------------
# * SDK Log Script
#------------------------------------------------------------------------------
SDK.log('Sudoku Puzzles', 'SephirothSpawn', 1, '2006-08-06')

#------------------------------------------------------------------------------
# * Begin SDK Enable Test
#------------------------------------------------------------------------------
if SDK.state('Sudoku Puzzles') == true
  
#==============================================================================
# ** SudokuPuzzles
#==============================================================================

module SudokuPuzzles
  #--------------------------------------------------------------------------
  # * Create Solution File
  #--------------------------------------------------------------------------
  Create_Solution_File = true
  #--------------------------------------------------------------------------
  # * Sound Effects
  #--------------------------------------------------------------------------
  Puzzle_Solved_SE = load_data("Data/System.rxdata").decision_se
  Puzzle_Unsolved_SE = load_data("Data/System.rxdata").buzzer_se
  #--------------------------------------------------------------------------
  # * Default Difficulty
  #
  #  ~ How Many Will be showed upon start up
  #--------------------------------------------------------------------------
  Default_Difficulty = 35
  #--------------------------------------------------------------------------
  # * This Will Save All Solutions the Maker Comes Up With
  #--------------------------------------------------------------------------
  def self.save_solution(solution_table)
	# Test For Saved Solution File
	unless FileTest.exist?('Data/SudokuSolutions.rxdata')
	  save_data({}, 'Data/SudokuSolutions.rxdata')
	end
	# Collects Saved Solution List
	saved_solutions = load_data('Data/SudokuSolutions.rxdata')
	# Saves List to Data File
	saved_solutions << solution_table
	# Resaves New Solution to File
	save_data(saved_solutions, 'Data/SudokuSolutions.rxdata')
  end
  #--------------------------------------------------------------------------
  # * Generate Solution
  #--------------------------------------------------------------------------
  def self.generate_solution
	# Creates Solution Table Data
	@solution = Table.new(9, 9)
	# Assigns Each Tile a Number
	81.times do
	  # Collects Cell Ranges
	  ranges = self.collect_cell_ranges
	  # If No Ranges
	  if ranges.nil?
		self.generate_solution
		return
	  end
	  # Gets Min Range
	  min_range = ranges.values.min
	  # Gets Index of Min Range
	  index = ranges.index(min_range)
	  # Gets Index X Y Coordinates
	  x = index % 9
	  y = index / 9
	  # Collects Ranges
	  range = self.collect_range(x, y)
	  # Sets Solution Value
	  @solution[x, y] = range[rand(range.size)]
	end
	# Saves Solution to Data File
	self.save_solution(@solution)
  end
  #--------------------------------------------------------------------------
  # * Collect Cell Ranges
  #--------------------------------------------------------------------------
  def self.collect_cell_ranges
	# Starts Ranges Hash
	ranges = {}
	# Checks All Cells
	for i in 0...81
	  # Gets X Y Coordinates
	  x = i % 9
	  y = i / 9
	  # If No Number in Cell
	  if @solution[x, y] == 0
		# If No Possible Range For Cell
		if self.collect_range(x, y).size == 0
		  # Restart Setup Solution
		  self.generate_solution
		  return
		end
		# Store Range
		ranges[i] = collect_range(x, y).size
	  end
	end
	# Return Ranges
	return ranges
  end
  #--------------------------------------------------------------------------
  # * Collects Possible Numbers For Cell
  #--------------------------------------------------------------------------
  def self.collect_range(x, y)
	# Gets All Possible Numbers
	range = (1..9).to_a
	# Checks Column & Row Numbers And Removes Impossible Numbers
	for i in 0...9
	  if range.include?(@solution[i, y])
		range.delete(@solution[i, y])
	  end
	  if range.include?(@solution[x, i])
		range.delete(@solution[x, i])
	  end
	end
	# Checks Sub-Cell And Removes Impossible Numbers
	subcell_size = 3
	subcell_x = x / subcell_size
	subcell_y = y / subcell_size
	for y_count in 0...subcell_size
	  for x_count in 0...subcell_size
		x_ = subcell_x * subcell_size + x_count
		y_ = subcell_y * subcell_size + y_count
		if range.include?(@solution[x_, y_])
		  range.delete(@solution[x_, y_])
		end
	  end
	end
	# Returns Possible Numbers
	return range
  end
end

#==============================================================================
# ** Game_SudokuPuzzles
#==============================================================================

class Game_SudokuPuzzles
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
	# Starts Data
	@data = []
  end
  #--------------------------------------------------------------------------
  # * Get Puzzle Data
  #--------------------------------------------------------------------------
  def [](puzzle_id, number_cells = SudokuPuzzles::Default_Difficulty)
	# Creates Unstarted Data
	if @data[puzzle_id].nil?
	  @data[puzzle_id] = Game_SudokuPuzzle.new(number_cells)
	end
	return @data[puzzle_id]
  end
  #--------------------------------------------------------------------------
  # * Reset Puzzle Data
  #--------------------------------------------------------------------------
  def reset_puzzle_data(puzzle_id)
	n = number_cells = SudokuPuzzles::Default_Difficulty
	unless @data[puzzle_id].nil?
	  n = @data[puzzle_id].number_cells
	end
	@data[puzzle_id] = Game_SudokuPuzzle.new(n)
  end
end

#==============================================================================
# ** Game_SudokuPuzzle
#==============================================================================

class Game_SudokuPuzzle
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader :number_cells
  attr_reader :showncells
  attr_reader :player_numbers
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(number_cells = SudokuPuzzles::Default_Difficulty)
	# Picks Random Solution File
	saved_solutions = load_data('Data/SudokuSolutions.rxdata')
	@solution = saved_solutions[rand(saved_solutions.size)]
	# Sets Up Shown Cell Numbers & Player Cells
	@number_cells = number_cells
	setup_showncells(number_cells)
	# Creates Solution File
	if SudokuPuzzles::Create_Solution_File
	  @solution.create_file('Sudoku Solution File.txt')
	end
  end
  #--------------------------------------------------------------------------
  # * Sets Up Shown Cells
  #--------------------------------------------------------------------------
  def setup_showncells(number_cells)
	@showncells = Table.new(9, 9)
	@player_numbers = Table.new(9, 9)
	i = 0
	until i == number_cells
	  x, y = rand(9), rand(9)
	  if @showncells[x, y] == 0
		@showncells[x, y] = @solution[x, y]
		@player_numbers[x, y] = @solution[x, y]
		i += 1
	  end
	end
  end
  #--------------------------------------------------------------------------
  # * Solved
  #--------------------------------------------------------------------------
  def solved?
	# Test Player Entered Each Number
	for x in 0..8
	  for y in 0..8
		return false if @player_numbers[x, y] == 0
	  end
	end
	# Test Rows
	for i in 0..8
	  return false unless test_rows(i)
	end
	# Test Columns
	for i in 0..8
	  return false unless test_columns(i)
	end
	# Test Sub-Cells
	for i in 0..8
	  return false unless test_subcells(i)
	end
	# Return Solved
	return true
  end
  #--------------------------------------------------------------------------
  # * Test Row Numbers
  #--------------------------------------------------------------------------
  def test_rows(y)
	numbers = []
	for i in 0..8
	  return false if numbers.include?(@player_numbers[i, y])
	  numbers << @player_numbers[i, y]
	end
	return numbers.sort == (1..9).to_a
  end
  #--------------------------------------------------------------------------
  # * Collect Column Numbers
  #--------------------------------------------------------------------------
  def test_columns(x)
	numbers = []
	for i in 0..8
	  return false if numbers.include?(@player_numbers[x, i])
	  numbers << @player_numbers[x, i]
	end
	return numbers.sort == (1..9).to_a
  end
  #--------------------------------------------------------------------------
  # * Collect Sub-Cell Numbers
  #--------------------------------------------------------------------------
  def test_subcells(n)
	numbers = []
	subcell_x = n % 3
	subcell_y = n / 3
	for x in 0..2
	  for y in 0..2
		i = subcell_x * 3 + x
		j = subcell_y * 3 + y
		return false if numbers.include?(@player_numbers[i, j])
		numbers << @player_numbers[i, j]
	  end
	end
	return numbers.sort == (1..9).to_a
  end
  #--------------------------------------------------------------------------
  # * Reset
  #--------------------------------------------------------------------------
  def reset
	@player_numbers = @showncells.dup
  end
end

#==============================================================================
# ** Window_SudokuPuzzle
#==============================================================================

class Window_SudokuPuzzle < Window_Base
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader :puzzle
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(puzzle_id)
	super(196, 100, 249, 280)
	self.contents = Bitmap.new(width - 32, height - 32)
	# Sets Puzzle Data
	@puzzle = $game_sudokupuzzles[puzzle_id]
	@puzzle_id = puzzle_id
	# Refresh Contents
	refresh
	@index = 0
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
	self.contents.clear
	# Draws Grid
	for i in [1, 2, 4, 5, 7, 8]
	  self.contents.fill_rect(0, i * 24, 216, 1, Color.new(0, 0, 0, 255))
	  self.contents.fill_rect(i * 24, 0, 1, 216, Color.new(0, 0, 0, 255))
	end
	for i in [0, 3, 6, 9]
	  color = 
	  self.contents.fill_rect(0, i * 24, 216, 1, Color.new(200, 0, 0, 255))
	  self.contents.fill_rect(i * 24, 0, 1, 216, Color.new(200, 0, 0, 255))
	end
	# Redraws Cell Data
	for x in 0..9
	  for y in 0..9
		refresh_celldata(x, y)
	  end
	end
	# Draws Puzzle Options
	self.contents.draw_text(0, 220, 108, 24, 'Restart', 1)
	self.contents.draw_text(108, 220, 108, 24, 'New Puzzle', 1)
  end
  #--------------------------------------------------------------------------
  # * Refresh Cell Data
  #--------------------------------------------------------------------------
  def refresh_celldata(x, y)
	# Gets Cell Rect
	rect = Rect.new(x * 24 + 1, y * 24 + 1, 23, 23)
	# Clears Rect
	self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
	# If Given Cell
	unless @puzzle.showncells[x, y] == 0
	  self.contents.font.color = system_color
	  self.contents.draw_text(rect, @puzzle.showncells[x, y].to_s, 1)
	  self.contents.font.color = normal_color
	  return
	end
	# Gets Player Number
	n = @puzzle.player_numbers[x, y]
	# Draws Player Number
	unless n == 0
	  self.contents.draw_text(rect, n.to_s, 1)
	end
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
	super
	# If Right is Pressed
	if Input.repeat?(Input::RIGHT)
	  $game_system.se_play($data_system.cursor_se)
	  @index = @index == 82 ? 0 : @index + 1
	# If Left is Pressed
	elsif Input.repeat?(Input::LEFT)
	  $game_system.se_play($data_system.cursor_se)
	  @index = @index == 0 ? 82 : @index - 1
	# If Up is Pressed
	elsif Input.repeat?(Input::UP)
	  $game_system.se_play($data_system.cursor_se)
	  if @index > 80
		@index -= 9
		return
	  end
	  top_index = (0..8).to_a
	  bottom_index = (72..80).to_a
	  if top_index.include?(@index)
		@index = bottom_index[top_index.index(@index)]
	  else
		@index -= 9
	  end
	# If Down is Pressed
	elsif Input.repeat?(Input::DOWN)
	  return if @index > 80
	  $game_system.se_play($data_system.cursor_se)
	  top_index = (0..8).to_a
	  bottom_index = (72..80).to_a
	  if bottom_index.include?(@index)
		@index = 81 # top_index[bottom_index.index(@index)]
	  else
		@index += 9
	  end
	end
	# Collects X and Y
	x = @index % 9
	y = @index / 9
	# If L is Pressed
	if Input.trigger?(Input::R)
	  # If Non-Shown Cell
	  unless @puzzle.showncells[x, y] == 0
		# Play Buzzer Se
		$game_system.se_play($data_system.buzzer_se)
		return
	  end
	  # Increases Player Number Cell
	  @puzzle.player_numbers[x, y] = @puzzle.player_numbers[x, y] == 9 ? 
		0 : @puzzle.player_numbers[x, y] + 1
	  # Refreshes Cell Number
	  refresh_celldata(x, y)
	# If R Button is Pressed
	elsif Input.trigger?(Input::L)
	  # If Non-Shown Cell
	  unless @puzzle.showncells[x, y] == 0
		# Play Buzzer Se
		$game_system.se_play($data_system.buzzer_se)
		return
	  end
	  # Decreases Player Number Cell
	  @puzzle.player_numbers[x, y] = @puzzle.player_numbers[x, y] == 0 ? 
		9 : @puzzle.player_numbers[x, y] - 1
	  # Refreshes Cell Number
	  refresh_celldata(x, y)
	end
	# If C Button Is Pressed
	if Input.trigger?(Input::C)
	  # Return if Not Puzzle Option
	  return unless [81, 82].include?(@index)
	  # Play decision Se
	  $game_system.se_play($data_system.decision_se)
	  # If Restart Puzzle
	  if @index == 81
		@puzzle.reset
		refresh
	  end
	  # If New Puzzle
	  if @index == 82
		$game_sudokupuzzles.reset_puzzle_data(@puzzle_id)
		@puzzle = $game_sudokupuzzles[@puzzle_id]
		refresh
	  end
	end
	# Update Cursor Rect
	update_cursor_rect
  end
  #--------------------------------------------------------------------------
  # * Cursor Rectangle Update
  #--------------------------------------------------------------------------
  def update_cursor_rect
	# If Grid Index
	if @index < 81
	  self.cursor_rect.set(@index % 9 * 24 + 1, @index / 9 * 24 + 1, 23, 23)
	else
	  self.cursor_rect.set(@index == 81 ? 0 : 108, 220, 108, 24)
	end
  end
end

#==============================================================================
# ** Table
#==============================================================================

class Table
  #--------------------------------------------------------------------------
  # * Create File with Data
  #--------------------------------------------------------------------------
  def create_file(filename = 'Table Inspection.txt')
	file = File.open(filename, 'wb')
	for z in 0...self.zsize
	  for y in 0...self.ysize
		for x in 0...self.xsize
		  file.write("#{self[x, y]}")
		end
		file.write('\n')
	  end
	  file.write('\n\n')
	end
	file.close
  end
end

#==============================================================================
# ** Scene_Map
#==============================================================================

class Scene_Map
  #--------------------------------------------------------------------------
  # * Alias Listings
  #--------------------------------------------------------------------------
  alias seph_sudokupuzzles_scnmap_update update
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
	# If Shift Puzzle Active
	unless @seph_sudokupuzzle_window.nil?
	  update_seph_sudokupuzzle
	  return
	end
	# Original Update
	seph_sudokupuzzles_scnmap_update
  end
  #--------------------------------------------------------------------------
  # * Frame Update : Seph Sudoku Puzzle
  #--------------------------------------------------------------------------
  def update_seph_sudokupuzzle
	# Update Shift Puzzle Window
	@seph_sudokupuzzle_window.update
	# Update Map and Spriteset
	$game_map.update
	$game_system.map_interpreter.update
	$game_system.update
	$game_screen.update
	@spriteset.update
	@message_window.update
	# If B Button is Pressed
	if Input.trigger?(Input::B)
	  # If Puzzle Solved
	  if @seph_sudokupuzzle_window.puzzle.solved?
		# Play Solved SE
		$game_system.se_play(SudokuPuzzles::Puzzle_Solved_SE)
	  else
		# Play Unsolved SE
		$game_system.se_play(SudokuPuzzles::Puzzle_Unsolved_SE)
	  end
	  # Dispose Window
	  @seph_sudokupuzzle_window.dispose
	  @seph_sudokupuzzle_window = nil
	end
  end
  #--------------------------------------------------------------------------
  # * Open Sudoku Puzzle
  #--------------------------------------------------------------------------
  def open_sudokupuzzle(puzzle_id = 1)
	# Creates Shift Puzzle Window
	@seph_sudokupuzzle_window = Window_SudokuPuzzle.new(puzzle_id)
  end
end

#==============================================================================
# ** Scene_Title
#==============================================================================

class Scene_Title
  #--------------------------------------------------------------------------
  # * Alias Listings
  #--------------------------------------------------------------------------
  alias seph_sudokupuzzles_scnttl_cng command_new_game
  #--------------------------------------------------------------------------
  # * Command : New Game
  #--------------------------------------------------------------------------
  def command_new_game
	# Original Command New Game
	seph_sudokupuzzles_scnttl_cng
	# Creates Sudoku Puzzle Game Data
	$game_sudokupuzzles = Game_SudokuPuzzles.new
  end
end

#==============================================================================
# ** Scene_Save
#==============================================================================

class Scene_Save
  #--------------------------------------------------------------------------
  # * Alias Listings
  #--------------------------------------------------------------------------
  alias seph_sudokupuzzles_scnsave_wd write_data
  #--------------------------------------------------------------------------
  # * Command : New Game
  #--------------------------------------------------------------------------
  def write_data(file)
	# Original Write Data
	seph_sudokupuzzles_scnsave_wd(file)
	# Saves Sudoku Puzzle Data
	Marshal.dump($game_sudokupuzzles, file)
  end
end

#==============================================================================
# ** Scene_Load
#==============================================================================

class Scene_Load
  #--------------------------------------------------------------------------
  # * Alias Listings
  #--------------------------------------------------------------------------
  alias seph_sudokupuzzles_scnload_rd read_data
  #--------------------------------------------------------------------------
  # * Command : New Game
  #--------------------------------------------------------------------------
  def read_data(file)
	# Original Write Data
	seph_sudokupuzzles_scnload_rd(file)
	# Saves Sudoku Puzzle Data
	$game_sudokupuzzles = Marshal.load(file)
  end
end

#------------------------------------------------------------------------------
# * End SDK Enable Test
#------------------------------------------------------------------------------
end

 

 

 

http://th09.deviantart.net/fs26/150/f/2008/091/7/3/Rule_of_Rose__brush__by_maelstromb.png

Coming http://i56.tinypic.com/fu56c6.png Soon...

http://fc06.deviantart.net/fs47/f/2009/163/8/a/Polka_from_Eternal_Sonata_by_oOLuccianaOo.pnghttp://fc00.deviantart.com/fs34/f/2008/306/2/d/Icon_Hojo_by_Sasori_donna.gif

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...