Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann.

das perfekte Labyrinth

Diskussion: das perfekte Labyrinth im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige *up* Hehe, haben die Threads in diesem Subforum eigentlich ein Verfallsdatum? Naja, ich hab mich mal rangesetzt. labyrinth.c   ...

Antwort
Alt 28.01.09, 08:18   #16 (permalink)
 
Registriert seit: 22.03.08
MontyPerl Leistung: Facit NTK
Likes: 0
Standard

Anzeige

*up*
Hehe, haben die Threads in diesem Subforum eigentlich ein Verfallsdatum?

Naja, ich hab mich mal rangesetzt.

labyrinth.c   
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define UPPER 1
#define RIGHT 2
#define LOWER 4
#define LEFT  8

#define START   16
#define END     32
#define VISITED 64

typedef struct {
    int xdim, ydim;   /* size */
    char **lab;
} labyrinth;

void *xmalloc(int size);    /* malloc() with automatic errorchecking */
labyrinth *getLab(int xdim, int ydim);
void createWays(labyrinth *l, int x, int y);
int solveRecur(labyrinth *l, int x, int y);
void solve(labyrinth *l);
void printLab(labyrinth *l);

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "usage: %s <x-dimension> <y-dimension>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    int x, y;
    x = atoi(argv[1]);
    y = atoi(argv[2]);
    labyrinth *l = getLab(x, y);

    srand( time(NULL) );
    createWays(l, rand() % l->xdim, rand() % l->ydim);
    solve(l);

    printLab(l);

    return EXIT_SUCCESS;
}

void solve(labyrinth *l) {
    int endx, endy;
    int startx = rand() % l->xdim;
    int starty = rand() % l->ydim;
    l->lab[starty][startx] ^= START;
    do {
        endx = rand() % l->xdim;
        endy = rand() % l->ydim;
    } while (endx == startx && endy == starty);

    l->lab[endy][endx] ^= END;
    solveRecur(l, startx, starty);
}

int solveRecur(labyrinth *l, int x, int y) {
    l->lab[y][x] ^= VISITED;
    if (l->lab[y][x] & END) {
        return 1;
    }
    int i;
    for (i = 0; i < 4; i++) {
        if (i == 0) {
            if (
                y > 0
             && !(l->lab[y][x] & UPPER)
             && !(l->lab[y-1][x] & VISITED)
            ) {
                if (solveRecur(l, x, y-1)) {
                    return 1;
                }
            }
        }
        else if (i == 1) {
            if (
                y < (l->ydim - 1)
             && !(l->lab[y][x] & LOWER)
             && !(l->lab[y+1][x] & VISITED)
            ) {
                if (solveRecur(l, x, y+1)) {
                    return 1;
                }
            }
        }
        else if (i == 2) {
            if (
                x > 0
             && !(l->lab[y][x] & LEFT)
             && !(l->lab[y][x-1] & VISITED)
            ) {
                if (solveRecur(l, x-1, y)) {
                    return 1;
                }
            }
        }
        else if (i == 3) {
            if (
                x < (l->xdim - 1)
             && !(l->lab[y][x] & RIGHT)
             && !(l->lab[y][x+1] & VISITED)
            ) {
                if (solveRecur(l, x+1, y)) {
                    return 1;
                }
            }
        }
    }
    l->lab[y][x] ^= VISITED;
    return 0;
}

void createWays(labyrinth *l, int x, int y) {
    int choice, gone = 0;
    while (gone != 15) {
        do {
            choice = rand() % 4;
            choice = 1 << choice;
        } while (choice & gone);

        if (choice == UPPER) {
            if (y > 0 && l->lab[y-1][x] == 15) {
                l->lab[y][x] &= ~ UPPER;
                l->lab[y-1][x] &= ~ LOWER;
                createWays(l, x, y-1);
            }
            gone |= UPPER;
        }
        else if (choice == LOWER) {
            if (y < (l->ydim-1) && l->lab[y+1][x] == 15) {
                l->lab[y][x] &= ~ LOWER;
                l->lab[y+1][x] &= ~ UPPER;
                createWays(l, x, y+1);
            }
            gone |= LOWER;
        }
        else if (choice == LEFT) {
            if (x > 0 && l->lab[y][x-1] == 15) {
                l->lab[y][x] &= ~ LEFT;
                l->lab[y][x-1] &= ~ RIGHT;
                createWays(l, x-1, y);
            }
            gone |= LEFT;
        }
        else if (choice == RIGHT) {
            if (x < (l->xdim-1) && l->lab[y][x+1] == 15) {
                l->lab[y][x] &= ~ RIGHT;
                l->lab[y][x+1] &= ~ LEFT;
                createWays(l, x+1, y);
            }
            gone |= RIGHT;
        }
    }
}

labyrinth *getLab(int xdim, int ydim) {
    char *rows = xmalloc(xdim * ydim);
    char **cols = xmalloc(ydim * sizeof(char *));
    int i, j;
    for (i = 0; i < ydim; i++) {
        cols[i] = &rows[i * xdim];
        for (j = 0; j < xdim; j++) {
            cols[i][j] = 15; /* all walls are up */
        }
    }
    labyrinth *l = xmalloc(sizeof(labyrinth));
    l->lab = cols;
    l->xdim = xdim;
    l->ydim = ydim;
    return l;
}

