///CS 7A Sam Lloyd's 14-15 Puzzle. - Page 2 of 2 Due 3/26/15
/// Geoff Hagopian

#include "std_lib_facilities.h"

unsigned getBlank(vector<unsigned> v) {
    unsigned i = 0;
    while(v[i]!=0) ++i;
    return i;
}

class SliderPuzzle {
public:
    unsigned edge;
    vector<unsigned> board;
    SliderPuzzle(unsigned e) : edge(e) {
        for(unsigned i=0; i < edge*edge; ++i)
            board.push_back(i);
    }
    void display();
    void shuffle(); ///takes a board and mixes it up  with the
                /// Fisher Yates shuffle algorithm
                ///After shuffling the board , a call to the 15
                ///function display() will produce a shuffled
                ///board like this
                /**
                14  5  4 11
                17 12  9  6
                7  13  8 10
                   15 13  2
                */
    bool won() {
        for(unsigned i = 0;i < edge*edge-1; ++i)
            if(board[i]!=i+1) return false;
        return true;
    }
    ///returns true if the board is as below, otherwise false
    /**
     1  2  3  4
     5  6  7  8
     9 10 11 12
    13 14 15
    */
    void getMove() {
    ///prompts the user to enter u, d, l, r
    /// moves the pieces on the board accordingly
        char move;
        cin>>move;
        switch(move) {
        case 'u': {
            unsigned blank = getBlank(board);
            if(blank >= edge*(edge-1)) {
                cout << "\ncan't do that, try again";
                return;
            }
            board[blank]=board[blank+edge];
            board[blank+edge]=0;
            break;
        }
        default :
            cout << "\nI don't know that command, tray again.";
            return;
        }


    }
};

void SliderPuzzle::display() {
    for(unsigned i=0; i<edge*edge;++i) {
        if(board[i]==0) cout << "    ";
        else cout << setw(3) << board[i] << ' ';
        if((i+1)%edge == 0)
            cout << endl;
    }
}

void SliderPuzzle::shuffle() {
    unsigned temp, next;
    for(int i = edge*edge-1; i > 0; i--) {
        next = rand()%i;
        temp = board[i];
        board[i]=board[next];
        board[next] = temp;
    }
}
//

int main() {
    /// create a board
    srand(unsigned(time(0)));
    SliderPuzzle puzz(6);
    ///puzz.display();
    puzz.shuffle();
    cout << endl;
    puzz.display();
    while(!puzz.won()) {
        puzz.getMove();
        puzz.display();
    }
}
