在Word搜索游戏中重叠的单词 [英] Words overlapping in a Word Search game

查看:145
本文介绍了在Word搜索游戏中重叠的单词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此函数中,程序从列表中获取先前生成的四个随机字,并随机将它们放在10x10矩阵中。

In this function the program gets the four random words generated previously from a list and randomly puts them in the 10x10 matrix.

问题是, / vertical / slanting相互重叠(但是来自同一类别的单词没有)。我不希望它们以这种方式重叠

The problem is that sometimes words from horizontal/vertical/slanting overlap each other (however words from the same category don't). I don't want them to overlap in this way

    void outputMatrix() {
char matrix[10][10];
for (int i = 0; i<10; i++) {
    for (int j = 0; j<10; j++) {
        matrix[i][j] = '-';         
    }
}
getRandomWord();
srand(time(NULL));
int randPosY = (rand() % 9);
int randPosX = (rand() % 9);
int incr = 0;
bool amend;
char r; 
for (int x = 0; x < 4; x++) {
    char randCase = (rand() % 3) + 65;

    switch (randCase) {
    case 'A': //to input words horizontally         
        if (incr == 1) {
            r1 = r2;
        }
        if (incr == 2) {
            r1 = r3;
        }
        if (incr == 3) {
            r1 = r4;
        }   

    reCheck:
        amend = false;
        if ((randPosX + strlen(dictionary[r1]) > 10)) {
            randPosX--;
            goto reCheck;
        }

        for (int i = 0; i < strlen(dictionary[r1]); i++) {
            matrix[randPosY][randPosX + i] = dictionary[r1][i];
        }

        for (int i = 0; i < strlen(dictionary[r1]); i++) {
            reRand:
                if (matrix[randPosY][randPosX + i] != '-') {
                    randPosY = (rand() % 9);
                    randPosX = (rand() % 9);                        
                    goto reRand;
                    amend = true;

                }if ((i == (strlen(dictionary[r1]) - 1)) && (amend == true)) goto reCheck;
            }           
        break;

    case 'B': //to input words vertically           
        if (incr == 1) {
            r1 = r2;
        }
        if (incr == 2) {
            r1 = r3;
        }
        if (incr == 3) {
            r1 = r4;
        }       
    reCheck2:
        amend = false;
        if ((randPosY + strlen(dictionary[r1]) > 10)) {
            randPosY--;
            goto reCheck2;
        }           
        for (int i = 0; i < strlen(dictionary[r1]); i++) {
            matrix[randPosY + i][randPosX] = dictionary[r1][i];
        }
        for (int i = 0; i < strlen(dictionary[r1]); i++) {
        reRand2:
            if (matrix[randPosY + i][randPosX] != '-') {
                randPosY = (rand() % 9);
                randPosX = (rand() % 9);
                goto reRand2;
                amend = true;
            }if ((i == (strlen(dictionary[r1]) - 1)) && (amend == true)) goto reCheck2;
        }
            break;

    case 'C': //to input words slanting         
        if (incr == 1) {
            r1 = r2;
        }
        if (incr == 2) {
            r1 = r3;
        }
        if (incr == 3) {
            r1 = r4;
        }

    reCheck3:
        amend = false;
        if ((randPosY + strlen(dictionary[r1]) > 10)) {
            randPosY--;
            goto reCheck3;
        }
    reCheck4:
        if ((randPosX + strlen(dictionary[r1]) > 10)) {
            randPosX--;
            goto reCheck4;
        }
        for (int i = 0; i < strlen(dictionary[r1]); i++) {
            matrix[randPosY + i][randPosX + i] = dictionary[r1][i];
        }
        for (int i = 0; i < strlen(dictionary[r1]); i++) {
        reRand3:
            if (matrix[randPosY + i][randPosX + i] != '-') {
                randPosY = (rand() % 9);
                randPosX = (rand() % 9);
                amend == true;
                goto reRand3;
            }if ((i == (strlen(dictionary[r1]) - 1)) && (amend == true)) goto reCheck3;
        }           
        break;
        } incr++;           
    }

//for (int i = 0; i<10; i++) {
    //for (int j = 0; j < 10; j++) {
        //if (matrix[i][j] == '-') {
            //r = (rand() % 26) + 65;
            //matrix[i][j] = r;
        //}

    //}
//}
printf("\n\t     A  B  C  D  E  F  G  H  I  J\n\n\n\t");
for (int a = 0; a <10; a++) {
    printf("%d", a);
    printf("    ");
    for (int b = 0; b < 10; b++) {
        printf("%c  ", matrix[a][b]);
    }       
    printf("\n\n\t");
}
}


推荐答案

放置字词的逻辑应为:


  • 选择字词

  • 选择随机坐标和方向


>相反,你放置第一个单词而不检查碰撞(这是好的,你有一个空的网格),并选择新的坐标,你放一个字。当时你不知道你要放置哪个单词,你要放置它的方向,以及是否必须调整坐标,以防止你的单词溢出网格的边框。

Instead, you place the first word without checking for collision (which is okay, you've got an empty grid) and pick new coordinates after you've placed a word. At that time you don't know which word you are going to place, at which orientation you are going to place it and whether you must adjust your coordinates to prevent your word from spilling over the grid's borders.

您的代码显示其他问题:

Your code exhibits other problems:


  • 您使用 goto s使代码几乎不可读。您可以用常见的控制结构替换所有的 goto 。例如,

  • Your use of gotos makes the code nearly unreadable. You can substitute all of the gotos with common control constructs. For example,

reCheck4:
    if ((randPosX + strlen(dictionary[r1]) > 10)) {
        randPosX--;
        goto reCheck4;
    }  

可写为

while (randPosX + strlen(dictionary[r1]) > 10) randPosX--;

某些 goto 无法存取示例:

goto reRand2;
amend = true;

此处 amend = true 。 (奇怪的是,你使用Fortran77-ish gotos遍布整个地方,但它们可以更清晰的地方,你使用一个Pascal-ish真值变量。)

Here amend = true will never be executed. (It's strange that you use the Fortran77-ish gotos all over the place, but the one place where they might have been clearer, you use a Pascal-ish truth variable.)

您对四个单词的循环使用 x ,但是您从不使用该变量。而是保留另一个变量 incr ,其值与 x 的值相同。替换

Your loop over the four words uses x, but you never use that variable. Instead, you keep another variable incr, whose value is the same as the value of x. Replace

int incr = 0;

for (int x = 0; x < 4; x++) {
    // Do stuff with incr, but not with x
    incr++;
}

与:

for (int incr = 0; incr < 4; incr++) {
    // Do stuff with incr, but not with x
}


  • 您有四个字词索引, r1 r4

    if (incr == 1) {
        r1 = r2;
    }
    if (incr == 2) {
        r1 = r3;
    }
    if (incr == 3) {
        r1 = r4;
    }
    

    你甚至在所有三个方向的情况下重复,建议你想要一个数组这里:

    which you even repeat in all three orientation cases, suggests that you want an array here:

    r1 = index[incr];
    


  • 只呼叫 srand main 开头。重复以 srand 以低粒度种子(例如时间(秒))调用 srand 会使您的程序更少随机。

  • Call srand only once, at the beginning of main. Repeatedly calling srand with a low-granularity seed such as the time in seconds will make your program less random.

    strlen 是一个函数,每次你通过遍历字符串直到找到null终止符,每次你确定字符串的长度。你总是在循环中查看同一个字符串,所以你可以把字符串长度存储在一个变量中。 (

    strlen is a function that determines the length of the string every time you call it by traversing the string until it finds the null terminator. You are always looking at the same string in the loop, so you can store the string length in a variable. (Yourstrings are short, and the overhead is negligible, but still.)

    您可以通过点击测试前面。这将意味着第一个单词的空测试,但至少逻辑是清楚的。

    You can correct your code by ptting the tests up front. That will mean a null test for the first word, but at least the logic is clear.

    您可以通过几种方式改进您的代码:

    You can improve your code in several ways:


    • 尝试消除代码的重复。目前,你的三种情况几乎相同。找到公共部分并将它们合并成一个公共函数。例如,方向实际上仅仅意味着通过网格的其它运动矢量,即对于垂直的(0,1),对于垂直的(0,1),对于对角线的(1,1)。

    • Try to eliminate the duplication of code. At the moment, your three cases are nearly the same. Find the common parts and coalesce them into a common function. For example, the orientations really just mean other "movement vectors" through the grid, namely (0,1) for oriontal, (0,1) for vertical and (1,1) for diagonal.

    一旦你有了这个,你可以计算前面位置的有效范围。不需要调整坐标。

    Once you have this, you can calulate the valid ranges for the position up front. There's no need to adjust the coordinates.

    不要害怕使用函数。将任务分解为函数意味着必须传递一些数据,但这也意味着如果必须,您可以立即使用返回值跳出函数。这会为你节省很多 goto 和真值变量,并且是C的流控制方式。

    Don't be shy to use functions. Separating tasks into functions means that you must pass some data, but it also means that you can jump out of the function with a return value right away if you have to. This saves you a lot of gotos and truth variables and is C's way of flow control.

    可以放置一个词是一个很好的候选函数。

    Checking whether you can place a word is a good candidate for a function. Placing the word, too.

    Tim B已设定重设。

    Tim B has sugested a reset. That's a good idea, because you might pait yourself into a corner here if your words are long.

    这是一个修订版本(或重写,而不是代码)版本,但不会随机选择要放置的字词:

    Here's a revised (or rewritten, rather) version of your code, which does not pick the words to place randomly, however:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    int isvalid(char matrix[10][10], int x, int y, int dx, int dy, int len)
    {
        for (int i = 0; i < len; i++) {
            if (matrix[y][x] != '-') return 0;
            x += dx;
            y += dy;
        }
    
        return 1;
    }
    
    void matrix_fill(char matrix[10][10], const char *words[4])
    {
        int dx[3] = {1, 0, 1};      // horizontal strides
        int dy[3] = {0, 1, 1};      // vertical strides
    
        startover:
    
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                matrix[j][i] = '-';
            }
        }
    
        for (int i = 0; i < 4; i++) {
            const char *word = words[i];
            int len = strlen(word);
    
            int orient, x, y;
            int tries = 0;
            int valid;
    
            if (len > 8) break;     // just to be sure
    
            do {
                orient = rand() % 3;
                x = rand() % (10 - dx[orient] * len);
                y = rand() % (10 - dy[orient] * len);
    
                valid = isvalid(matrix, x, y,
                                dx[orient], dy[orient], len);            
                tries++;
            } while (!valid && tries < 100);
    
            if (!valid) goto startover;
    
            for (int i = 0; i < len; i++) {
                matrix[y][x] = word[i];
                x += dx[orient];
                y += dy[orient];
            }
        }
    
    }
    
    void matrix_print(char matrix[10][10])
    {
        printf("%4s    ", "");
        for (int i = 0; i < 10; i++) {
            printf("%4c", 'A' + i);
        }
        printf("\n\n");
    
        for (int j = 0; j < 10; j++) {
            printf("%4d    ", j);
    
            for (int i = 0; i < 10; i++) {
                printf("%4c", matrix[j][i]);
            }
            printf("\n\n");
        }
    }
    
    int main()
    {
        const char *dictionary[4] = {"apple", "pear", "cherry", "lemon"};
        char matrix[10][10];
    
        srand(time(NULL));
    
        matrix_fill(matrix, dictionary);
        matrix_print(matrix);
    
        return 0;
    }
    

    这篇关于在Word搜索游戏中重叠的单词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