void printLab(labyrinth *l) {
    int x, y, floor;
    char *e, *e2, *f = "##";
    printf("\n\n");
    for (x = 0; x < l->xdim; x++) {
        printf("%s%s", f, f);
    }
    printf("##\n");
    for (y = 0; y < l->ydim; y++) {
        for (floor = 0; floor < 2; floor++) {
            for (x = 0; x < l->xdim; x++) {
                e =   (l->lab[y][x] & START)
                    ? ":o"
                    : (l->lab[y][x] & END)
                    ? ":D"
                    : (l->lab[y][x] & VISITED)
                    ? ".."
                    : "  ";
                e2 = e;
                if (floor == 0) {
                    if (x > 0 && !(l->lab[y][x-1] & VISITED)) {
                        e2 = "  ";
                    }
                    printf("%s%s", l->lab[y][x] & LEFT ? f : e2, e);
                }
                else if (floor == 1) {
                    if (y < (l->ydim - 1) && !(l->lab[y+1][x] & VISITED)) {
                        e2 = "  ";
                    }
                    printf("%s%s", f, l->lab[y][x] & LOWER ? f : e2);
                }
            }
            printf("##\n");
        }
    }

}

void *xmalloc(int size) {
    void *ptr = malloc(size);
    if (ptr == NULL) {
        fprintf(stderr, "not enough memory\n");
        exit(EXIT_FAILURE);
    }
    return ptr;
}


Code:
$ ./labyrinth 20 20


##################################################################################
##......        ##..............    ##..............##......    ##......    ##  ##
##..##..##  ######..##########..##  ##..##########..##..##..##  ##..##..##  ##  ##
##..##..##  ##......##      ##..##  ##..##      ##..##..##..##  ##..##..##      ##
##..##..######..##########  ##..######..##  ##  ##..##..##..##  ##..##..######  ##
##..##..........##      ##  ##..........##  ##  ##..##..##..##  ##..##......##  ##
##..##############  ##  ##  ##################  ##..##..##..##  ##..######..##  ##
##..##:D        ##  ##          ##              ##......##..##  ##..##  ##..##  ##
##..##:D######  ##  ##########  ##  ##  ##################..##  ##..##  ##..######
##......##          ##      ##  ##  ##  ##              ##..##  ##......##......##
##############  ######  ##  ##  ######  ##  ##########  ##..##  ######..######..##
##          ##  ##      ##  ##          ##  ##      ##  ##..##  ##......##  ##..##
##  ######  ######  ######  ##########  ##  ##  ######  ##..######..######  ##..##
##  ##  ##          ##  ##      ##      ##  ##          ##..........##      ##..##
##  ##  ##############  ######  ##########  ##  ##############  ######  ######..##
##  ##                  ##  ##              ##  ##          ##  ##          ##..##
##  ##########  ######  ##  ##################  ##  ######  ##  ######  ##  ##..##
##  ##      ##      ##                      ##      ##  ##  ##      ##  ##  ##..##
##  ##  ##  ##  ##  ##################################  ##  ######  ##  ##  ##..##
##      ##  ##  ##          ##      ##              ##      ##  ##  ##  ##  ##..##
##########  ##############  ##  ##  ##  ######  ######  ######  ##  ######  ##..##
##      ##  ##              ##  ##      ##  ##      ##  ##      ##  ##      ##..##
##  ######  ##  ##########  ##  ##########  ######  ##  ##  ######  ##  ######..##
##      ##  ##  ##          ##  ##          ##  ##      ##      ##  ##      ##..##
######  ##  ##  ##  ##########  ######  ##  ##  ##########  ##  ##  ######  ##..##
##      ##  ##  ##  ##  ##      ##      ##              ##  ##              ##..##
##  ######  ##  ##  ##  ##  ######  ##################  ######  ##############..##
##  ##      ##  ##      ##          ##          ##  ##      ##  ##..............##
##  ######  ##  ######################  ######  ##  ######  ######..##############
##          ##                          ##              ##      ##:o    ##      ##
##############  ##############  ######  ##############  ######  ##  ##  ##  ##  ##
##          ##              ##  ##  ##  ##          ##      ##  ##  ##      ##  ##
##  ######  ##############  ##  ##  ##  ##  ######  ######  ##  ##############  ##
##      ##  ##      ##      ##  ##      ##  ##  ##      ##  ##      ##      ##  ##
##  ##  ######  ##  ##  ######  ##  ######  ##  ######  ##########  ##  ##  ##  ##
##  ##          ##  ##  ##      ##  ##  ##  ##      ##              ##  ##  ##  ##
##  ##############  ##  ##  ######  ##  ##  ######  ##################  ##  ##  ##
##  ##          ##      ##  ##          ##      ##          ##      ##  ##      ##
##  ##########  ##########  ##################  ######  ##  ##  ##  ##  ######  ##
##                      ##                              ##      ##      ##      ##
##################################################################################

$ time ./labyrinth 800 800 >/dev/null

real    0m1.360s
user    0m1.239s
sys     0m0.027s
$ time ./labyrinth 1000 1000 >/dev/null

real    0m2.144s
user    0m2.016s
sys     0m0.024s
$ time ./labyrinth 5000 5000 >/dev/null

real    0m53.948s
user    0m51.399s
sys     0m0.536s
MontyPerl ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » das perfekte Labyrinth
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Perfekte Distribution? kalil1234 Linux/UNIX 6 12.04.07 14:12
die perfekte Maus ghostdog Hardware Probleme 25 20.07.05 08:18
Labyrinth Nornagest Programmieraufgaben 10 19.10.04 15:49


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 50 51 52 53 54 55 56 57 58 59 60 61