/* Author: Alexander Switzer */

//includes
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>

// structs
struct camel {
    char * name;
    int indexOfBelow;
    bool isGroundBelow;
};

struct ground {
    int indexOfTopCamel;
};

// header
void printTrack(struct ground track[], struct camel camels[]);
int getGround(struct ground track[], struct camel camels[], int indexOfCamel);
void moveCamel(struct ground track[], struct camel camels[], int indexOfCamel, int amount);

//lenth of the race track
const int trackSize = 30;
//amount of camels
const int camelsSize = 7;


int main(){

    //set up random seed
    srand(time(NULL)); 

    //array to store all the camels
    struct camel camels[camelsSize];
    //array to store all the squares on the track
    struct ground track[trackSize];

    //set all the camels

    //one one the ground
    camels[0].name = "Violet";
    //this index is used on the track array
    camels[0].indexOfBelow = 0;
    //to note the index is for the ground
    camels[0].isGroundBelow = true;

    //not on the ground
    camels[1].name = "Indigo";
    //this index is used on camels array
    camels[1].indexOfBelow = 0;
    //to note the index is for the camels array
    camels[1].isGroundBelow = false;

    camels[2].name = "Blue";
    camels[2].indexOfBelow = 1;
    camels[2].isGroundBelow = false;

    camels[3].name = "Green";
    camels[3].indexOfBelow = 2;
    camels[3].isGroundBelow = false;

    camels[4].name = "Yellow";
    camels[4].indexOfBelow = 3;
    camels[4].isGroundBelow = false;

    camels[5].name = "Orange";
    camels[5].indexOfBelow = 4;
    camels[5].isGroundBelow = false;

    camels[6].name = "Red";
    camels[6].indexOfBelow = 5;
    camels[6].isGroundBelow = false;

    //set the fist square to point to Indigo
    track[0].indexOfTopCamel = camelsSize - 1;
    //set all to be empty
    for (int i = 1; i < trackSize; i++)
    {
        track[i].indexOfTopCamel = -1;
    }

    // loop untill the is a winner
    while(true){
        //get raodom numbers
        //witch camel
        int index = rand() % camelsSize;
        //how far to move
        int amount = rand() % 3 + 1;

        //print the move
        printf("Camel %s is moving %x tiles\n", camels[index].name, amount);
        //move camel
        moveCamel(track, camels, index, amount);
        //show the change
        printTrack(track, camels);
        //just note the next move set
        printf("-----------------------");
        //wait for next
        getchar();
    }

    //just in-case the while(true) exits
    return -1;
}

//print a track
void printTrack(struct ground track[], struct camel camels[]){
    //go though all squares
    for (int i = 0; i < trackSize; i++){
        
        //if the square is empty
        if(track[i].indexOfTopCamel == -1){
            //just print the square number
            printf("%d\n", i);
            //stop the loop
            continue;
        }

        //start line
        printf("%d ", i);

        //save the found camel for revsing
        //number found
        int k = 0;
        int line[camelsSize];

        //loop though all data backwards
        int index = track[i].indexOfTopCamel;

        //keep looking untill you find a camel on the ground
        while(!camels[index].isGroundBelow){
            //save the index
            line[k] = index;
            //add one to the cound of camels found
            k++;
            //move on to the next camles
            index = camels[index].indexOfBelow;
        }

        //save the next camles
        line[k] = index;

        //print the fist camel with no fist arrow
        printf("%s",  camels[line[k]].name);
        //move back one camel
        k--;

        //loop though found camels
        while (k >= 0)
        {
            //print camel
            printf("<-%s",  camels[line[k]].name);
            //move to next camel
            k--;
        }
        
        //print the last camel
        printf("\n");
    }
}

int getGround(struct ground track[], struct camel camels[], int indexOfCamel){
    //find the square that a camel is standing on.
    //keep going untill a camel is on the grouid
    while(!camels[indexOfCamel].isGroundBelow){
        //move down a camel
        indexOfCamel = camels[indexOfCamel].indexOfBelow;
    }
    //return the index of the square
    return camels[indexOfCamel].indexOfBelow;
}

//move a camel stack
void moveCamel(struct ground track[], struct camel camels[], int indexOfCamel, int amount){

    //get what tile the moved camel is on
    int currentGround = getGround(track, camels, indexOfCamel);
    //where they will move to
    int newGround = currentGround + amount;

    //check for a winner
    if (newGround >= trackSize){

        //say good job
        printf("The winner %s",  camels[track[currentGround].indexOfTopCamel].name);

        //quit
        exit(0);
    }

    //get all the need values
    int newGroundCurrentTop = track[newGround].indexOfTopCamel;
    int newGroundNewTop = track[currentGround].indexOfTopCamel;
    int currentGroundNewTop = camels[indexOfCamel].indexOfBelow;
    bool currentGroundIsBottom = camels[indexOfCamel].isGroundBelow;

    //move the pick camel
    if(track[newGround].indexOfTopCamel != -1){
        //there is alread a stack on the tile
        //point moved camel to to top of the stack
        camels[indexOfCamel].indexOfBelow = newGroundCurrentTop;
        camels[indexOfCamel].isGroundBelow = false;
        track[newGround].indexOfTopCamel = newGroundNewTop;
    } else {
        //new camel to the tile
        //point moved camel to the tile index
        camels[indexOfCamel].indexOfBelow = newGround;
        camels[indexOfCamel].isGroundBelow = true;
        track[newGround].indexOfTopCamel = newGroundNewTop;
    }

    //clean up tile that was left
    if(currentGroundIsBottom == false){
        //there is still camels on the stack
        track[currentGround].indexOfTopCamel = currentGroundNewTop;
    } else {
        //the stack is now empty
        track[currentGround].indexOfTopCamel = -1;
    }
    
}
