As a proud memeber of the 10% unemployed and the 45% under-employed, I often find that I have a lot of time on me' hands. Now my dear ol' mom likes to play this game, and she's often at home alone.. so with nothing else to offer this holliday season, I'm trying to code up this little game as an x-mas present.

This game features my mamaw as a live player, and my brother and I as AI players. Currently, the game will go through all the automation.. but will make really really bad decisions on what die to keep.

I am just starting the debugging process. If ya'll want to compile and give me your thoughts, I'd appreciate it. I'm open to suggestions and what not.

(click on "toggle plain text", then copy/paste into ye' compiler)

#include <iostream>
#include <windows.h>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cctype>
#include <string>
#include <ctime>


using namespace std;

class Yaht
{
    public:

    Yaht();
    void display_card();
    void display_dice();
    void display_menu();
    void menu();
    void display_stats();
    char get_choice(){return choice;}
    void die_keep();
    void die_unkeep();
    void clear_keep();
    void line_entry();
    void set_card();
    void set_turn_chip();
    int  set_uppers(int);
    int  get_ofkind(int);
    int  get_fullhouse();
    int  get_sm_straight();
    int  get_lg_straight();
    int  get_yahtzee();
    void set_ybonus();
    int  get_chance();
    void turn_manager();
    void roll_the_dice();
    void gotoxy(int x, int y);

    //Artificial Intelligence
    void auto_player();
    void dice_analyze();
    void ai_test_yahtzee();
    void ai_test_lg_straight();
    void ai_test_sm_straight();
    void ai_test_fullhouse();
    void ai_test_4kind();
    void ai_test_3kind();
    int  ai_get_uppers(int);
    void ai_try_yahtzee();
    void ai_try_lg_straight();
    void ai_try_sm_straight();
    void ai_try_fullhouse();
    void ai_try_4kind();
    void ai_try_3kind();
    void ai_try_uppers();
    void ai_set_card();
    void ai_make_decision();

    private:

    int roll;
    int turn;
    int player;
    int subtotal;
    int upper_total[3];
    int lower_total[3];
    int games_won[3];
    int line;
    int x;
    int y;
    int dice_value[5];
    int ybonus_counter[3];
    char dice[6][5][9];
    COORD ybonus_coord[3][3];
    COORD chip_coord[3];
    COORD card_coord[3][21];
    COORD keep_coord[5];
    bool is_keep[5];
    char choice;

    //AI Vars
    int  is_needed_upper[2][6];
    bool is_needed_lower[2][6];
    bool chance[2];
    int  low_weight[6];
    enum{one, two, three, four, five, six};
    enum{yahtzee, lgstraight, smstraight, fullhouse, kind4, kind3};

};

int main()
{
    Yaht zee;

    zee.display_card();
    zee.display_stats();
    zee.display_dice();

    do
    {
        zee.turn_manager();

    }while(zee.get_choice() != 'Q');

    return 0;
}

Yaht::Yaht()
{
    roll = 0;
    turn = 0;
    player = 0;
    subtotal = 0;
    line = 0;

    srand((unsigned)time(NULL));

    //Build Card Coordinates
    x = 29;
    y = 8;
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<21; j++)
        {
            card_coord[i][j].X = x;
            card_coord[i][j].Y = y;

            if(j == 7 || j == 16)
            {
              y++;
            }
            else if(j == 8)
            {
                y += 2;
            }

            y += 2;
        }

        x += 8;
        y = 8;
    }

    //Initialize totals
    for(int i=0; i<3; i++)
    {
        lower_total[i] = 0;
        upper_total[i] = 0;
        games_won[i] = 0;
        ybonus_counter[i] = 0;
    }

    //Initialize needs
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<6; j++)
        {
                is_needed_upper[i][j] = true;
                is_needed_lower[i][j] = true;
        }
    }

    //Initialize dice_values and is_keep
    for(int i=0; i<5; i++)
    {
        dice_value[i]= 0;
        is_keep[i] = false;
    }

    //Turn chip indicator coordinates
    {
        chip_coord[0].X = 27;
        chip_coord[0].Y = 6;
        chip_coord[1].X = 34;
        chip_coord[1].Y = 6;
        chip_coord[2].X = 43;
        chip_coord[2].Y = 6;
    }

    //Build "KEEP" display coordinates
    for(int i=0, y=4; i<5; i++, y+=11)
    {
       keep_coord[i].X = 71;
       keep_coord[i].Y = y;
    }

    //Yahtzee bonus coords 'X' checkmark
    x = 27;
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
        {
            ybonus_coord[i][j].X = x;
            ybonus_coord[i][j].Y = 43;
            x += 2;
        }

        x += 2;
    }

    //Yahtzee Bonus Counter Initialize
    for(int i=0; i<3; i++)
    {
            ybonus_counter[i] = 0;
    }

    //initialize all dice elements to white space
    for(int i=0; i<6; i++)
    {
        for(int j=0; j<5; j++)
        {
            for(int k=0; k<9; k++)
            {
               dice[i][j][k] = ' ';
            }
        }

    }

    //One
    dice[one][2][4] = 'O';

    //Two
    dice[two][0][1] = 'O';
    dice[two][4][7] = 'O';

    //Three
    dice[three][0][1] = 'O';
    dice[three][2][4] = 'O';
    dice[three][4][7] = 'O';

    //Four
    dice[four][0][1] = 'O';
    dice[four][0][7] = 'O';
    dice[four][4][1] = 'O';
    dice[four][4][7] = 'O';

    //Five
    dice[five][0][1] = 'O';
    dice[five][0][7] = 'O';
    dice[five][2][4] = 'O';
    dice[five][4][1] = 'O';
    dice[five][4][7] = 'O';

    //Six
    dice[six][0][1] = 'O';
    dice[six][0][7] = 'O';
    dice[six][2][1] = 'O';
    dice[six][2][7] = 'O';
    dice[six][4][1] = 'O';
    dice[six][4][7] = 'O';
}




