<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://sokobano.de/wiki/index.php?action=history&amp;feed=atom&amp;title=JSoko_Solver</id>
	<title>JSoko Solver - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://sokobano.de/wiki/index.php?action=history&amp;feed=atom&amp;title=JSoko_Solver"/>
	<link rel="alternate" type="text/html" href="http://sokobano.de/wiki/index.php?title=JSoko_Solver&amp;action=history"/>
	<updated>2026-04-17T19:07:05Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://sokobano.de/wiki/index.php?title=JSoko_Solver&amp;diff=5541&amp;oldid=prev</id>
		<title>Matthias Meger: /* Search algorithm */</title>
		<link rel="alternate" type="text/html" href="http://sokobano.de/wiki/index.php?title=JSoko_Solver&amp;diff=5541&amp;oldid=prev"/>
		<updated>2017-01-28T23:27:16Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Search algorithm&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;JSoko solver&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
This article is a technical description of my solver.&lt;br /&gt;
&lt;br /&gt;
The JSoko solver is part of my program [http://www.sokoban-online.de JSoko].&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s written in Java. The source code is available as the whole JSoko project is open source.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Limits of the solver ==&lt;br /&gt;
The solver inherits the [[Feature_list_:_General_Information#Limits|limits of JSoko]].&lt;br /&gt;
This means in can only be used for levels not larger than 70*70 squares.&lt;br /&gt;
&amp;lt;br&amp;gt;The solver only tries to find any solution regardless of the number of moves or pushes needed to solve the level.&lt;br /&gt;
&amp;lt;br&amp;gt;The solver can only be used as part of JSoko, since there is no stand-alone version.&lt;br /&gt;
&lt;br /&gt;
== JSoko overall structure ==&lt;br /&gt;
&lt;br /&gt;
=== Search algorithm ===&lt;br /&gt;
The main search is an A* search. The solver only uses forward searching.&lt;br /&gt;
However, if the level is considered a &amp;#039;&amp;#039;goal room level&amp;#039;&amp;#039; then a packing order algorithm calculates a packing sequence for filling the goals first.&lt;br /&gt;
&lt;br /&gt;
=== Heuristic score ===&lt;br /&gt;
The A* search calculates the minimum perfect bipartite matching of the boxes&amp;#039; distances to the goals after every push.&lt;br /&gt;
This pushes lower bound is enhanced by adding a penalty for simple linear conflicts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transposition table ===&lt;br /&gt;
All board positions are stored in a hash table.&lt;br /&gt;
The player player is normalized to the top-left position reachable in the current board position before the board positions are stored in the hash table.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Deadlock detection ===&lt;br /&gt;
JSoko can detect all deadlocks described in the [[Deadlocks]] article.&lt;br /&gt;
Neither a precalculation of deadlocks nor a deadlock database is used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PI-Corral pruning ===&lt;br /&gt;
The solver uses the PI-Corral pruning developed by Brian Damgaard and me to reduce the search tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packing sequence ===&lt;br /&gt;
A packing sequence is calculated for some levels:&amp;lt;br&amp;gt;&lt;br /&gt;
The solver counts the &amp;quot;connected goals&amp;quot;. The definition of &amp;quot;connected goal&amp;quot; is:&lt;br /&gt;
#The goal has one or more neighboring goals&lt;br /&gt;
#When the neighboring goal is located at one axis, there must be a neighboring position along the other axis, which either is a goal too, or a wall&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If the number of connected goals is higher than 8 the level is classified as packing sequence level.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The packing sequence is calculated by performing a backward search:&amp;lt;br&amp;gt;&lt;br /&gt;
all boxes are placed on goals and the search tries to remove one box at a time.&lt;br /&gt;
The box positions at the start of the level are considered &amp;#039;&amp;#039;backward goals&amp;#039;&amp;#039; during the search.&amp;lt;br&amp;gt;&lt;br /&gt;
If a box can be pulled to a backward goal then it is removed from the board.&amp;lt;br&amp;gt;&lt;br /&gt;
If none of the boxes can be pulled to any backward goal anymore the boxes are pulled one position to any direction and then it&amp;#039;s checked again if any of the boxes can now reach a backward goal.&amp;lt;br&amp;gt;&lt;br /&gt;
if all boxes have reached a goal then a packing sequence has been found.&amp;lt;br&amp;gt;&lt;br /&gt;
This push sequence is then used by the forward search to push the boxes to the goals.&lt;/div&gt;</summary>
		<author><name>Matthias Meger</name></author>
	</entry>
</feed>