compare arrays for scoring

To help you understand what I am trying to explain I will tell you the rules for Yahtzee scoring. You have two scoring categories 'lows' and 'highs'. The user rolls 5 dice up to 3 times or until they are satisfied with the results, in other words they can stop rolling at anytime but may re-roll a picked amount of dice. They can only roll a total of three times overall. Lets say you rolled 6-6-3-4-6 and you wanted to re-roll the 3 and 4 to try to make it 5 6's to get a higher score then you could re-roll 2 more times to get that score. The scoring system works like this:
Lows
ones:
twos:
threes:
fours:
fives:
sixes:
total:
bonus:

Highs:
three of a kind:3 die faces are the same (2,2,2,3,4)
four of a kind: 4 die faces are the same (1,1,1,1,5)
small straight: 4 sequential dice (1,2,3,4)
large straight: 5 sequential dice(1,2,3,4,5)
full house: 3 of a kind and a pair (6,6,5,5,5)
Yahtzee: 5 dice all of same value for 50 points. (5,5,5,5,5)
total = lowstotal + highstotal + bonus;

What I am trying to do is write a function that controls where the player can apply the points. I could do this using endless amounts of else if statements but that doesn't seem efficient to me and is most likely what the rest of the class will do as they like to follow in the book and never think outside of the box. I have this program working up to the storing all the values of each die after max number of re-rolls or they decide to keep it. I want to take those 5 values and compare them to a scoring category to output to the user only the available categories to use. This will eliminate tons of error handling and potential bugs. I also have to make sure that it does not display a category with a score value already stored in it. I've got kind of a pseudocode for it, but would appreciate any thoughts on how you might do something similar to this or if you could point me in the right direction.

Thanks,


1
2
3
4
5
6
7
8
9
10
11
12
13


for(int i = 0; i < 4; i++){
//check for keptdie[5] values against a bool?
if (keptdie[i] == category[i]) 
category[i] = options[i];
}  

/*I think this would work for scoring the lows but it wouldn't work for any of
the Highs as it would need to compare every value in the keptdie[] to see if it
 contains 3 of a kind or 3 of kind and a pair. I am not sure on what step to
 take next and if maybe there is a better way of doing this or a built function
 i could use that already does something similar to this.*/
Last edited on
What I am trying to do is write a function that controls where the player can apply the points.
By this do you mean that the user will tell the program I got a 3 of a kind so add this many points? Or are you trying to say that you want to determine if they got a three of a kind or w/e score?

Assuming the second case as it is a bit more interesting. To me a possible way is to make a histogram. For example, the user rolls 3 3 3 5 6. Then make an array that count how many times a particular number rolled like for example in this case the array would be 0 0 3 0 1 1 where 3 would be the 3 three's counted and the 1's are the 5 and 6.

Or if we out putted it it would be:

1
2 
3 ***
4
5 *
6 *


Then this can significantly reduce the if statements in fact you would only have to write 5 and the seperate loops/single loop of coarse.

1. check for a four of kind (see if a index in the histogram contains four)
2. check for three of a kind (See if a index in the histogram contains 3)
2.5 check if there is also index containing 2 ie full house
3. check for a short straight one index will be 2
4. if the index never gets bigger then 1 then it is a full straight.


That is one of many ways to do it. Not sure if that is the way your thinking of it.


Last edited on
The player can apply the points where ever they want to apply them as long as they follow the rules for each scoring group. For instance you could roll (3,3,3,4,4) This could count as a full house, threes, fours and three of a kind.
Thus the player can choose where they want to apply the points, in most cases the player would probably choose what ever will give them the highest score.

So, what I am trying to do is write a function that handles the values of each die the player has which is stored in an array called keptdie[5] compares the values in the array to the rules of each category to see where the player is allowed to put the points (based on the rules) then display a menu showing only the categories that were determined legal.


Where would you like to apply the points?
1. full house : 40 points
2. three of a kind : sum of all dice
3. threes : sum of only dies showing 3
4. fours : sum of only fours showing


The output to player would look like this. Say they already have applied points to a fullhouse this option would no longer be displayed because it holds a value now. So only choices would be three of a kind , threes and fours.


I never thought about using a histogram, this is definitely something i will use to help me figure it out. I think I can get it done using your method. If you have any other thoughts based off of my new explanation of what I am trying to accomplish please let me know.

edit:
Ok here is something I've come up with that may work. It is a histogram algorithm I suppose.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "stdafx.h"
#include <iostream>

using namespace std;

void score();

int main()
{

	score();

	system("PAUSE");
	return 0;
}

void score()
{
	int const x = 6;
        int const y = 5;
	int inteliscore[x] = { 0, 0, 0, 0, 0, 0 }; 
	int keptdie[y] = { 2, 2, 3, 2, 3 };//for testing set the array

	for (int i = 0; i != y; i++)
	{
		for (int j = 1; j != 7; j++)
		{
			if (keptdie[i] == j)
			{
				int temp = 1;

				if (inteliscore[j - 1] != 0)//if index position is not zero 
				{
					inteliscore[j - 1] = inteliscore[j - 1] + 1; //then add 1 onto stored value in index position.
					cout << inteliscore[j - 1] << endl;
				}
				else
				{
					inteliscore[j - 1] = temp;
					cout << inteliscore[j - 1] << endl;
				}
			}
		}
	}

	for (int i = 0; i != x; i++)
	cout << inteliscore[i];
}
}


What do you think of that?
Last edited on
The if and else statement isn't needed and the int temp.

In terms of converting the dice values to a histogram consider the following

1
2
3
4
5
6
7
8
9
10
11
12
 
void makeHistogram () {

int inteliscore[6] = { 0, 0, 0, 0, 0,0}; 
int keptdie[5] = { 2, 2, 3, 2, 3 }; 
 
    for (int c = 0; c < 5; c++) // in particular pay attention to this loop
    {
        inteliscore [keptdie[c] - 1] = inteliscore [keptdie[c] - 1] + 1;
    }

}


This probably the better way to do so. As whatever value of keptdie[c] - 1 will equal to the correct index position that needs to be added by 1.

From here one you can do a tests for which legal scores can be returned to the user. Unfortunately, this just comes down to trying to figure out the best way to test for all permutations in the smallest amount of steps.
Holy crap you are a genius!!!! So much smaller and more efficient then what i wrote and it does the same damn thing! Just goes to show you how much of a newbie I am when it comes to logic of an algorithm. Thank you for your help I will post my code once I have the scoring situation figured out to see if you notice anything in the code that I could do more efficiently. Learning these tricks and making my brain think like a programmer will only benefit me at my future job more.

Thank you a million times.
Topic archived. No new replies allowed.