void Yaht::display_card()
{

    cout << "\n  -------------------------------------------------"
         << "\n  |                                               |"
         << "\n  |                ASCII YAHTZEE !!!              |"
         << "\n  |                                               |"
         << "\n  |-----------------------------------------------|"
         << "\n  | Line |         Name: |   Mom |  Dave |   Bru  |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   1  |          Ones |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   2  |          Twos |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   3  |        Threes |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   4  |         Fours |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   5  |         Fives |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   6  |         Sixes |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |      Subtotal |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |   Bonus 35pts |       |       |        |"
         << "\n  |      |  (63 or over) |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |   Upper Total |       |       |        |"
         << "\n  ------------------------------------------------- "
         << "\n\n  -------------------------------------------------"
         << "\n  |   7  |   3 of a kind |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   8  |   4 of a kind |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |   9  |    Full House |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |  10  |  Sm. Straight |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |  11  |  Lg. Straight |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |  12  |       Yahtzee |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |  13  |        Chance |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      | Yahtzee Bonus |       |       |        |"
         << "\n  |      |  100pts each  |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |   Total Lower |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |   Total Upper |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |   Grand Total |       |       |        |"
         << "\n  |-----------------------------------------------|"
         << "\n  |      |   # Games Won |       |       |        |"
         << "\n  -------------------------------------------------- ";
}

void Yaht::display_dice()
{
    int x = 60,
        y = 1,
        die = 1;

    for(int i=0; i<5; i++)
    {
        gotoxy(x,y++);  cout << "   ---------";
        gotoxy(x,y++);  cout << " /    " << die++ << "    /|";
        gotoxy(x,y++);  cout << " ---------  |";
        gotoxy(x,y++);  cout << "|         | |";
        gotoxy(x,y++);  cout << "|         | |";
        gotoxy(x,y++);  cout << "|         | |";
        gotoxy(x,y++);  cout << "|         | |";
        gotoxy(x,y++);  cout << "|         |/";
        gotoxy(x,y++); cout << " ---------";

        y += 2;
    }
}

