# Sliding Puzzle (#196)

**URL:** <https://www.ruby-forum.com/t/sliding-puzzle-196/162774>\
**Category:** Ruby\
**Created:** [March 13, 2009, 4:52pm UTC](https://www.ruby-forum.com/t/sliding-puzzle-196/162774 "2009-03-13T16:52:26Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [March 13, 2009, 4:52pm UTC](https://www.ruby-forum.com/t/sliding-puzzle-196/162774/1 "2009-03-13T16:52:26Z")

</div>

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Q.:

1. Please do not post any solutions or spoiler discussion for this  
quiz until 48 hours have elapsed from the time this message was  
sent.

2. Support Ruby Q. by submitting ideas and responses  
as often as you can! Visit: [http://rubyquiz.strd6.com](http://rubyquiz.strd6.com)

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem  
helps everyone on Ruby T. follow the discussion. Please reply to  
the original quiz message, if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

## Sliding Puzzle (#196)

Bienvenidos fellow Rubyists,

This weeks quiz will be to create and implement a [sliding puzzle](http://en.wikipedia.org/wiki/Fifteen_puzzle).  
The puzzle must be playable from keyboard input. The program will  
generate a puzzle in a random configuration and the puzzle generated  
must be solvable. You may create either the 8-puzzle or the 15-puzzle.  
You may include a mode that will automatically solve the puzzle or  
present a hint.

The puzzle must throw a small party when solved.

Bonus: Have the puzzle be displayed as an ascii art image that needs  
to be arranged instead of simple numbers.

Have Fun!

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [March 16, 2009, 6:07pm UTC](https://www.ruby-forum.com/t/sliding-puzzle-196/162774/2 "2009-03-16T18:07:39Z")

</div>

My small solution attached. It will create an 8-puzzle by default, but  
can do n-puzzle if you specify width and height as parameters.

Then you can shuffle it with ‘s’ key - it will make 100 random moves.

Everything else remains basic… so the party when solved 😉

Martin

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [March 17, 2009, 10:55am UTC](https://www.ruby-forum.com/t/sliding-puzzle-196/162774/3 "2009-03-17T10:55:11Z")

</div>

I fixed a bug if board isn’t square (messed up x and y on my one  
dimensional container). Now for example:

spuzzle.rb 10 3

…works - to play on a 10x3 board .

martin

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [March 23, 2009, 7:55pm UTC](https://www.ruby-forum.com/t/sliding-puzzle-196/162774/4 "2009-03-23T19:55:48Z")

</div>

The sole submission to this week’s quiz comes from Martin B…  
Martin provided a simple and versatile solution. It can generate  
puzzles of any size, and is able to shuffle to a random starting  
configuration. It also throws a nice party when the player succeeds.

The program provides a driver that reads keyboard commands and  
translates them into the correct actions on the puzzle class. The  
program accepts four movement commands as well as commands to quit and  
shuffle.

Here’s a look at the puzzle’s shuffle method to randomize the  
configuration:

```
def shuffle
  100.times { move 'udlr'[(rand*4).to_i].chr }
end

```

The shuffling is done by making 100 random moves, this ensures that  
the puzzle remains solvable; a random shuffling of the tiles without  
maintaining the movement constraints is not necessarily solvable.  
Additionally, this leverages the existing functionality of the `move`  
method to keep the code simple. One potential drawback is that this  
doesn’t select all possible starting positions with equal probability.  
However, having the random configurations generated with equal  
probability wasn’t a quiz requirement, and it is often best to go with  
the least complex solution that meets the requirements.

The method to detect whether or not the puzzle is solved also  
leverages existing functionality to reduce complexity, it checks if  
the current board is equal to a newly created board. Because the newly  
created board starts in the solved position and the board is an array  
of integers, this leads to a short and sweet definition:

```
def solved?
  @board == mkboard(@x,@y) && @moved
end

```

The check for `@moved` to be true is to prevent the puzzle from  
partying when the game is first created and before it is shuffled.  
Speaking of the party, here’s the section responsible for that magical  
functionality:

```
puts
10.times { $stdout.print '*'; sleep 0.1; $stdout.flush }
puts " You won!\n"

```

It creates a rapid display of asterisks and congratulates the player!

Thank you, Martin, for a wonderful solution!

[http://rubyquiz.strd6.com/quizzes/196](http://rubyquiz.strd6.com/quizzes/196)

- Daniel
