void test_tree() { TreeNode *tree = (TreeNode*)malloc(sizeof(TreeNode)); int key = 0; init_tree(key++, 0, 0, tree); add_left(key++, 0, tree); add_right(key++, 0, tree); add_left(key++, 0, tree->left); add_right(key++, 0, tree->left); add_left(key++, 0, tree->right); add_right(key++, 0, tree->right); add_left(key++, 0, tree->left->left); print_tree(tree); std::cout << std::endl; std::cout << "max depth: " << max_depth(tree, 0) << std::endl; std::cout << "min depth: " << min_depth(tree, 0) << std::endl; std::cout << "Is tree balanced? " << (is_tree_balanced(tree) == 1 ? "yes" : "no") << std::endl; free_tree(tree); }
int min_depth(node_t *node) { if( node == nullptr ) return 0; int dlhs = min_depth(node->lhs); int drhs = min_depth(node->rhs); if( dlhs <= drhs ) return dlhs + 1; else return drhs + 1; }
int isBalanced(struct btree *root) { if(max_depth(root)-min_depth(root) <= 1) { printf("Tree is balanced\n"); return 0; } else { printf("NOT BALANCED\n"); return 1; } }
/* * Read the dungeon * * The monsters/objects must be loaded in the same order * that they were stored, since the actual indexes matter. * * Note that the size of the dungeon is now hard-coded to * DUNGEON_HGT by DUNGEON_WID, and any dungeon with another * size will be silently discarded by this routine. * * Note that dungeon objects, including objects held by monsters, are * placed directly into the dungeon, using "object_copy()", which will * copy "iy", "ix", and "held_m_idx", leaving "next_o_idx" blank for * objects held by monsters, since it is not saved in the savefile. * * After loading the monsters, the objects being held by monsters are * linked directly into those monsters. */ static errr rd_dungeon(void) { int i, y, x; int by, bx; s16b town; s16b dungeon; s16b depth; s16b py, px; s16b ymax, xmax; byte count; byte tmp8u; u16b tmp16u; u16b limit; /*** Basic info ***/ /* Header info */ rd_s16b(&depth); rd_s16b(&dungeon); rd_s16b(&py); rd_s16b(&px); rd_s16b(&ymax); rd_s16b(&xmax); rd_s16b(&town); rd_u16b(&tmp16u); /* Ignore illegal dungeons */ if (town>=z_info->t_max) { note(format("Ignoring illegal dungeon (%d)", dungeon)); return (0); } /* Ignore illegal dungeons */ if ((depth < 0) || (depth > max_depth(dungeon))) { note(format("Ignoring illegal dungeon depth (%d)", depth)); return (0); } /* Ignore illegal dungeons */ if ((ymax != DUNGEON_HGT) || (xmax != DUNGEON_WID)) { /* XXX XXX XXX */ note(format("Ignoring illegal dungeon size (%d,%d).", ymax, xmax)); return (0); } /* Ignore illegal dungeons */ if ((px < 0) || (px >= DUNGEON_WID) || (py < 0) || (py >= DUNGEON_HGT)) { note(format("Ignoring illegal player location (%d,%d).", py, px)); return (1); } /*** Run length decoding ***/ /* Load the dungeon data */ for (x = y = 0; y < DUNGEON_HGT; ) { /* Grab RLE info */ rd_byte(&count); rd_byte(&tmp8u); /* Apply the RLE info */ for (i = count; i > 0; i--) { /* Extract "info" */ cave_info[y][x] = tmp8u; /* Advance/Wrap */ if (++x >= DUNGEON_WID) { /* Wrap */ x = 0; /* Advance/Wrap */ if (++y >= DUNGEON_HGT) break; } } } /* Hack -- not fully dynamic */ dyna_full = FALSE; /*** Run length decoding ***/ /* Load the dungeon data */ for (x = y = 0; y < DUNGEON_HGT; ) { /* Grab RLE info */ rd_byte(&count); if (variant_save_feats) rd_u16b(&tmp16u); else rd_byte(&tmp8u); /* Apply the RLE info */ for (i = count; i > 0; i--) { /* Save the feat */ if (variant_save_feats) cave_feat[y][x] = tmp16u; else cave_feat[y][x] = tmp8u; /* Check for los flag set*/ if (f_info[cave_feat[y][x]].flags1 & (FF1_LOS)) { cave_info[y][x] &= ~(CAVE_WALL); } /* Handle wall grids */ else { cave_info[y][x] |= (CAVE_WALL); } /* Handle dynamic grids */ if (f_info[cave_feat[y][x]].flags3 & (FF3_DYNAMIC_MASK)) { if (dyna_n < (DYNA_MAX-1)) { dyna_g[dyna_n++] = GRID(y,x); } else { dyna_full = TRUE; dyna_cent_y = 255; dyna_cent_x = 255; } } /* Advance/Wrap */ if (++x >= DUNGEON_WID) { /* Wrap */ x = 0; /* Advance/Wrap */ if (++y >= DUNGEON_HGT) break; } } } /*** Player ***/ /* Fix depth */ if (depth < 1) depth = min_depth(dungeon); /* Fix depth */ if (depth > max_depth(dungeon)) depth = max_depth(dungeon); /* Load depth */ p_ptr->depth = depth; p_ptr->dungeon = dungeon; p_ptr->town = town; /* Place player in dungeon */ if (!player_place(py, px)) { note(format("Cannot place player (%d,%d)!", py, px)); return (-1); } /*** Room descriptions ***/ if (!variant_room_info) { /* Initialize the room table */ for (by = 0; by < MAX_ROOMS_ROW; by++) { for (bx = 0; bx < MAX_ROOMS_COL; bx++) { dun_room[by][bx] = 0; } } /* Initialise 'zeroeth' room description */ room_info[0].flags = 0; } else { for (bx = 0; bx < MAX_ROOMS_ROW; bx++) { for (by = 0; by < MAX_ROOMS_COL; by++) { rd_byte(&dun_room[bx][by]); } } for (i = 1; i < DUN_ROOMS; i++) { int j; rd_byte(&room_info[i].type); rd_byte(&room_info[i].flags); if (room_info[i].type == ROOM_NORMAL) { for (j = 0; j < ROOM_DESC_SECTIONS; j++) { rd_s16b(&room_info[i].section[j]); if (room_info[i].section[j] == -1) break; } } } } /*** Objects ***/ /* Read the item count */ rd_u16b(&limit); /* Verify maximum */ if (limit > z_info->o_max) { note(format("Too many (%d) object entries!", limit)); return (-1); } /* Read the dungeon items */ for (i = 1; i < limit; i++) { object_type *i_ptr; object_type object_type_body; s16b o_idx; object_type *o_ptr; /* Get the object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Read the item */ if (rd_item(i_ptr)) { note("Error reading item"); return (-1); } /* Make an object */ o_idx = o_pop(); /* Paranoia */ if (o_idx != i) { note(format("Cannot place object %d!", i)); return (-1); } /* Get the object */ o_ptr = &o_list[o_idx]; /* Structure Copy */ object_copy(o_ptr, i_ptr); /* Dungeon floor */ if (!i_ptr->held_m_idx) { int x = i_ptr->ix; int y = i_ptr->iy; /* ToDo: Verify coordinates */ /* Link the object to the pile */ o_ptr->next_o_idx = cave_o_idx[y][x]; /* Link the floor to the object */ cave_o_idx[y][x] = o_idx; } } /*** Monsters ***/ /* Read the monster count */ rd_u16b(&limit); /* Hack -- verify */ if (limit > z_info->m_max) { note(format("Too many (%d) monster entries!", limit)); return (-1); } /* Read the monsters */ for (i = 1; i < limit; i++) { monster_type *n_ptr; monster_type monster_type_body; /* Get local monster */ n_ptr = &monster_type_body; /* Clear the monster */ (void)WIPE(n_ptr, monster_type); /* Read the monster */ rd_monster(n_ptr); /* Place monster in dungeon */ if (monster_place(n_ptr->fy, n_ptr->fx, n_ptr) != i) { note(format("Cannot place monster %d", i)); return (-1); } } /*** Holding ***/ /* Reacquire objects */ for (i = 1; i < o_max; ++i) { object_type *o_ptr; monster_type *m_ptr; /* Get the object */ o_ptr = &o_list[i]; /* Ignore dungeon objects */ if (!o_ptr->held_m_idx) continue; /* Verify monster index */ if (o_ptr->held_m_idx >= z_info->m_max) { note("Invalid monster index"); return (-1); } /* Get the monster */ m_ptr = &m_list[o_ptr->held_m_idx]; /* Link the object to the pile */ o_ptr->next_o_idx = m_ptr->hold_o_idx; /* Link the monster to the object */ m_ptr->hold_o_idx = i; } /*** Success ***/ /* The dungeon is ready */ character_dungeon = TRUE; /* Regenerate town in post 2.9.3 versions */ if (older_than(2, 9, 4) && (p_ptr->depth == 0)) character_dungeon = FALSE; /* Success */ return (0); }
/* * Go to any level */ static void do_cmd_wiz_jump(void) { /* Ask for a town */ if (adult_campaign) { /* Ask for level */ if (p_ptr->command_arg <= 0) { char ppp[80]; char tmp_val[160]; /* Prompt */ sprintf(ppp, "Jump to dungeon (1-%d): ", z_info->t_max-1); /* Default */ sprintf(tmp_val, "%d", p_ptr->dungeon); /* Ask for a level */ if (!get_string(ppp, tmp_val, 10)) return; /* Extract request */ p_ptr->command_arg = atoi(tmp_val); } /* Paranoia */ if (p_ptr->command_arg < 1) p_ptr->command_arg = 1; /* Paranoia */ if (p_ptr->command_arg >= z_info->t_max) p_ptr->command_arg = z_info->t_max -1; /* Accept request */ msg_format("You jump to %s.", t_name + t_info[p_ptr->command_arg].name); /* New depth */ p_ptr->dungeon = p_ptr->command_arg; p_ptr->command_arg = 0; } /* Ask for level */ if (p_ptr->command_arg <= 0) { char ppp[80]; char tmp_val[160]; /* Prompt */ sprintf(ppp, "Jump to level (0-%d): ", max_depth(p_ptr->dungeon)-min_depth(p_ptr->dungeon)); /* Default */ sprintf(tmp_val, "%d", p_ptr->depth); /* Ask for a level */ if (!get_string(ppp, tmp_val, 10)) return; /* Extract request */ p_ptr->command_arg = atoi(tmp_val); } /* Paranoia */ if (p_ptr->command_arg < 0) p_ptr->command_arg = 0; /* Paranoia */ if (p_ptr->command_arg > max_depth(p_ptr->dungeon)-min_depth(p_ptr->dungeon)) p_ptr->command_arg = max_depth(p_ptr->dungeon)-min_depth(p_ptr->dungeon); /* Accept request */ msg_format("You jump to dungeon level %d.", p_ptr->command_arg); /* New depth */ p_ptr->depth = p_ptr->command_arg + min_depth(p_ptr->dungeon); /* Leaving */ p_ptr->leaving = TRUE; }
/* * Attempt to Load a "savefile" * * On multi-user systems, you may only "read" a savefile if you will be * allowed to "write" it later, this prevents painful situations in which * the player loads a savefile belonging to someone else, and then is not * allowed to save his game when he quits. * * We return "TRUE" if the savefile was usable, and we set the global * flag "character_loaded" if a real, living, character was loaded. * * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. */ bool load_player(void) { int fd = -1; errr err = 0; byte vvv[4]; #ifdef VERIFY_TIMESTAMP struct stat statbuf; #endif /* VERIFY_TIMESTAMP */ cptr what = "generic"; /* Paranoia */ turn = 0; /* Paranoia */ p_ptr->is_dead = FALSE; // Set a flag to show that we are restoring a game p_ptr->restoring = TRUE; /* Allow empty savefile name */ if (!savefile[0]) return (TRUE); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) { /* Give a message */ msg_format("Savefile \"%s\" does not exist.", savefile); message_flush(); /* Allow this */ p_ptr->restoring = FALSE; return (FALSE);//// } /* Close the file */ fd_close(fd); #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (!err) { FILE *fkk; char temp[1024]; /* Extract name of lock file */ my_strcpy(temp, savefile, sizeof(temp)); my_strcat(temp, ".lok", sizeof(temp)); /* Grab permissions */ safe_setuid_grab(); /* Check for lock */ fkk = my_fopen(temp, "r"); /* Drop permissions */ safe_setuid_drop(); /* Oops, lock exists */ if (fkk) { /* Close the file */ my_fclose(fkk); /* Message */ msg_print("Savefile is currently in use."); message_flush(); /* Oops */ return (FALSE); } /* Grab permissions */ safe_setuid_grab(); /* Create a lock file */ fkk = my_fopen(temp, "w"); /* Drop permissions */ safe_setuid_drop(); /* Dump a line of info */ fprintf(fkk, "Lock file for savefile '%s'\n", savefile); /* Close the lock file */ my_fclose(fkk); } #endif /* VERIFY_SAVEFILE */ /* Okay */ if (!err) { /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = "Cannot open savefile"; } /* Process file */ if (!err) { #ifdef VERIFY_TIMESTAMP /* Grab permissions */ safe_setuid_grab(); /* Get the timestamp */ (void)fstat(fd, &statbuf); /* Drop permissions */ safe_setuid_drop(); #endif /* VERIFY_TIMESTAMP */ /* Read the first four bytes */ if (fd_read(fd, (char*)(vvv), sizeof(vvv))) err = -1; /* What */ if (err) what = "Cannot read savefile"; /* Close the file */ fd_close(fd); } /* Process file */ if (!err) { /* Extract version */ sf_major = vvv[0]; sf_minor = vvv[1]; sf_patch = vvv[2]; sf_extra = vvv[3]; /* Clear screen */ Term_clear(); if (older_than(OLD_VERSION_MAJOR, OLD_VERSION_MINOR, OLD_VERSION_PATCH)) { err = -1; what = "Savefile is too old"; } else if (!older_than(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 1)) { err = -1; what = "Savefile is from the future"; } else { /* Attempt to load */ err = rd_savefile(); /* Message (below) */ if (err) what = "Cannot parse savefile"; } } /* Paranoia */ if (!err) { /* Invalid turn */ if (!turn) err = -1; /* Message (below) */ if (err) what = "Broken savefile"; } #ifdef VERIFY_TIMESTAMP /* Verify timestamp */ if (!err && !arg_wizard) { /* Hack -- Verify the timestamp */ if (sf_when > (statbuf.st_ctime + 100) || sf_when < (statbuf.st_ctime - 100)) { /* Message */ what = "Invalid timestamp"; /* Oops */ err = -1; } } #endif /* VERIFY_TIMESTAMP */ /* Okay */ if (!err) { /* Give a conversion warning */ if ((version_major != sf_major) || (version_minor != sf_minor) || (version_patch != sf_patch)) { /* Message */ msg_format("Converted a %d.%d.%d savefile.", sf_major, sf_minor, sf_patch); message_flush(); } // if Morgoth has lost his crown... if ((&a_info[ART_MORGOTH_3])->cur_num == 1) { // lower Morgoth's protection, remove his light source, increase his will and perception (&r_info[R_IDX_MORGOTH])->pd -= 1; (&r_info[R_IDX_MORGOTH])->light = 0; (&r_info[R_IDX_MORGOTH])->wil += 5; (&r_info[R_IDX_MORGOTH])->per += 5; } /* Player is dead */ if (p_ptr->is_dead) { /* Cheat death (unless the character retired) */ if (arg_wizard) { /*heal the player*/ hp_player(100, TRUE, TRUE); /* Forget death */ p_ptr->is_dead = FALSE; /* A character was loaded */ character_loaded = TRUE; // put the character somewhere sensible p_ptr->depth = min_depth(); // Mark savefile p_ptr->noscore |= 0x0001; /* Done */ return (TRUE); } /* Forget death */ p_ptr->is_dead = FALSE; /* Count lives */ sf_lives++; /* Forget turns */ turn = 0; playerturn = 0; /* A dead character was loaded */ character_loaded_dead = TRUE;//// /* Done */ return (TRUE); } /* A character was loaded */ character_loaded = TRUE; /* Still alive */ if (p_ptr->chp >= 0) { /* Reset cause of death */ my_strcpy(p_ptr->died_from, "(alive and well)", sizeof (p_ptr->died_from)); } // count the artefacts seen for the player p_ptr->artefacts = artefact_count(); /* Success */ return (TRUE); } #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (TRUE) { char temp[1024]; /* Extract name of lock file */ my_strcpy(temp, savefile, sizeof(temp)); my_strcat(temp, ".lok", sizeof(temp)); /* Grab permissions */ safe_setuid_grab(); /* Remove lock */ fd_kill(temp); /* Drop permissions */ safe_setuid_drop(); } #endif /* VERIFY_SAVEFILE */ /* Message */ msg_format("Error (%s) reading %d.%d.%d savefile.", what, sf_major, sf_minor, sf_patch); message_flush(); /* Oops */ return (FALSE); }
int min_depth() { return min_depth(m_root); }
int min_depth(struct btree *root) { if(root == NULL) {return 0;} return (1 + min(min_depth(root->left), min_depth(root->right))); }