void Yaht::display_menu()
{
    int x = 85,
        y = 4;

    gotoxy(x,y++);  cout << "--------------------";
    gotoxy(x,y++);  cout << "|       MENU       |";
    gotoxy(x,y++);  cout << "--------------------";
    gotoxy(x,y++);  cout << "| (R) Roll         |";
    gotoxy(x,y++);  cout << "| (K) Keep         |";
    gotoxy(x,y++);  cout << "| (U) Unkeep       |";
    gotoxy(x,y++);  cout << "| (A) Keep All     |";
    gotoxy(x,y++);  cout << "| (Q) Exit Game    |";
    gotoxy(x,y++);  cout << "--------------------";
    gotoxy(x,y++);  cout << "|     Roll #" << roll << "      |";
    gotoxy(x,y++);  cout << "--------------------";
}

void Yaht::menu()
{
    int x = 85,
        y = 16;

    gotoxy(x,y); cout << "                                      ";
    gotoxy(x,y); cout << "Enter ye' choice: ";
    cin >> choice;

    switch(toupper(choice))
    {
        case 'R':  roll_the_dice();
                   break;

        case 'K':  die_keep();
                   break;

        case 'U':  die_unkeep();
                   break;

        case 'A':  roll = 3;
                   turn_manager();
                   break;

        case 'Q':  choice = 'Q';
                   break;

        default:   gotoxy(x,y); cout << choice << "\a is not a menu choice! ";
                   cin.ignore();
                   cin.get();
                   menu();
                   break;
    }
}

void Yaht::turn_manager()
{

    //Player Adjust
    if(player > 2)
    {
        player = 0;
    }

    set_turn_chip();

    //Auto Roll
    if(!roll)
    {
        roll_the_dice();
    }


    //Handle Live Player
    if(player == 0 && roll < 3)
    {
        display_menu();
        menu();
    }

    if(player == 0 && roll == 3)
    {
        display_menu();
        line_entry();
        roll = 0;
        clear_keep();
        player++;
    }

    //Handle AI
    if(player != 0)
    {
        auto_player();
    }
}

void Yaht::display_stats()
{
    //Display Subtotals

    if(upper_total[player] < 63)
    {
        gotoxy(card_coord[player][6].X,  card_coord[player][6].Y );  cout << upper_total[player];
        gotoxy(card_coord[player][8].X,  card_coord[player][8].Y );  cout << upper_total[player];
        gotoxy(card_coord[player][18].X, card_coord[player][18].Y);  cout << upper_total[player];
        gotoxy(card_coord[player][19].X, card_coord[player][19].Y);  cout << upper_total[player]+lower_total[player];
    }
    else
    {
        gotoxy(card_coord[player][6].X,  card_coord[player][6].Y );  cout <<  upper_total[player];
        gotoxy(card_coord[player][7].X,  card_coord[player][7].Y );  cout << "35";
        gotoxy(card_coord[player][8].X,  card_coord[player][8].Y );  cout << upper_total[player]+35;
        gotoxy(card_coord[player][18].X, card_coord[player][18].Y);  cout << upper_total[player]+35;
        gotoxy(card_coord[player][19].X, card_coord[player][19].Y);  cout << upper_total[player]+lower_total[player]+35;
    }

        gotoxy(card_coord[player][17].X, card_coord[player][17].Y);  cout << lower_total[player];
        gotoxy(card_coord[player][20].X, card_coord[player][20].Y);  cout << games_won[player];
}

