#include #include #include #include #include #include #include #include /* include game configuration */ #ifndef GAME_CONF #define GAME_CONF "gold-cult.h" #endif #include GAME_CONF /* in the following variables named selected, selected1, selected2 refer to bitsets which represent selected words from words[] */ #ifndef LINE_LENGTH #define LINE_LENGTH 70 #endif /* print words that have not yet been selected */ void print_word_set(unsigned int indent, unsigned int group_size, unsigned int selected) { unsigned int printed = 0; unsigned int group_count = 0; for (unsigned int index = 0; index < nof_words; ++index) { if ((1< 0 && group_count == group_size) || (printed > 0 && indent + printed + len + 1 > LINE_LENGTH)) { printf("\n%*s", indent, ""); printed = 0; group_count = 0; } if (printed) { printf(" "); ++len; } printf("%s", words[index]); printed += len; ++group_count; } } printf("\n"); } /* number of letters 'a' to 'z' */ enum { letters = 'z' - 'a' + 1 }; /* return true if the selected words win, i.e. if one of the letters occurs winning_count times */ char won(unsigned int selected) { unsigned int count[letters] = {0}; for (unsigned int index = 0; index < nof_words; ++index) { if ((1<= winning_count) { unsigned int val = count1[letter]; sum += val * val; } } return sum; } /* evaluate situation for player 1 who has selected selected1 */ int eval(unsigned int selected1, unsigned int selected2) { if (won(selected1)) return INT_MAX; if (won(selected2)) return -INT_MAX; return evaluate_counts(selected1, selected2) - evaluate_counts(selected2, selected1); } #ifndef MAX_LEVEL #define MAX_LEVEL 4 /* default recursion depth of chose_move */ #endif /* chose a move for the next player: - selected1: selected words of the player - selected2: selected words of the opponent - move: pointer where the best move is stored - level: current recursion depth chose_move returns an integer value which is - > 0: if the situation is promising - = 0: if the situation appears to be balanced - < 0: if the opponent has an advantage */ int chose_move(unsigned int selected1, unsigned int selected2, unsigned int* move, unsigned int level) { unsigned int selected = selected1 | selected2; unsigned int best_move = 0; int best_result = 0; unsigned int best_move_count = 0; for (unsigned int index = 0; index < nof_words; ++index) { if (!((1< best_result) { best_move = index; best_result = res; best_move_count = 1; } else if (res == best_result) { /* if there are multiple equally good moves, select one by random */ ++best_move_count; if (rand() % best_move_count == 0) { best_move = index; } } } } assert(best_move_count > 0); *move = best_move; return best_result; } /* read and check a move from a human player */ bool read_move(unsigned int selected1, unsigned int selected2, unsigned int* move) { for(;;) { printf("Which word? "); char word[word_len+1]; if (scanf(word_format, word) != 1) { printf("Bye!\n"); return false; } bool retry = false; for (unsigned int i = 0; !retry && i < nof_words; ++i) { if (strcmp(word, words[i]) == 0) { if ((1<