How to resolve the algorithm 15 puzzle solver step by step in the Forth programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm 15 puzzle solver step by step in the Forth programming language
Table of Contents
Problem Statement
Your task is to write a program that finds a solution in the fewest moves possible single moves to a random Fifteen Puzzle Game. For this task you will be using the following puzzle:
The output must show the moves' directions, like so: left, left, left, down, right... and so on. There are two solutions, of fifty-two moves: rrrulddluuuldrurdddrullulurrrddldluurddlulurruldrdrd rrruldluuldrurdddluulurrrdlddruldluurddlulurruldrrdd see: Pretty Print of Optimal Solution Finding either one, or both is an acceptable result. Solve the following problem:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm 15 puzzle solver step by step in the Forth programming language
Source code in the forth programming language
#! /usr/bin/gforth
cell 8 <> [if] s" 64-bit system required" exception throw [then]
\ In the stack comments below,
\ "h" stands for the hole position (0..15),
\ "s" for a 64-bit integer representing a board state,
\ "t" a tile value (0..15, 0 is the hole),
\ "b" for a bit offset of a position within a state,
\ "m" for a masked value (4 bits selected out of a 64-bit state),
\ "w" for a weight of a current path,
\ "d" for a direction constant (0..3)
\ Utility
: 3dup 2 pick 2 pick 2 pick ;
: 4dup 2over 2over ;
: shift dup 0 > if lshift else negate rshift then ;
hex 123456789abcdef0 decimal constant solution
: row 2 rshift ; : col 3 and ;
: up-valid? ( h -- f ) row 0 > ;
: down-valid? ( h -- f ) row 3 < ;
: left-valid? ( h -- f ) col 0 > ;
: right-valid? ( h -- f ) col 3 < ;
: up-cost ( h t -- 0|1 ) 1 - row swap row < 1 and ;
: down-cost ( h t -- 0|1 ) 1 - row swap row > 1 and ;
: left-cost ( h t -- 0|1 ) 1 - col swap col < 1 and ;
: right-cost ( h t -- 0|1 ) 1 - col swap col > 1 and ;
\ To iterate over all possible directions, put direction-related functions into arrays:
: ith ( u addr -- w ) swap cells + @ ;
create valid? ' up-valid? , ' left-valid? , ' right-valid? , ' down-valid? , does> ith execute ;
create cost ' up-cost , ' left-cost , ' right-cost , ' down-cost , does> ith execute ;
create step -4 , -1 , 1 , 4 , does> ith ;
\ Advance from a single state to another:
: bits ( h -- b ) 15 swap - 4 * ;
: tile ( s b -- t ) rshift 15 and ;
: new-state ( s h d -- s' ) step dup >r + bits 2dup tile ( s b t ) swap lshift tuck - swap r> 4 * shift + ;
: new-weight ( w s h d -- w' ) >r tuck r@ step + bits tile r> cost + ;
: advance ( w s h d -- w s h w' s' h' ) 4dup new-weight >r 3dup new-state >r step over + 2r> rot ;
\ Print a solution:
: rollback 2drop drop ;
: .dir ( u -- ) s" d..r.l..u" drop 4 + swap + c@ emit ;
: .dirs ( .. -- ) 0 begin >r 3 pick -1 <> while 3 pick over - .dir rollback r> 1+ repeat r> ;
: win cr ." solved (read right-to-left!): " .dirs ." - " . ." moves" bye ;
\ The main recursive function for depth-first search:
create limit 1 , : deeper 1 limit +! ;
: u-turn ( .. h2 w1 s1 h1 ) 4 pick 2 pick - ;
: search ( .. h2 w1 s1 h1 )
over solution = if win then
2 pick limit @ > if exit then
4 0 do dup i valid? if i step u-turn <> if i advance recurse rollback then then loop ;
\ Iterative-deepening search:
: solve 1 limit ! begin search deeper again ;
\ -1 0 hex 0c9dfbae37254861 decimal 0 solve \ uhm.
-1 0 hex fe169b4c0a73d852 decimal 8 solve \ the 52 moves case
\ -1 0 hex 123456789afbde0c decimal 14 solve \ some trivial case, 3 moves
bye
You may also check:How to resolve the algorithm Population count step by step in the Free Pascal programming language
You may also check:How to resolve the algorithm Twin primes step by step in the jq programming language
You may also check:How to resolve the algorithm Nth root step by step in the NewLISP programming language
You may also check:How to resolve the algorithm Loops/While step by step in the Tailspin programming language
You may also check:How to resolve the algorithm Modular inverse step by step in the Rust programming language