void Yaht::roll_the_dice()
{
    int x = 61,
        y = 4;

    roll++;
    display_menu();

    for(int c=0; c<rand()%10+10; c++)
    {
        for(int i=0; i<5; i++)
        {
            if(!is_keep[i])
            {
                dice_value[i] = rand()%6;
            }
        }

        for(int i=0; i<5; i++)
        {
            gotoxy(x,y);

            for(int j=0; j<5; j++)
            {
                gotoxy(x, y++);

                for(int k=0; k<9; k++)
                {
                    cout << dice[dice_value[i]][j][k];
                }
            }

            y += 6;
        }

        Sleep(100);
        y = 4;
    }
}

void Yaht::die_keep()
{
    string keep("KEEP");
    int x = 85,
        y = 16;

if(roll && !player)
{
    gotoxy(x,y); cout << "Enter # die to keep: ";
                 cin >> choice;
}

    is_keep[choice-'1'] = true;

    for(int i=0; i<5; i++)
    {
        if(is_keep[i])
        {
            for(int j=0; j<4; j++)
            {
                gotoxy(keep_coord[i].X, keep_coord[i].Y+j); cout << keep[j];
            }

        }
    }
}

void Yaht::die_unkeep()
{
    int x = 85,
        y = 16;

    if(roll && !player)
    {
        gotoxy(x,y); cout << "Enter # die to unkeep: ";
        cin >> choice;
    }

    is_keep[choice-'1'] = false;

    for(int i=0; i<5; i++)
    {
        if(!is_keep[i])
        {
            for(int j=0; j<4; j++)
            {
                gotoxy(keep_coord[i].X, keep_coord[i].Y+j); cout << ' ';
            }

        }
    }
}

void Yaht::clear_keep()
{
    for(int i=0; i<5; i++)
    {
        choice = '1'+i;
        die_unkeep();
    }
}

void Yaht::line_entry()
{
    int x = 85,
        y = 16;

    gotoxy(x,y); cout << "Enter line # to score (1-13): ";
    cin >> line;
    gotoxy(x,y); cout << "                                 ";
    set_card();
}

void Yaht::set_card()
{
    if(line <= 6)
    {
        gotoxy(card_coord[player][line-1].X, card_coord[player][line-1].Y);  cout << set_uppers(line);
    }
    else if(line == 7 || line == 8)
    {
        gotoxy(card_coord[player][line+2].X, card_coord[player][line+2].Y);  cout << get_ofkind(line-4);
    }
    else if(line == 9)
    {
        gotoxy(card_coord[player][line+2].X, card_coord[player][line+2].Y);  cout << get_fullhouse();
    }
    else if(line == 10)
    {
        gotoxy(card_coord[player][line+2].X, card_coord[player][line+2].Y);  cout << get_sm_straight();
    }
    else if(line == 11)
    {
        gotoxy(card_coord[player][line+2].X, card_coord[player][line+2].Y);  cout << get_lg_straight();
    }
    else if(line == 12)
    {
        gotoxy(card_coord[player][line+2].X, card_coord[player][line+2].Y);  cout << get_yahtzee();
        set_ybonus();
    }
    else if(line == 13)
    {
        gotoxy(card_coord[player][line+2].X, card_coord[player][line+2].Y);  cout << get_chance();
    }

    display_stats();
}

void Yaht::set_turn_chip()
{
    char check = 251;

     for(int i=0; i<3; i++)
    {
        gotoxy(chip_coord[i].X, chip_coord[i].Y );  cout << ' ';
    }

     gotoxy(chip_coord[player].X, chip_coord[player].Y );  cout << check;

}

int Yaht::set_uppers(int value)
{
    int sub = 0;

    sub = count(dice_value, dice_value+5, value-1) * value;

    upper_total[player] += sub;

    return sub;
}


int Yaht::get_ofkind(int value)
{
    int counter = 0;
    int sub = 0;

    for(int i=0; i<5; i++)
    {
        counter = count(dice_value, dice_value+5, i);

        if(counter >= value)
        {
            for(int i=0; i<5; i++)
            {
                sub += dice_value[i]+1;
            }

            lower_total[player] += sub;
            return sub;
        }
    }

    return 0;
}

