Skip to content

Commit

Permalink
Modified Yacht bug, L/S Straight order
Browse files Browse the repository at this point in the history
  • Loading branch information
ho94949 committed Feb 4, 2021
1 parent 875c062 commit 60c430e
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

eval.bin
op.bin
data.bin

# Main executable
main
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ AI of [Yacht Dice](https://en.wikipedia.org/wiki/Yacht_(dice_game)).

This AI maximizes expected value of yacht. This AI Do not consider opponent, thus not maximizing winning probability.

Expected score value of Yacht dice game with optimal play is 185.317430, way more than average person playing.
Expected score value of Yacht dice game with optimal play is 191.774369, way more than average person playing.

## Requirement

Expand All @@ -14,7 +14,7 @@ Expected score value of Yacht dice game with optimal play is 185.317430, way mor

## Rules

Yacht dice game has many variations, and this game uses following rule.
Yacht dice game has many variations, and this game uses following rules.

- One, Two, Three, Four, Five, Six
- For any combination, score is the sum of dice with chosen number.
Expand All @@ -23,26 +23,27 @@ Yacht dice game has many variations, and this game uses following rule.
- If combination includes four dice showing the same face, score is the sum of all dice.
- Full House
- If combination is given ans two of one number and three of another, score is the sum of all dice.
- L. Straight
- If combination is 5 consecutive numbers, score is 30.
- S. Straight
- If combination has 4 consecutive numbers, score is 15.
- L. Straight
- If combination is 5 consecutive numbers, score is 30.
- Yacht
- If all five dices are showing same face, score is 50.

You can modify these rules in [rule.hh](https://github.com/ho94949/yacht-dice/blob/main/src/rule.hh) and [rule.cc](https://github.com/ho94949/yacht-dice/blob/main/src/rule.cc)

## Build & Execution

1. Build all `*.cc` files in `src` or use `./compile.sh`. `./main` will be produced in root directory.
2. `./main calc` produces pre-calculation files, `eval.bin` and `op.bin`. (Total 200MB)
1. Build all `*.cc` files in `src`, or just execute `./compile.sh`. If you execute `./compile.sh`, `./main` will be produced in root directory.
2. `./main calc` produces pre-calculation files, `data.bin`. (Total 200MB)
1. Calculation takes 20 minutes, 1.7GB of memory on Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz.
2. pre-computed `eval.bin` and `op.bin` can be downloaded in "Release" tab.
3. `./main` loads `eval.bin` and `op.bin` if they exists.
3. `./main` loads `data.bin` if they exists.

Win10 64bit binary and pre-computed `data.bin` can be downloaded in [Releases](https://github.com/ho94949/yacht-dice/releases) tab.

## Usage

This program shows tabular interface of yacht dice game.
This program shows tabular interface of yacht dice game. Score is your earned score, while estimation is expected value of optimal play.
- `Input your dice (? more re-rolls)`
- You should enter 5 space-separated integer, when dice rolled.
- This program shows recommended dice to keep. (In most program, Click can be used to keep dices.)
Expand Down
44 changes: 24 additions & 20 deletions src/calc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,42 +12,46 @@
double dpave[1<<TOTAL_SUIT][BONUS_LIMIT+1];
int8_t op[TOTAL_DICE_ROUND+1][1<<TOTAL_SUIT][BONUS_LIMIT+1][TOTAL_DICE_COMB];

void save()
bool save(const char* file_name)
{
FILE *fp = fopen("eval.bin", "wb");
if(!fp) std::cerr << "Cannot open eval.bin to write." << std::endl, exit(EXIT_FAILURE);
FILE *fp = fopen(file_name, "wb");
if(!fp) return false;

if(sizeof(dpave)/sizeof(double) !=
fwrite(dpave, sizeof(double), sizeof(dpave)/sizeof(double), fp))
std::cerr << "Cannot write to eval.bin" << std::endl, exit(EXIT_FAILURE);
fclose(fp);

fp = fopen("op.bin", "wb");
if(!fp) std::cerr << "Cannot open op.bin to write." << std::endl, exit(EXIT_FAILURE);

return false;
if(sizeof(op)/sizeof(int8_t) !=
fwrite(op, sizeof(int8_t), sizeof(op)/sizeof(int8_t), fp))
std::cerr << "Cannot write to op.bin" << std::endl, exit(EXIT_FAILURE);
return false;

fclose(fp);
return true;
}

void load(char* prog)
bool load(const char* file_name)
{
FILE *fp = fopen("eval.bin", "rb");
if(!fp) std::cerr << "eval.bin not found. use '" << prog << " calc' to calculate." << std::endl, exit(EXIT_FAILURE);
FILE *fp = fopen(file_name, "rb");
if(!fp)
{
std::cerr << "Cannot open " << file_name << std::endl;
return false;
}

if(sizeof(dpave)/sizeof(double) !=
fread(dpave, sizeof(double), sizeof(dpave)/sizeof(double), fp))
std::cerr << "Corrupted eval.bin" << std::endl, exit(EXIT_FAILURE);
fclose(fp);

fp = fopen("op.bin", "rb");
if(!fp) std::cerr << "op.bin not found. use '" << prog << " calc' to calculate." << std::endl, exit(EXIT_FAILURE);

{
std::cerr << "Corrupted " << file_name << std::endl;
return false;
}
if(sizeof(op)/sizeof(int8_t) !=
fread(op, sizeof(int8_t), sizeof(op)/sizeof(int8_t), fp))
std::cerr << "Corrupted op.bin" << std::endl, exit(EXIT_FAILURE);
{
std::cerr << "Corrupted " << file_name << std::endl;
return false;
}

fclose(fp);
return true;
}

void calc()
Expand Down
13 changes: 9 additions & 4 deletions src/calc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
*/
extern double dpave[1<<TOTAL_SUIT][BONUS_LIMIT+1];



/*
* op[k][i][j][s], optimal operation
* when current selected combinations are i, sum of bonus score is j,
Expand All @@ -24,9 +22,16 @@ extern double dpave[1<<TOTAL_SUIT][BONUS_LIMIT+1];
*/
extern int8_t op[TOTAL_DICE_ROUND+1][1<<TOTAL_SUIT][BONUS_LIMIT+1][TOTAL_DICE_COMB];

// Main calculation, fills dpave and op array.
void calc();
void load(char* prog);
void save();

// Load calculated data from file_name to dpave and op array.
// Returns true on success.
bool load(const char* file_name);

// Save calculated data from dpave and op array to file_name
// Returns true on success.
bool save(const char* file_name);



Expand Down
20 changes: 16 additions & 4 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,27 @@ int main(int argc, char **argv)
if(argc == 2 && std::string(argv[1]) == "calc")
{
calc();
save();
if(!save("data.bin"))
{
std::cerr << "Cannot write to data.bin" << std::endl;
return 1;
}
return 0;
}
else load(argv[0]), std::cout << "Load OK!" << std::endl;
else
{
if(!load("data.bin"))
{
std::cerr << "`" << argv[0] << " calc` to calculate data.bin" << std::endl;
return 1;
}
std::cout << "Load OK!" << std::endl;
}

std::vector<int> score(12);
std::vector<int> score(TOTAL_SUIT);
int curval = 0, bonus = 0;

for(int i=0; i<12; ++i)
for(int i=0; i<TOTAL_SUIT; ++i)
{
Dices d;
print(curval, score);
Expand Down
2 changes: 1 addition & 1 deletion src/print.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include <algorithm>

std::string names[] = {"One", "Two", "Three", "Four", "Five", "Six", "Choice", "Four Card", "Full House", "L.Straight", "S.Straight", "Yacht"};
std::string names[] = {"One", "Two", "Three", "Four", "Five", "Six", "Choice", "Four Card", "Full House", "S.Straight", "L.Straight", "Yacht"};

void print(int selection, const std::vector<int>& score)
{
Expand Down
24 changes: 12 additions & 12 deletions src/rule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@ int FullHouse(Dices d)
else return 0;
}

int LStraight(Dices d)
{
std::sort(d.begin(), d.end());
if( d[0] + 1 == d[1] &&
d[1] + 1 == d[2] &&
d[2] + 1 == d[3] &&
d[3] + 1 == d[4] ) return 30;
else return 0;
}

int SStraight(Dices d)
{
bool a[DICE_NO+1];
Expand All @@ -56,12 +46,22 @@ int SStraight(Dices d)
else return 0;
}

int LStraight(Dices d)
{
std::sort(d.begin(), d.end());
if( d[0] + 1 == d[1] &&
d[1] + 1 == d[2] &&
d[2] + 1 == d[3] &&
d[3] + 1 == d[4] ) return 30;
else return 0;
}

int Yacht(Dices d)
{
for(int v: d) if(v == d[0]) return 0;
for(int v: d) if(v != d[0]) return 0;
return 50;
}

std::function<int(Dices)> scoring[TOTAL_SUIT] = {
Ones, Twos, Threes, Fours, Fives, Sixes, Choice, FourCards, FullHouse, LStraight, SStraight, Yacht
Ones, Twos, Threes, Fours, Fives, Sixes, Choice, FourCards, FullHouse, SStraight, LStraight, Yacht
};

0 comments on commit 60c430e

Please sign in to comment.