#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <sys/time.h>
#include "Random.h"

#define MIN_GET_ONBOARD    500
#define MIN_STAY_AT        300
//minimum dice to roll on if not to MIN_STAY_AT
#define MIN_WILL_ROLL 3

/*
	Three different pairs scores 1000 points
	single fives worth 50 points
	single ones worth 100 points
	three of a kinds worth 100 points times the number rolled, except for three ones which is worth 1000 points.
	If four, five, or six of a kind is rolled, each additional die is worth double the three of a kind score
	straight from 1 to 6 is worth 1500 points.
	
*/

static uint32_t Roll_Dice(uint64_t *s, char onboard){
	/*Roll 6 dice and play out a turn of 10,000*/
	//uint64_t rand_seed = 
	uint32_t rand_num1 = 0;
	//uint32_t lrand(uint64_t *s)
	uint32_t score = 0;
	uint32_t score_tmp = 0;
	uint32_t num1 = 0;
	uint32_t num2 = 0;
	uint32_t dice_to_roll = 6;
	char turn_over = 0;
	char roll_results[6] = {0, 0, 0, 0, 0, 0};
	char num_counts[6]   = {0, 0, 0, 0, 0, 0};
	char *c_ptr;
	struct Comb comb;
	(void)memset(&comb, '\0', sizeof(struct Comb));
/*
	char has_straight      = 0;
	char has_three_pairs   = 0;
	char has_single_five   = 0;
	char has_single_one    = 0;
	char has_three_of_kind = 0;
	char has_four_of_kind  = 0;
	char has_five_of_kind  = 0;
	char has_six_of_kind   = 0;
	char has_two_one       = 0;
	char has_two_five      = 0;
	char zilch = 0;
	char dice_left_over    = 0;
*/

	while(!turn_over){
		(void)memset(&comb, '\0', sizeof(struct Comb));
		(void)memset(roll_results, '\0', 6);
		//roll dice
		for(num1=0; num1<dice_to_roll; num1++){
			roll_results[num1] = lrand(s) % 6 + 1;
		}
		//analyse results
		(void)memset(num_counts, '\0', 6);
		for(num1=0; num1<dice_to_roll; num1++){
			num_counts[ roll_results[num1] ]++;
		}
			//results only possible if 6 rolled
		//has_straight = 0;
		//has_three_pairs = 0;
		//has_six_of_kind = 0;

		if(dice_to_roll == 6){
				//check for straight
			//has_straight = 0;
			for(num1=0; num1<6; num1++){
				if(!num_counts[num1])
					break;
				if(num1 == 5)
					comb.has_straight = 1;
			}
				//check for three pairs
			//has_three_pairs = 0;
			num2 = 0;
			for(num1=0; num1<6; num1++){
				if(num_counts[num1] == 2)
					num2++;
			}
			if(num2 == 3)
				comb.has_three_pairs = 1;
				//check for 6 of a kind
			//has_six_of_kind = 0;
			for(num1=1; num1<6; num1++){
				if(roll_results[num1] != roll_results[0])
					break;
				if(num1 == 5)
					comb.has_six_of_kind = 1;
			}
		}
		//check for a single 5
		//has_single_five = 0;
		for(num1=0; num1<dice_to_roll; num1++){
			if(roll_results[num1] == 5){
				comb.has_single_five = 1;
				break;
			}
		}
		//check for a single 1
		//has_single_one = 0;
		for(num1=0; num1<dice_to_roll; num1++){
			if(roll_results[num1]){
				comb.has_single_one = 1;
				break;
			}
		}
		//check for 5 of a kind
		//has_five_of_kind = 0;
		if(dice_to_roll > 4){
			for(num1=0; num1<dice_to_roll; num1++){
				if(num_counts[num1] == 5){
					comb.has_five_of_kind = 1;
					break;
				}
			}
		}
		//check for 4 of a kind
		//has_four_of_kind = 0;
		if(dice_to_roll > 3){
			for(num1=0; num1<dice_to_roll; num1++){
				if(num_counts[num1] == 4){
					comb.has_four_of_kind = 1;
					break;
				}
			}
		}
		//check for two 5's or 1's
		//has_two_five = 0;
		//has_two_one = 0;
		if(dice_to_roll > 1){
			if(num_counts[4] == 2)
				comb.has_two_five = 1;
			if(num_counts[0] == 2)
				comb.has_two_one = 1;
		}
		//don't have anything: "zilch"
		zilch = 1;
		num2 = sizeof(struct Comb);
		c_ptr = (char *)&comb;
		for(num1=0; num1<num2; num1++){
			if(*(char *)(c_ptr+num1) != '\0'){
				zilch = 0;
				break;
			}
		}
		//
		if(zilch)
			return 0;
		//find the highest possible score without breaking MIN_WILL_ROLL or MIN_STAY_AT
		//ignore MIN_WILL_ROLL and MIN_STAY_AT if not onboard
		while(1){
			if(comb.has_six_of_kind){
				turn_over = 0;
				score += s_six_of_kind[roll_results[0]-1];
				break;
			}
			if(comb.has_straight){
				turn_over = 0;
				score += 1500;
				break;
			}
			if(comb.has_three_pairs){
				turn_over = 0;
				score += 1000;
				break;
			}
			score_tmp = 0;
			//check combinations of conditions against rules
			if(comb.has_five_of_kind){
				if(dice_to_roll == 6){
					//check for sweep
					

					//if the 1 dice not part of series is not 1 or 5 then bust
					for(num1=0; num1<6; num1++){
						if(roll_results[num1]){
							if(num1){
								
							}
							if(num1 == 5){
								
							}
						}
					}
				}else{

				}
			}
		}

		/*
		if(has_single_five || has_single_one || has_three_of_kind || has_four_of_kind || has_five_of_kind
			|| has_six_of_kind || has_three_pairs || has_straight)
			zilch = 0;
		if(zilch)
			return 0;
		//highest result
		dice_left_over = 0;
		while(1){
			if(has_six_of_kind){
				if(roll_results[0]){
					score+=8000;
					break;
				}
				if(roll_results[0] == 5){

				}
				if(roll_results[0] == 5){
					score+=4000;
					break;
				}
			}
			if(has_five_of_kind){

			}
			if(has_four_of_kind){

			}
			if(has_straight){
			1500
			}
			if(has_three_pairs){

			}
			if(has_three_of_kind){

			}
			if(has_two_one){

			}
			if(has_two_five){

			}
			if(has_single_one){

			}
			if(has_single_five){

			}
			zilch = 1;
			break;
		}
		*/

		//a sweep

		//bank the score and pass?

		turn_over = 1;

	}

	return score;
}

int main(int argc, char **argv){
	uint32_t score = 0;
	uint32_t score_tmp = 0;
	uint32_t turn = 0;
	struct timeval cur;
	gettimeofday(&cur, NULL);
	uint64_t rseed = (uint64_t)cur.tv_usec + 3 + t;
	//get on the board
	while(score_tmp < MIN_GET_ONBOARD){
		score_tmp = Roll_Dice(&rseed, 0);
		turn++;
	}
	score += score_tmp;
	//play to 10,000
	while(score < 10000){
		score += Roll_Dice(&rseed, 1);
		turn++;
	}
	return 0;
}