int Yaht::get_fullhouse()
{
    int sub2 = 0,
        sub3 = 0,
        temp = 0;

    for(int i=0; i<6; i++)
    {
        temp = count(dice_value, dice_value+5, i);

        if(temp == 2)
        {
            sub2 = temp++;
        }
        else if(temp == 3)
        {
            sub3 = temp++;
        }
    }

    if(!sub2 || !sub3)
    {
        return 0;
    }
    else
    {
        lower_total[player] += 25;
        return 25;
    }
}

int Yaht::get_sm_straight()
{
    int index = 0;
    bool is_straight = false;

    sort(dice_value, dice_value+5);

    //check low-side
    do
    {
        is_straight = false;
        if(dice_value[index]+1 == dice_value[index+1])
        {
            is_straight = true;
        }

        index++;

    }while(index < 3 && is_straight);

    if(is_straight)
    {
        lower_total[player] += 30;
        return 30;
    }
    //Check high side
    else
    {
        index = 1;
        is_straight = false;
        do
        {
            is_straight = false;
            if(dice_value[index]+1 == dice_value[index+1])
            {
                is_straight = true;
            }

            index++;

        }while(index < 4 && is_straight);

        if(is_straight)
        {
            lower_total[player] += 30;
            return 30;
        }
        else
        {
            return 0;
        }
    }
}

int Yaht::get_lg_straight()
{
    int index = 0;
    bool is_straight = true;

    sort(dice_value, dice_value+5);

    do
    {
        is_straight = false;
        if(dice_value[index]+1 == dice_value[index+1])
        {
            is_straight = true;
        }

        index++;

    }while(index < 4 && is_straight);

    if(is_straight)
    {
        lower_total[player] += 40;
        return 40;
    }
    else
    {
        return 0;
    }
}

int Yaht::get_yahtzee()
{
    int index = 0;
    bool is_yahtzee = false;

    do
    {
        is_yahtzee = false;

        if(dice_value[index] == dice_value[index+1])
        {
            is_yahtzee = true;
        }

        index++;

    }while(index < 4 && is_yahtzee);

    if(is_yahtzee)
    {
        ybonus_counter[player]++;
        lower_total[player] += 50;
        return 50;
    }
    else
    {
        return 0;
    }
}

void Yaht::set_ybonus()
{
    int counter = ybonus_counter[player];

    if(counter)
    {
        gotoxy(ybonus_coord[player][counter].X, ybonus_coord[player][counter].Y);  cout << 'X';
        lower_total[player] += 100;
    }
}

int Yaht::get_chance()
{

    int temp = 0;

    for(int i=0; i<5; i++)
    {
        temp += dice_value[i]+1;
    }

     lower_total[player] += temp;
     return temp;
}


void Yaht::gotoxy(int x, int y)
{
  COORD coord;
  coord.X = x;
  coord.Y = y;
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}



//Aritifical Intelligence Function Definitions
void Yaht::auto_player()
{
    set_turn_chip();
    dice_analyze();
    ai_make_decision();

    if(roll<3)
    {
        auto_player();
    }
    else
    {
        roll = 0;
        player++;
        clear_keep();
        turn_manager();
    }
}

void Yaht::dice_analyze()
{
    ai_test_yahtzee();
    ai_test_lg_straight();
    ai_test_sm_straight();
    ai_test_fullhouse();
    ai_test_4kind();
    ai_test_3kind();
    //ai_get_uppers();
}

void Yaht::ai_test_yahtzee()
{
    int temp = 0,
        sub = 0;

    for(int i=0; i<5; i++)
    {
        temp = count(dice_value, dice_value+5, i);

        if(temp > sub)
        {
            sub = temp;
        }
    }

    low_weight[yahtzee] = 5-sub;
}

