/* ダンジョン生成 map : フィールドデータ */ void genDungeon(uchar map[FIELD_SZ][FIELD_SZ]){ uchar dir, x, y; uint plen = 0; uint max_plen = FIELD_SZ * FIELD_SZ * 4 / 9; uchar max[2], min[2]; srand(seed); // 初期化 for(y=0; y<FIELD_SZ; y++){ for(x=0; x<FIELD_SZ; x++){ map[y][x] = ID_WALL; } } x = rand() % (FIELD_SZ-1) + 1; // 初期ポイントを設定 y = rand() % (FIELD_SZ-1) + 1; map[y][x] = ID_PASSAGE; // 通路にする plen ++; max[0] = min[0] = x; // 範囲を更新 max[1] = min[1] = y; // 範囲を更新 // 生成する while(plen <= max_plen){ _wdt_reset(); if(scanAround(map, x, y)){ // 周りに進められるところがあるか dir = nextDir(); if(checkdig(map, x, y, dir)){ // その方向に進められるか dig(map, &x, &y, dir, &plen, max, min); // 進める } }else{ // ない findBranchPoint(map, &x, &y, max, min); // 分岐点を決定 } } }
/* * string2ean --- try to parse a string into an ean13. * * If errorOK is false, ereport a useful error message if the string is bad. * If errorOK is true, just return "false" for bad input. * * if the input string ends with '!' it will always be treated as invalid * (even if the check digit is valid) */ static bool string2ean(const char *str, bool errorOK, ean13 *result, enum isn_type accept) { bool digit, last; char buf[17] = " "; char *aux1 = buf + 3; /* leave space for the first part, in case * it's needed */ const char *aux2 = str; enum isn_type type = INVALID; unsigned check = 0, rcheck = (unsigned) -1; unsigned length = 0; bool magic = false, valid = true; /* recognize and validate the number: */ while (*aux2 && length <= 13) { last = (*(aux2 + 1) == '!' || *(aux2 + 1) == '\0'); /* is the last character */ digit = (isdigit((unsigned char) *aux2) != 0); /* is current character * a digit? */ if (*aux2 == '?' && last) /* automagically calculate check digit * if it's '?' */ magic = digit = true; if (length == 0 && (*aux2 == 'M' || *aux2 == 'm')) { /* only ISMN can be here */ if (type != INVALID) goto eaninvalid; type = ISMN; *aux1++ = 'M'; length++; } else if (length == 7 && (digit || *aux2 == 'X' || *aux2 == 'x') && last) { /* only ISSN can be here */ if (type != INVALID) goto eaninvalid; type = ISSN; *aux1++ = toupper((unsigned char) *aux2); length++; } else if (length == 9 && (digit || *aux2 == 'X' || *aux2 == 'x') && last) { /* only ISBN and ISMN can be here */ if (type != INVALID && type != ISMN) goto eaninvalid; if (type == INVALID) type = ISBN; /* ISMN must start with 'M' */ *aux1++ = toupper((unsigned char) *aux2); length++; } else if (length == 11 && digit && last) { /* only UPC can be here */ if (type != INVALID) goto eaninvalid; type = UPC; *aux1++ = *aux2; length++; } else if (*aux2 == '-' || *aux2 == ' ') { /* skip, we could validate but I think it's worthless */ } else if (*aux2 == '!' && *(aux2 + 1) == '\0') { /* the invalid check digit sufix was found, set it */ if (!magic) valid = false; magic = true; } else if (!digit) { goto eaninvalid; } else { *aux1++ = *aux2; if (++length > 13) goto eantoobig; } aux2++; } *aux1 = '\0'; /* terminate the string */ /* find the current check digit value */ if (length == 13) { /* only EAN13 can be here */ if (type != INVALID) goto eaninvalid; type = EAN13; check = buf[15] - '0'; } else if (length == 12) { /* only UPC can be here */ if (type != UPC) goto eaninvalid; check = buf[14] - '0'; } else if (length == 10) { if (type != ISBN && type != ISMN) goto eaninvalid; if (buf[12] == 'X') check = 10; else check = buf[12] - '0'; } else if (length == 8) { if (type != INVALID && type != ISSN) goto eaninvalid; type = ISSN; if (buf[10] == 'X') check = 10; else check = buf[10] - '0'; } else goto eaninvalid; if (type == INVALID) goto eaninvalid; /* obtain the real check digit value, validate, and convert to ean13: */ if (accept == EAN13 && type != accept) goto eanwrongtype; if (accept != ANY && type != EAN13 && type != accept) goto eanwrongtype; switch (type) { case EAN13: valid = (valid && ((rcheck = checkdig(buf + 3, 13)) == check || magic)); /* now get the subtype of EAN13: */ if (buf[3] == '0') type = UPC; else if (strncmp("977", buf + 3, 3) == 0) type = ISSN; else if (strncmp("978", buf + 3, 3) == 0) type = ISBN; else if (strncmp("9790", buf + 3, 4) == 0) type = ISMN; else if (strncmp("979", buf + 3, 3) == 0) type = ISBN; if (accept != EAN13 && accept != ANY && type != accept) goto eanwrongtype; break; case ISMN: memcpy(buf, "9790", 4); /* this isn't for sure yet, for now * ISMN it's only 9790 */ valid = (valid && ((rcheck = checkdig(buf, 13)) == check || magic)); break; case ISBN: memcpy(buf, "978", 3); valid = (valid && ((rcheck = weight_checkdig(buf + 3, 10)) == check || magic)); break; case ISSN: memcpy(buf + 10, "00", 2); /* append 00 as the normal issue * publication code */ memcpy(buf, "977", 3); valid = (valid && ((rcheck = weight_checkdig(buf + 3, 8)) == check || magic)); break; case UPC: buf[2] = '0'; valid = (valid && ((rcheck = checkdig(buf + 2, 13)) == check || magic)); default: break; } /* fix the check digit: */ for (aux1 = buf; *aux1 && *aux1 <= ' '; aux1++); aux1[12] = checkdig(aux1, 13) + '0'; aux1[13] = '\0'; if (!valid && !magic) goto eanbadcheck; *result = str2ean(aux1); *result |= valid ? 0 : 1; return true; eanbadcheck: if (g_weak) { /* weak input mode is activated: */ /* set the "invalid-check-digit-on-input" flag */ *result = str2ean(aux1); *result |= 1; return true; } if (!errorOK) { if (rcheck == (unsigned) -1) { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid %s number: \"%s\"", isn_names[accept], str))); } else { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid check digit for %s number: \"%s\", should be %c", isn_names[accept], str, (rcheck == 10) ? ('X') : (rcheck + '0')))); } } return false; eaninvalid: if (!errorOK) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for %s number: \"%s\"", isn_names[accept], str))); return false; eanwrongtype: if (!errorOK) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("cannot cast %s to %s for number: \"%s\"", isn_names[type], isn_names[accept], str))); return false; eantoobig: if (!errorOK) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for %s type", str, isn_names[accept]))); return false; }