extern crate rand;

use std::collections::HashMap;
use std::fmt;

use rand::Rng;
use rand::seq::SliceRandom;

#[derive(Copy, Clone, PartialEq, Debug)]
enum Cell {
    Card(usize),
    Empty,
}

#[derive(Eq, PartialEq, Hash, Debug)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

enum Action {
    Move(Direction),
    Quit,
}

type Board = [Cell; 16];
const EMPTY: Board = [Cell::Empty; 16];

struct P15 {
    board: Board,
}

impl P15 {
    fn new() -> Self {
        let mut board = EMPTY;
        for (i, cell) in board.iter_mut().enumerate().skip(1) {
            *cell = Cell::Card(i);
        }

        let mut rng = rand::thread_rng();

        board.shuffle(&mut rng);
        if!Self::is_valid(board) {