void Yaht::ai_test_lg_straight()
{
    int sub = 0;

    sort(dice_value, dice_value+5);

    for(int i=0; i<4; i++)
    {
        if(dice_value[i]+1 != dice_value[i+1])
        {
            sub++;
        }
    }

    low_weight[lgstraight] = sub;
}

void Yaht::ai_test_sm_straight()
{
    int sub1 = 0,
        sub2 = 0;

    sort(dice_value, dice_value+5);

    //check low side
    for(int i=0; i<3; i++)
    {
        if(dice_value[i]+1 != dice_value[i+1])
        {
            sub1++;
        }
    }

    //check high side
      for(int i=1; i<4; i++)
    {
        if(dice_value[i]+1 != dice_value[i+1])
        {
            sub2++;
        }
    }

    if(sub1 < sub2)
    {
        low_weight[smstraight] = sub1;
    }
    else
    {
        low_weight[smstraight] = sub2;
    }
}

void Yaht::ai_test_fullhouse()
{
    int temp = 0,
        sub3 = 0,
        sub2 = 0;

    for(int i=0; i<5; i++)
    {
        temp = count(dice_value, dice_value+5, i);

        if(sub3 < temp)
        {
            sub3 = temp;
        }
    }

    for(int i=0; i<5; i++)
    {
        temp = count(dice_value, dice_value+5, i);

        if(sub2 < temp && temp != sub3)
        {
            sub2 = temp;
        }
    }

    if(sub3 > 3)
    {
        sub3 = 3;
    }

    low_weight[fullhouse] = (3-sub3) + (2-sub2);
}

void Yaht::ai_test_4kind()
{
    int temp = 0,
        sub = 0;

    for(int i=0; i<5; i++)
    {
        temp = count(dice_value, dice_value+5, i);

        if(sub < temp)
        {
            sub = temp;
        }
    }

    if(sub > 4)
    {
        sub = 4;
    }

    low_weight[kind4] = 4-sub;
}

void Yaht::ai_test_3kind()
{
    int temp = 0,
        sub = 0;

    for(int i=0; i<5; i++)
    {
        temp = count(dice_value, dice_value+5, i);

        if(sub < temp)
        {
            sub = temp;
        }
    }

    if(sub > 3)
    {
        sub = 3;
    }

    low_weight[kind3] = 3-sub;
}

 int Yaht::ai_get_uppers(int value)
{
    int sub = 0;

    sub = count(dice_value, dice_value+5, value-1) * value;

    return sub;
}

