这是针对家庭作业 所以我必须编写一个简单的拼字游戏。我在整个计划中都有评论,但我会在本文结尾处解释我想做的事情。
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#define N 96
int main() {
srand((unsigned) time(NULL));
int letter_set = N , size_let = 7 , num_let = 7 , max_size_word = 7 , size_letter_set = 7, size_word, arr[N];
char word [7];
printf("This program plays a game of scrabble.\n");
generate_letter_set(letter_set , size_let , num_let, arr);
read_word(word, max_size_word);
check_word(word, size_word, letter_set, size_letter_set, arr);
return 0;
}
void generate_letter_set(int letter_set[] , int size_let , int num_let, int arr[])
{
const char let[26] =
{'K','J','X','Q','Z','B','C','M','P','F','H','V','W','Y','G','L','S','U','D','N','R','T','O','A','I','E'};
int freq[26] =
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };
const int score[26] =
{ 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
int index = 0;
for(int i = 0 ; i < 26 ; i++) {
for(int f = 0 ; f < freq[i]; f++) {
arr[index++] = let[i]; //All the 96 letters are stored in let[i]
//printf("%c " , let[i]); // Created the letter bank for all the letters
}
}
int letter;
printf("Your letters are: ");
for(int l = 0; l < 7; l++){
letter = rand() % 97; //Gives the user their letters all the letters are from arr[letter]
printf("%c ", arr[letter]);
}
}
int read_word(char word[], int max_size_word) {
{
int c = 0, let_count = 0;
printf("\nPlease enter your word: ");
char input = toupper(getchar());
for(c = 0; c < max_size_word; c++) {
if(input != '\n')
{ word[c] = input;
let_count++;
}
else if(input == '\n')
input = toupper(getchar()); //The word the user entered is in word[c]
}
return let_count;
}
}
int check_word(char word[], int size_word, int letter_set[], int
size_letter_set, int arr[]) {
//Figure out how to pass two arrays through the functions
//Pass word[c] into this function
//Pass arr[letter] into this function then compare the two arrays
//Make it so the user has to enter less than 7 chars
for (int a; a < 7; a++) {
if (word[a] != arr[a]) {
printf("Use your letters");
}
}
return 1;
}
所以我在这个计划中唯一的问题是如何获得我的&#39; check_word&#39;工作的功能。此功能必须检查用户是否输入了提供的字母。在拼字游戏中你得到7个字母,给用户的7个字母的数组存储在(arr [])然后在&#39; read_word&#39; function是用户输入的字母。输入的字母存储在 word [] 中。因此,我检查用户是否实际使用了 arr [] 中的字母的直觉是制作条件语句,比较两个数组 arr [] 和 word [ ] 即可。但是我意识到这将检查用户是否实际使用了每一个字母,我只需要检查用户是否使用了任何未提供的字母。我迷失了如何实现这一点,任何帮助将不胜感激!如果需要澄清,请在评论中告诉我,我也为这篇巨大的帖子道歉。
答案 0 :(得分:4)
所以我在这个程序中唯一的问题就是如何让我的'check_word'功能起作用。这个函数必须检查用户是否输入了提供的字母。在拼字游戏中,你得到7个字母,给用户的7个字母的数组存储在(arr [])中。然后在'read_word'函数中是用户输入的字母。
有很多方法可以解决这个问题。这是一种方式。构建提供给用户的字母的频率表。因此,如果已向用户提供:R S T L N E E
,则freq['R'] = 1
,freq['S] = 1
,freq['T'] = 1
,freq['L'] = 1
,freq['N'] = 1
和freq['E'] = 2
。 freq
中的所有其他值均为0.然后,当用户输入单词时,您可以循环每个字母并从该字母的频率表中减去1。如果任何值小于0,则该单词无效。
但是,您的代码中存在另一个关于随机化输入的问题 - 即:将字母交给用户。 @Weathervane在那里发表了一些可能有所帮助的评论。考虑将所有字母放入set(或更恰当的bag - 因为字母可以重复)并随机从包中画出一个字母。重复7次(或直到袋子为空)。
答案 1 :(得分:1)
当从所有字母和字母中选择字母时,它们会交换到数组的末尾,并且可用字母的数量会减少。
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#define N 98
void generate_letter_set( char arr[], int *all, char yourletters[], int limit);
void read_word(char word[], int max_size_word);
int check_word(char word[], char yourletters[]);
int main ( void) {
srand((unsigned) time(NULL));
char arr[N] = "";
char yourletters [8] = "";
char word [8]= "";
int pool = N;//available letters
int size_let = 7;
int num_let = 7;
int max_size_word = 7;
int size_letter_set = 7;
int size_word;
printf("This program plays a game of scrabble.\n");
printf ( "pool of available letters is %d\n", pool);
generate_letter_set( arr, &pool, yourletters, max_size_word);
printf ( "\npool of available letters is now %d\n", pool);
printf ( "\nyour letters %s\n", yourletters);
read_word(word, max_size_word);
if ( ( check_word(word, yourletters))) {
printf ( "word %s is usable from your letters %s\n", word, yourletters);
}
else {
printf ( "word %s is not usable from your letters %s\n", word, yourletters);
}
return 0;
}
void generate_letter_set(char arr[], int *all,char yourletters[], int limit)
{
const char let[26] = {"KJXQZBCMPFHVWYGLSUDNRTOAIE"};
int freq[26] =
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };
const int score[26] =
{ 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
int index = 0;
for(int i = 0 ; i < 26 ; i++) {
for(int f = 0 ; f < freq[i]; f++) {
arr[index++] = let[i]; //All the 98 letters are stored in let[i]
}
}
int letter;
char swap;
printf("Your letters are: ");
for(int l = 0; l < limit; l++){
letter = rand() % *all; //Gives the user their letters all the letters are from arr[letter]
printf("%c ", arr[letter]);
yourletters[l] = arr[letter];
*all = *all - 1;//deduct from the number of available letters
swap = arr[letter];//swap letter to end of array
arr[letter] = arr[*all];
arr[*all] = swap;
}
}
void read_word(char word[], int max_size_word) {
int c = 0;
printf("\nPlease enter your word: ");
for(c = 0; c < max_size_word; c++) {
int input = toupper(getchar());
if(input != '\n')
{
word[c] = input;
}
else if(input == '\n')
break; //The word the user entered is in word[c]
}
return;
}
int check_word(char word[], char valid[]) {
char *check = word;//check is first letter in word
char swap = ' ';
int match = 0;
int len = strlen ( valid);
//Figure out how to pass two arrays through the functions
//Pass word[c] into this function
//Pass arr[letter] into this function then compare the two arrays
//Make it so the user has to enter less than 7 chars
while ( *check) {//loop until check points to '\0'
for ( int each = 0; each < len; each++) {
match = 0;
//this printf is just for show and can be removed
printf ( "check %c in %.*s\n", *check, len, valid);
if ( *check == valid[each]) {
match = 1;
swap = valid[each];//swap letter to end of array
valid[each] = valid[len - 1];
valid[len - 1] = swap;
len--;//deduct from avaiable letters
break;
}
}
if ( !match) {
return 0;
}
check++;//next letter to check
}
return 1;
}
答案 2 :(得分:1)
我编写了您的任务,如果您有兴趣,我可以在代码中添加注释。
工作原理:
A
为65,B
为66,Z
为90.因此,我们需要90个元素的数组,其中只使用66到90的索引,其他则不需要。所以,我做了下一个技巧 - 从 ascii 字母代码中减去65并得到以下索引:A
- 0,B
- 1,Z
- 26.现在,只需要26个元素的阵列。该方法的优点是以O(1)效率检测字母可用性。数组是否包含M
字母? - 检查数组[12],如果它不为零,则包含字母,否则不包含。不需要两个for
循环。cat
。 Ascii 代码为67
,65
,84
(大写)。从每个代码中减去65,我们获得2
,0
,19
。机架阵列中是否存在此项(非零)?是的 - 这个词是有效的。否 - 无效,&#34;再试一次&#34;。如果机架的瓦片少于7个,则从袋子中重新装满。#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define CNT 26
//////////////////
typedef struct tile {
char letter;
int amount;
int points;
} tile;
/////////////
typedef struct tiles_set {
int tiles_num;
int storage_size;
tile storage[CNT];
} tiles_set;
void check_user_word(char *word, tiles_set rack_copy, tiles_set *rack_ptr);
void fill_rack(tiles_set *rack, int to_size);
void print_set(tiles_set set);
void bag_init();
tiles_set bag;
int main() {
int rack_size = 7;
char *user_word;
srand((unsigned) time(NULL));
bag_init();
tiles_set rack;
rack.storage_size = CNT;
rack.tiles_num = 0;
memset(rack.storage, 0, sizeof(rack.storage));
while(bag.tiles_num > 0 || rack.tiles_num > 0) {
fill_rack(&rack, rack_size);
puts("Rack:");
print_set(rack);
printf("\nWrite your word: \n");
fgets(user_word, rack_size + 2, stdin);
check_user_word(user_word, rack, &rack);
}
return 0;
}
void check_user_word(char *word, tiles_set rack_copy, tiles_set *rack_ptr) {
int i, ch, len;
if(!strchr(word, '\n')) {
printf("The word should be less or equal to the amount of tiles in the rack - %d tiles\n", rack_ptr->tiles_num);
while(((ch = getchar()) != EOF) && (ch != '\n'));
puts("Try again.");
return;
}
len = strlen(word) - 1;
char letter;
for(i = 0; i < len; i++) {
letter = toupper(word[i]) - 65;
if(rack_copy.storage[letter].amount) {
rack_copy.storage[letter].amount--;
rack_copy.tiles_num--;
} else {
puts("You should use letters only from the rack. Try again.");
return;
}
}
*rack_ptr = rack_copy;
}
void fill_rack(tiles_set *rack, int to_size) {
int i;
char letter;
int cnt = to_size - rack->tiles_num;
for(i = 0; i < cnt; i++) {
if(bag.tiles_num <= 0) {
puts("Tiles in the bag ended.");
return;
}
do {
letter = rand() / (RAND_MAX / bag.storage_size + 1);
} while(!bag.storage[letter].amount);
rack->storage[letter].letter = bag.storage[letter].letter;
rack->storage[letter].amount++;
rack->storage[letter].points = bag.storage[letter].points;
rack->tiles_num++;
bag.storage[letter].amount--;
bag.tiles_num--;
}
}
void bag_init() {
const char letters[CNT] =
{'K','J','X','Q','Z','B','C','M','P','F','H','V','W','Y','G','L','S','U','D','N','R','T','O','A','I','E'};
int freq[CNT] =
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };
const int points[CNT] =
{ 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
bag.storage_size = CNT;
bag.tiles_num = 98;
int i;
int letter_index;
for(i = 0; i < bag.storage_size; i++) {
letter_index = letters[i] - 65;
bag.storage[letter_index].letter = letters[i];
bag.storage[letter_index].amount= freq[i];
bag.storage[letter_index].points = points[i];
}
}
void print_set(tiles_set set) {
int i, cnt;
for(i = 0; i < set.storage_size; i++) {
cnt = set.storage[i].amount;
while(cnt > 0) {
printf("%c ", set.storage[i].letter);
cnt--;
}
}
puts("");
}