void Yaht::ai_make_decision()
{

    int  temp = 0,
         best_lower = 0;
    bool need_lower = false,
         need_upper = false;

    clear_keep();

    //See what we need
    for(int i=0; i<6; i++)
    {
        if(is_needed_lower[player-1][i])
        {
            need_lower = true;
        }
        if(is_needed_upper[player-1][i])
        {
            need_upper = true;
        }
        if(need_lower && need_upper)
        {
            break;
        }
    }

    //Identify Best Lower
    if(need_lower)
    {
        for(int i=0; i<6; i++)
        {
            for(int j=5; j<-1; j++)
            {
                if(low_weight[i] > low_weight[i+1])
                {
                    best_lower = i+1;
                }
            }
        }

        //If we got somethin', take it
        if(low_weight[best_lower] == 0)
        {
            switch(best_lower)
            {
                case 0: line = 12;
                        if(ybonus_counter[player] > 3)
                        {
                            is_needed_lower[player][yahtzee]=false;
                        }
                        break;
                case 1: line = 11;
                        is_needed_lower[player-1][lgstraight]=false;
                        break;
                case 2: line = 10;
                        is_needed_lower[player-1][smstraight]=false;
                        break;
                case 3: line = 9;
                        is_needed_lower[player-1][fullhouse]=false;
                        break;
                case 4: line = 8;
                        is_needed_lower[player-1][kind4]=false;
                        break;
                case 5: line = 7;
                        is_needed_lower[player-1][kind3]=false;
                        break;
            }

            set_card();
            //player++;
        }
    }

    //If not, try for somethin'
    if(roll<3)
    {
        //Unkeep everything
        switch(best_lower)
        {
            case 0: ai_try_yahtzee();
                    break;
            case 1: ai_try_lg_straight();
                    break;
            case 2: ai_try_sm_straight();
                    break;
            case 3: ai_try_fullhouse();
                    break;
            case 4: ai_try_4kind();
                    break;
            case 5: ai_try_3kind();
                    break;
        }

        roll_the_dice();
        Sleep(2000);
    }

    //If no dice on the lower card, handle uppper card
    if(need_upper && roll == 3)
    {
        int score = 0;

        for(int i=0; i<5; i++)
        {
            if(score < ai_get_uppers(i+1) && is_needed_upper[player][i])
            {
                score = ai_get_uppers(i+1);
                line = i+1;
            }
        }

        is_needed_upper[player][line] = false;
        set_uppers(line);
        set_card();
    }

    /*
    //Damage Control
    else if(!need_lower && !need_upper)
    {
       //if available, take chance
        if(!need_lower && !need_upper && chance[player])
        {
            line = 13;
            chance[player] = false;
            get_chance();
            set_card();
        }
        //otherwise take the lowest zero hit
        else
        {
            ai_get_uppers();

            for(int i=0; i<6; i++)
            {
                if(!upper_scores[player][i])
                {
                    line = i;
                    set_card();
                    break;
                }
            }
        }
    }*/

    //clear_keep();
}

void Yaht::ai_try_yahtzee()
{
    int freqs[5] = {0,0,0,0,0};
    int highest = 0;
    int pos = 0;

    //Get die with highest frequency
    for(int i=0; i<5; i++)
    {
        freqs[i] = count(dice_value, dice_value+5, i);

        if(freqs[i] > highest)
        {
            highest = freqs[i];
            pos = i;
        }
    }

    //Keep 'yahtzee' die
    for(int i=0; i<5; i++)
    {
        if(dice_value[i] == pos+1)
        {
            choice = '1'+i;
            die_keep();
        }
    }
}

void Yaht::ai_try_lg_straight()
{
    vector<int> keeps(dice_value, dice_value+5);

    sort(keeps.begin(), keeps.end());

    unique(keeps.begin(), keeps.end());

    for(int i=0, size=keeps.size(); i<size; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(dice_value[j] == keeps[i])
            {
                choice = '1'+j;
                die_keep();
                break;
            }

        }
    }
}

void Yaht::ai_try_sm_straight()
{
    vector<int> keeps(dice_value, dice_value+5);

    sort(keeps.begin(), keeps.end());

    unique(keeps.begin(), keeps.end());

    //Handle the 'ends' of a small straight...
    if(keeps[0] == 1 && keeps[4] == 6)
    {
        //Decide to keep either the 1 or the 6
        if(keeps[1] == 2)
        {
            keeps[5] = 0;
        }
        else if(keeps[3] == 5)
        {

            keeps[0] = 0;
        }

    }

    for(int i=0, size=keeps.size(); i<size; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(dice_value[j] == keeps[i])
            {
                choice = '1'+j;
                die_keep();
                break;
            }

        }
    }
}

void Yaht::ai_try_fullhouse()
{
    int freqs[5] = {0,0,0,0,0};
    int highest = 0;
    int pos1 = 0;
    int pos2 = 0;
    int keep1 = 0;
    int keep2 = 0;

    //Get die with highest frequency
    for(int i=0; i<5; i++)
    {
        freqs[i] = count(dice_value, dice_value+5, i);

        if(freqs[i] > highest)
        {
            highest = freqs[i];
            pos1 = i;
        }
    }

    keep1 = dice_value[pos1];

    //Get die with second most frequency
    for(int i=0; i<5; i++)
    {
        freqs[i] = count(dice_value, dice_value+5, i);

        if(freqs[i] > highest)
        {
            highest = freqs[i];

            if(i != pos1)
            {
               pos2 = i;
            }

        }
    }

    keep2 = dice_value[pos2];

    //Keep them' die
    for(int i=0; i<5; i++)
    {
        if(dice_value[i] == keep1 || dice_value[i] == keep2)
        {
            choice = '1'+i;
            die_keep();
        }
    }
}

void Yaht::ai_try_4kind()
{
  ai_try_yahtzee();
}

void Yaht::ai_try_3kind()
{
    ai_try_yahtzee();
}

Recommended Answers

All 10 Replies

Hi, I just tried your program.

It runs quite well for a time but it crashed on me (twice) while it was throwing the die.

Also, the "enter ye' choice" is presented at another place obscuring the scoreboard - but not always. Another small point; the "Keep All" label is scrolled round to the LHS also obscuring part of scoreboard.

I hope this helps
David

commented: Thanks.. I'll look into these issues +6

Thanks for your input; I'll add it on my somewhat extensive list of things to check out.

One thing I had to do is change the properties of my console window to like a width of 130 and a height of 300 (this might get rid of some of that wrap-around ye' are expeirencing.) Once I get this thing runnin' right I'll add code to automatically size the window on program startup.

It just crashed again - again on rolling the die and kept printing out lines 364 and 384 of the code. It is possible that I mucked up and pressed something unexpected - it is a little confusing with the (sometimes) misplaced placement of the question.

Hope that helps you narrow down your search.

Just from my one time playing it I thought that it was great. The only problem is that on the second time i got to the part where it asks me what to do, the score board was messed up, it was missing part of it

I'm am not sure about this issue; if you've resized your window to 130 width and 300 height... it should eliminate any wrap-around.

If you've already resized your console window... I am really not sure what would cause this. It works fine on my machine.

I'll go ahead and add some code to automatically size the window on start-up to eliminate this variable... which has been mentioned more than once.

Thank ye' for your input. Still stepping through 1,000+ lines of code in the ol' codeblocks debugger.

Here is a little band-aid that will set the console window size at program execution:

void Yaht::set_console_size()
{
     HANDLE hOut;
     SMALL_RECT DisplayArea = {0, 0, 0, 0};
     int x = 125;
     int y = 55;

     hOut = GetStdHandle(STD_OUTPUT_HANDLE);
     DisplayArea.Right  = x;
     DisplayArea.Bottom = y;

     SetConsoleWindowInfo(hOut, TRUE, &DisplayArea);
}

I would probaby make this function call somewhere inside the Yaht() constructor.. as it is 'constructing' the playing area.

Try this and let me know if ye' still have any display issues.

Something spotted .. what's up with line #1057

for(int j=5; j<-1; j++)

?

It was originally I spotted this in the debugger yesterday and what was happening it was evaluting 3 of a kind last.. which gave it preferrence as a deciding score. So as an easy fix I just did a reverse array traversal of low_weight[ ] to evalute 'yahtzee' last (which has an enumerated value of zero). This will give a tendency to chose higher qualifying scoring scores first.

>> It was originally I spotted this in the debugger yesterday and what was happening it was evaluting 3 of a kind last.. which gave it preferrence as a deciding score. So as an easy fix I just did a reverse array traversal of low_weight[ ] to evalute 'yahtzee' last (which has an enumerated value of zero). This will give a tendency to chose higher qualifying scoring scores first.

?? You can delete lines 1055 to 1064. They have no effect. Line 1061 can never execute due to the impossible loop condition mitrmkar pointed out

for(int i=0; i<6; i++)
        {
            for(int j=5; j<-1; j++)
            {
                if(low_weight[i] > low_weight[i+1])
                {
                    best_lower = i+1;
                }
            }
        }
commented: muy bueno +6

good catch.. i more or less got a < when i needed a >

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.