home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <iostream.h>
- #include "oracle.h"
- #include "cell.h"
- #include "titillat.h"
- #include "hexmaze.h"
-
- #define TRUE -1
- #define FALSE 0
-
- typedef cell *cell_ptr;
- typedef char *char_ptr;
-
- maze::maze(int row_count,int column_count,int thickness_of_wall,char *seed)
- // Contruct a maze having "row_count" rows and "column_count" columns of
- // rooms. The walls should be "thickness_of_wall" (bricks) thick. A different
- // (8 character of less) "seed" generally yields a different maze.
- {
- struct
- {
- int row_num;
- int column_num;
- } delta [2] [6];
- int mud_filled_room_found;
- struct
- {
- int row_num;
- int column_num;
- } next;
- char wall [720] [6];
- char wall_to_check;
- char wall_num;
- char way_out;
- int x1;
- int x2;
- int y1;
- int y2;
-
- wall_thickness=thickness_of_wall;
- num_rows=row_count;
- num_y_dots=wall_thickness*(4*num_rows+1);
- y_dot_max=num_y_dots-1;
- num_columns=column_count;
- max_x=8*(num_columns/2)+6;
- num_x_dots=wall_thickness*(max_x+1);
- x_dot_max=num_x_dots-1;
- // Allocate a two dimensional array of rooms.
- if (memory_allocated=((room=new cell_ptr[num_rows]) != NULL))
- {
- int row_num=0;
- while (memory_allocated && (row_num < num_rows))
- if (memory_allocated=((room[row_num]=new cell [num_columns]) != NULL))
- row_num++;
- if (! memory_allocated)
- {
- while (row_num)
- delete [] room[--row_num];
- delete [] room;
- cerr << "Fatal error: cannot allocate maze.\n";
- }
- }
- if (memory_allocated)
- {
- // Allocate a two dimensional array for plotting the maze in
- // terms of "bricks" where a wall is "wall_thickness" bricks
- // thick.
- if (memory_allocated=((page=new char_ptr [num_y_dots]) != NULL))
- {
- int y_dot_num=0;
- while (memory_allocated && (y_dot_num < num_y_dots))
- if (memory_allocated=((page[y_dot_num]=new char [num_x_dots])
- != NULL))
- y_dot_num++;
- if (! memory_allocated)
- {
- while (y_dot_num)
- delete [] page[--y_dot_num];
- delete [] page;
- for (int row_num=num_rows-1; row_num >= 0; row_num--)
- delete [] room[row_num];
- delete [] room;
- cerr << "Fatal error: cannot allocate maze.\n";
- }
- }
- else
- {
- for (int row_num=num_rows-1; row_num >= 0; row_num--)
- delete [] room[row_num];
- delete [] room;
- cerr << "Fatal error: cannot allocate maze.\n";
- }
- }
- if (memory_allocated)
- {
- // Set up the directions by which a room can be exited.
- // Directions for even columns.
- delta[0][0].row_num=-1; // north
- delta[0][0].column_num=0;
- delta[0][1].row_num=-1; // northwest
- delta[0][1].column_num=-1;
- delta[0][2].row_num=0; // southwest
- delta[0][2].column_num=-1;
- delta[0][3].row_num=1; // south
- delta[0][3].column_num=0;
- delta[0][4].row_num=0; // southeast
- delta[0][4].column_num=1;
- delta[0][5].row_num=-1; // northeast
- delta[0][5].column_num=1;
- // Directions for odd columns.
- delta[1][0].row_num=-1; // north
- delta[1][0].column_num=0;
- delta[1][1].row_num=0; // northwest
- delta[1][1].column_num=-1;
- delta[1][2].row_num=1; // southwest
- delta[1][2].column_num=-1;
- delta[1][3].row_num=1; // south
- delta[1][3].column_num=0;
- delta[1][4].row_num=1; // southeast
- delta[1][4].column_num=1;
- delta[1][5].row_num=0; // northeast
- delta[1][5].column_num=1;
- // Set up the 6! orders in which the wall of a room can be accessed.
- int order_num=0;
- for (int wall_num_1=0; wall_num_1 < 6; wall_num_1++)
- for (int wall_num_2=0; wall_num_2 < 6; wall_num_2++)
- if (wall_num_2 != wall_num_1)
- for (int wall_num_3=0; wall_num_3 < 6; wall_num_3++)
- if ((wall_num_3 != wall_num_2)
- && (wall_num_3 != wall_num_1))
- for (int wall_num_4=0; wall_num_4 < 6; wall_num_4++)
- if ((wall_num_4 != wall_num_3)
- && (wall_num_4 != wall_num_2)
- && (wall_num_4 != wall_num_1))
- for (int wall_num_5=0; wall_num_5 < 6; wall_num_5++)
- if ((wall_num_5 != wall_num_4)
- && (wall_num_5 != wall_num_3)
- && (wall_num_5 != wall_num_2)
- && (wall_num_5 != wall_num_1))
- for (int wall_num_6=0; wall_num_6 < 6; wall_num_6++)
- if ((wall_num_6 != wall_num_5)
- && (wall_num_6 != wall_num_4)
- && (wall_num_6 != wall_num_3)
- && (wall_num_6 != wall_num_2)
- && (wall_num_6 != wall_num_1))
- {
- wall[order_num][wall_num_6]='\0';
- wall[order_num][wall_num_5]='\1';
- wall[order_num][wall_num_4]='\2';
- wall[order_num][wall_num_3]='\3';
- wall[order_num][wall_num_2]='\4';
- wall[order_num][wall_num_1]='\5';
- order_num++;
- }
- titillator_ptr=new titillator;
- order_selector=new oracle(&seed[0],order_num);
- row_selector=new oracle(&seed[0],num_rows);
- column_selector=new oracle(&seed[0],num_columns);
- int finished=FALSE;
- // Generate mazes until you have one that is hard to solve.
- do
- {
- // Pick a starting room.
- first.column_num=column_selector->random_number();
- if ((first.column_num)%2)
- do
- {
- first.row_num=row_selector->random_number();
- }
- while (first.row_num == (num_rows-1));
- else
- first.row_num=row_selector->random_number();
- current.row_num=first.row_num;
- current.column_num=first.column_num;
- // Excavate the starting room.
- room[current.row_num][current.column_num].mark_floor(' ');
- // Pick the order in which the walls of the starting room will be
- // considered.
- room[current.row_num][current.column_num].set_order(
- order_selector->random_number());
- titillator_ptr->titillate();
- // Excavate rooms until there are no more to excavate.
- do
- {
- mud_filled_room_found=FALSE;
- // Find an adjacent room (not yet considered) that needs
- // excavating.
- do
- {
- wall_num=room[current.row_num][
- current.column_num].next_wall_num();
- if (wall_num < '\6')
- {
- wall_to_check=wall[room[current.row_num][
- current.column_num].order_to_check()][wall_num];
- if (room[current.row_num][
- current.column_num].wall_up(wall_to_check))
- {
- next.column_num=current.column_num
- +delta[(current.column_num)%2]
- [wall_to_check].column_num;
- if ((next.column_num >= 0)
- && (next.column_num < num_columns))
- {
- next.row_num=current.row_num
- +delta[(current.column_num)%2]
- [wall_to_check].row_num;
- if ((next.row_num >= 0)
- && ((((next.column_num)%2 == 1)
- && (next.row_num < (num_rows-1)))
- || (((next.column_num)%2 == 0)
- && (next.row_num < num_rows))))
- {
- if (room[next.row_num][
- next.column_num].mark()
- == 'M')
- mud_filled_room_found=TRUE;
- }
- }
- }
- }
- }
- while ((wall_num < '\6')
- && (! mud_filled_room_found));
- if (mud_filled_room_found)
- // an adjacent room needs excavating
- {
- // Exit the current room, knocking down a wall.
- room[current.row_num][
- current.column_num].knock_down_wall(wall_to_check);
- way_out=char(((int) wall_to_check+3)%6);
- // Enter the adjacent room, knocking down a wall.
- room[next.row_num][next.column_num].knock_down_wall(
- way_out);
- // Record how to return to the previous room.
- room[next.row_num][next.column_num].set_way_out(
- way_out);
- current.row_num=next.row_num;
- current.column_num=next.column_num;
- // Excavate the room.
- room[current.row_num][current.column_num].mark_floor(
- ' ');
- // Select the order in which the walls of the room will
- // be considered.
- room[current.row_num][current.column_num].set_order(
- order_selector->random_number());
- }
- else
- // no adjacent room needs excavating
- {
- if ((first.row_num != current.row_num)
- || (first.column_num != current.column_num))
- {
- // Go back to the room from which you entered
- // the current room.
- next.row_num=current.row_num+delta[
- (current.column_num)%2]
- [room[current.row_num]
- [current.column_num].way_back()].row_num;
- next.column_num=current.column_num+delta[
- (current.column_num)%2]
- [room[current.row_num]
- [current.column_num].way_back()].column_num;
- current.row_num=next.row_num;
- current.column_num=next.column_num;
- }
- }
- }
- while ((first.row_num != current.row_num)
- || (first.column_num != current.column_num)
- || (wall_num < '\6'));
- if (maze_okay()) // Maze is hard to solve.
- finished=TRUE;
- else // Prepare to try another maze.
- for (int row_num=0; row_num < num_rows; row_num++)
- for (int column_num=0; column_num < num_columns; column_num++)
- room[row_num][column_num].reinitialize();
- }
- while (! finished);
- // Knock down walls blocking the entrance and exit to the maze.
- room[0][0].knock_down_wall(0);
- room[num_rows-1][num_columns-1].knock_down_wall(3);
-
- delete column_selector;
- delete row_selector;
- delete order_selector;
-
- // Generate a 2D plot of the maze. Each element of "page" corresponds
- // to a possible position of a brick composing the maze. An element
- // has value 'W' if a brick is present and value ' ' otherwise. Each
- // wall is "wall_thickness" bricks thick.
- for (y1=0; y1 < num_y_dots; y1++)
- for (x1=0; x1 < num_x_dots; x1++)
- page[y1][x1]=' ';
- for (int row_num=0; row_num < num_rows; row_num++)
- {
- int half_column_num=0;
- for (int column_num=0; column_num < num_columns; column_num+=2)
- {
- if (room[row_num][column_num].wall_up('\0'))
- {
- x1=8*half_column_num+2;
- y1=4*row_num;
- x2=x1+2;
- y2=y1;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // ***
- // O O
- // O OOO
- // O O
- // OOO
- }
- half_column_num++;
- }
- half_column_num=0;
- for (column_num=0; column_num < num_columns; column_num+=2)
- {
- if (room[row_num][column_num].wall_up('\1'))
- {
- x1=8*half_column_num;
- y1=4*row_num+2;
- x2=x1+2;
- y2=y1-2;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // *OO
- // * O
- // * OOO
- // O O
- // OOO
- }
- if (room[row_num][column_num].wall_up('\5'))
- {
- x1=8*half_column_num+4;
- y1=4*row_num;
- x2=x1+2;
- y2=y1+2;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // OO*
- // O *
- // O *OO
- // O O
- // OOO
- }
- half_column_num++;
- }
- half_column_num=0;
- for (column_num=0; column_num < (num_columns-1); column_num+=2)
- {
- if (row_num != (num_rows-1))
- {
- if (room[row_num][column_num+1].wall_up('\0'))
- {
- x1=8*half_column_num+6;
- y1=4*row_num+2;
- x2=x1+2;
- y2=y1;
- draw_line_on_page(wall_thickness*x1,
- wall_thickness*y1,wall_thickness*x2,
- wall_thickness*y2);
- // OOO
- // O O
- // O ***
- // O O
- // OOO
- }
- }
- half_column_num++;
- }
- half_column_num=0;
- for (column_num=0; column_num < num_columns; column_num+=2)
- {
- if (room[row_num][column_num].wall_up('\2'))
- {
- x1=8*half_column_num;
- y1=4*row_num+2;
- x2=x1+2;
- y2=y1+2;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // OOO
- // O O
- // * OOO
- // * O
- // *OO
- }
- if (room[row_num][column_num].wall_up('\4'))
- {
- x1=8*half_column_num+4;
- y1=4*row_num+4;
- x2=x1+2;
- y2=y1-2;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // OOO
- // O O
- // O *OO
- // O *
- // OO*
- }
- half_column_num++;
- }
- }
- int half_column_num=0;
- for (int column_num=0; column_num < num_columns; column_num+=2)
- {
- if (room[num_rows-1][column_num].wall_up('\3'))
- {
- x1=8*half_column_num+2;
- y1=4*(num_rows-1)+4;
- x2=x1+2;
- y2=y1;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // OOO
- // O O
- // O OOO
- // O O
- // ***
- }
- if (column_num+1 < num_columns)
- {
- if (room[num_rows-2][column_num+1].wall_up('\3'))
- {
- x1=8*half_column_num+6;
- y1=4*(num_rows-1)+2;
- x2=x1+2;
- y2=y1;
- draw_line_on_page(wall_thickness*x1,wall_thickness*y1,
- wall_thickness*x2,wall_thickness*y2);
- // OOO
- // O O
- // O ***
- // O O
- // OOO
- }
- }
- half_column_num++;
- }
- delete titillator_ptr;
- }
- }
-
- maze::~maze()
- {
- if (memory_allocated)
- {
- // Free dynamically allocated memory.
- for (int y_dot_num=num_y_dots-1; y_dot_num >= 0; y_dot_num--)
- delete [] page[y_dot_num];
- delete [] page;
- for (int row_num=num_rows-1; row_num >= 0; row_num--)
- delete [] room[row_num];
- delete [] room;
- }
- }
-
- void maze::draw_line_on_page(
- int x1,
- int y1,
- int x2,
- int y2)
- // Draw wall (of bricks) on "page".
- {
- int error;
- int error_prime_x;
- int error_prime_y;
- int permissible_delta_x;
- int permissible_delta_y;
- int x;
- int x_diff;
- int y;
- int y_diff;
-
- error=0;
- if (x2 >= x1)
- permissible_delta_x=1;
- else
- permissible_delta_x=-1;
- if (y2 >= y1)
- permissible_delta_y=1;
- else
- permissible_delta_y=-1;
- x=x1;
- y=y1;
- x_diff=x2-x1;
- y_diff=y2-y1;
- set_point_on_page(x,y);
- while ((x != x2) || (y != y2))
- {
- error_prime_x=error+permissible_delta_x*y_diff;
- error_prime_y=error-permissible_delta_y*x_diff;
- if (abs(error_prime_x) <= abs(error_prime_y))
- {
- x+=permissible_delta_x;
- error=error_prime_x;
- }
- else
- {
- y+=permissible_delta_y;
- error=error_prime_y;
- }
- set_point_on_page(x,y);
- }
- return;
- }
-
- int maze::maze_okay()
- {
- int adjacency;
- struct
- {
- int row_num;
- int column_num;
- } delta [2] [6];
- struct
- {
- int row_num;
- int column_num;
- } next;
- int num_rooms_in_maze;
- int num_rooms_in_solution;
- int passage_found;
- struct
- {
- int row_num;
- int column_num;
- } previous;
- int result;
- struct
- {
- int row_num;
- int column_num;
- } saved;
- char wall_to_check;
- char way_out;
-
- // Set up the directions by which a room can be exited.
- // Even columns.
- delta[0][0].row_num=-1; // north
- delta[0][0].column_num=0;
- delta[0][1].row_num=-1; // northwest
- delta[0][1].column_num=-1;
- delta[0][2].row_num=0; // southwest
- delta[0][2].column_num=-1;
- delta[0][3].row_num=1; // south
- delta[0][3].column_num=0;
- delta[0][4].row_num=0; // southeast
- delta[0][4].column_num=1;
- delta[0][5].row_num=-1; // northeast
- delta[0][5].column_num=1;
- // Odd columns.
- delta[1][0].row_num=-1; // north
- delta[1][0].column_num=0;
- delta[1][1].row_num=0; // northwest
- delta[1][1].column_num=-1;
- delta[1][2].row_num=1; // southwest
- delta[1][2].column_num=-1;
- delta[1][3].row_num=1; // south
- delta[1][3].column_num=0;
- delta[1][4].row_num=1; // southeast
- delta[1][4].column_num=1;
- delta[1][5].row_num=0; // northeast
- delta[1][5].column_num=1;
- // Solve the maze.
-
- // Start at the entrance.
- current.row_num=0;
- current.column_num=0;
- // Mark the room as part of the solution.
- room[current.row_num][current.column_num].mark_floor('S');
- num_rooms_in_solution=1;
- // Prepare to consider all the walls of the room.
- room[current.row_num][current.column_num].zero_wall_to_check();
- // Try rooms until you get to the exit.
- do
- {
- // Find a passage (not yet considered) out of the current room leading
- // to a room not part of the proposed solution.
- passage_found=FALSE;
- do
- {
- wall_to_check
- =room[current.row_num][current.column_num].next_wall_num();
- if (wall_to_check < '\6')
- {
- if (! (room[current.row_num][
- current.column_num].wall_up(wall_to_check)))
- {
- next.column_num=current.column_num
- +delta[(current.column_num)%2]
- [wall_to_check].column_num;
- if ((next.column_num >= 0)
- && (next.column_num < num_columns))
- {
- next.row_num=current.row_num
- +delta[(current.column_num)%2]
- [wall_to_check].row_num;
- if ((next.row_num >= 0)
- && ((((next.column_num)%2 == 1)
- && (next.row_num < (num_rows-1)))
- || (((next.column_num)%2 == 0)
- && (next.row_num < num_rows))))
- {
- if (room[next.row_num][
- next.column_num].mark()
- == ' ')
- passage_found=TRUE;
- }
- }
- }
- }
- }
- while ((! passage_found) && (wall_to_check < '\6'));
- if (passage_found)
- // passage to room not currently part of proposed solution found
- {
- // Enter the room.
- current.row_num=next.row_num;
- current.column_num=next.column_num;
- // Record the way back to the previous room.
- way_out=char(((int) wall_to_check+3)%6);
- room[current.row_num][current.column_num].set_way_out(way_out);
- // Mark the room as part of the proposed solution.
- room[current.row_num][current.column_num].mark_floor('S');
- num_rooms_in_solution++;
- // Prepare to consider all the walls of the room.
- room[current.row_num][current.column_num].zero_wall_to_check();
- }
- else
- // dead end
- {
- // Mark current room as not part of proposed solution.
- room[current.row_num][current.column_num].mark_floor(' ');
- num_rooms_in_solution--;
- // Go back to the room from which this room was entered.
- next.row_num=current.row_num+delta[(current.column_num)%2][
- room[current.row_num][current.column_num].way_back()].row_num;
- next.column_num=current.column_num+delta[(current.column_num)%2][
- room[current.row_num][current.column_num].way_back()].column_num;
- current.row_num=next.row_num;
- current.column_num=next.column_num;
- }
- }
- while((current.row_num != num_rows-1)
- || (current.column_num != num_columns-1));
-
- // Now that the maze is solved, calculate the number of rooms in the
- // solution (or outside the maze) that are adjacent to the rooms in
- // the solution.
- adjacency=0;
- previous.row_num=-1;
- previous.column_num=0;
- current.row_num=0;
- current.column_num=0;
- do
- {
- for (wall_to_check='\0'; wall_to_check < '\6'; wall_to_check++)
- if (room[current.row_num][current.column_num].wall_up(wall_to_check))
- {
- next.column_num=current.column_num
- +delta[(current.column_num)%2]
- [wall_to_check].column_num;
- if ((next.column_num >= 0)
- && (next.column_num < num_columns))
- {
- next.row_num=current.row_num
- +delta[(current.column_num)%2]
- [wall_to_check].row_num;
- if ((next.row_num >= 0)
- && ((((next.column_num)%2 == 1)
- && (next.row_num < (num_rows-1)))
- || (((next.column_num)%2 == 0)
- && (next.row_num < num_rows))))
- {
- if (room[next.row_num][next.column_num].mark() == 'S')
- adjacency++;
- }
- else
- adjacency++;
- }
- else
- adjacency++;
- }
- else
- {
- next.column_num=current.column_num
- +delta[(current.column_num)%2]
- [wall_to_check].column_num;
- if ((next.column_num >= 0)
- && (next.column_num < num_columns))
- {
- next.row_num=current.row_num
- +delta[(current.column_num)%2]
- [wall_to_check].row_num;
- if ((next.row_num >= 0)
- && ((((next.column_num)%2 == 1)
- && (next.row_num < (num_rows-1)))
- || (((next.column_num)%2 == 0)
- && (next.row_num < num_rows))))
- {
- if ((room[next.row_num][next.column_num].mark() == 'S')
- && ((previous.row_num != next.row_num)
- || (previous.column_num != next.column_num)))
- {
- saved.row_num=next.row_num;
- saved.column_num=next.column_num;
- }
- }
- }
- }
- previous.row_num=current.row_num;
- previous.column_num=current.column_num;
- current.row_num=saved.row_num;
- current.column_num=saved.column_num;
- }
- while((current.row_num != num_rows-1)
- || (current.column_num != num_columns-1));
- for (wall_to_check='\0'; wall_to_check < '\6'; wall_to_check++)
- if (room[current.row_num][current.column_num].wall_up(wall_to_check))
- {
- next.column_num=current.column_num
- +delta[(current.column_num)%2]
- [wall_to_check].column_num;
- if ((next.column_num >= 0)
- && (next.column_num < num_columns))
- {
- next.row_num=current.row_num
- +delta[(current.column_num)%2]
- [wall_to_check].row_num;
- if ((next.row_num >= 0)
- && ((((next.column_num)%2 == 1)
- && (next.row_num < (num_rows-1)))
- || (((next.column_num)%2 == 0)
- && (next.row_num < num_rows))))
- {
- if (room[next.row_num][next.column_num].mark() == 'S')
- adjacency++;
- }
- else
- adjacency++;
- }
- else
- adjacency++;
- }
- num_rooms_in_maze=num_rows*num_columns-(num_columns/2);
-
- // The maze is hard to solve (from the outside) if more than a third of its
- // rooms are part of its solution and rooms not part of its solution tend to
- // be next to rooms in its solution.
- if ((3*num_rooms_in_solution >= num_rooms_in_maze)
- && (5*adjacency <= 11*num_rooms_in_solution))
- result=TRUE;
- else
- result=FALSE;
- return result;
- }
-
- int maze::external_to_maze(double x,double y)
- // Return TRUE if and only if a point (x,y) is external to the maze.
- {
- int result;
- int x_out;
- int x_next;
- int y_out;
- int y_next;
-
- result=FALSE;
- y_out=(int) x;
- if (y_out < 0)
- result=TRUE;
- else
- if (y_out > y_dot_max)
- result=TRUE;
- else
- {
- x_out=(int) y;
- if (x_out < 0)
- result=TRUE;
- else
- if (x_out > x_dot_max)
- result=TRUE;
- else
- // A point is external to the maze if you don't have to cross
- // a wall, the entrance, or the exit to move from the point to
- // outside the maze.
- {
- if ((x_out/wall_thickness != 3)
- && (x_out/wall_thickness != max_x-3))
- {
- x_next=x_out;
- result=TRUE;
- while((result) && (x_next >= 0))
- {
- if (page[y_out][x_next] == ' ')
- x_next--;
- else
- result=FALSE;
- }
- if (! result)
- {
- x_next=x_out;
- result=TRUE;
- while((result) && (x_next <= x_dot_max))
- {
- if (page[y_out][x_next] == ' ')
- x_next++;
- else
- result=FALSE;
- }
- }
- if (! result)
- {
- y_next=y_out;
- result=TRUE;
- while((result) && (y_next >= 0))
- {
- if (page[y_next][x_out] == ' ')
- y_next--;
- else
- result=FALSE;
- }
- }
- if (! result)
- {
- y_next=y_out;
- result=TRUE;
- while((result) && (y_next <= y_dot_max))
- {
- if (page[y_next][x_out] == ' ')
- y_next++;
- else
- result=FALSE;
- }
- }
- }
- }
- }
- return result;
- }
-
- double maze::f(double x,double y)
- // Return 5.0*wall_thickness if a point (x,y) is on a wall, 0.0 otherwise.
- {
- int x_out;
- int y_out;
- double z;
-
- y_out=(int) x;
- if (y_out < 0)
- z=0.0;
- else
- if (y_out > y_dot_max)
- z=0.0;
- else
- {
- x_out=(int) y;
- if (x_out < 0)
- z=0.0;
- else
- if (x_out > x_dot_max)
- z=0.0;
- else
- if (page[y_out][x_out] == 'W')
- z=1.0;
- else
- z=0.0;
- }
- return z*double(5*wall_thickness);
- }
-
- int maze::part_of_solution(double x,double y)
- // Return TRUE if and only if a point (x,y) is on a wall outlining the
- // solution to the maze.
- {
- int base_x;
- int base_x_mod_8;
- int base_y;
- int base_y_mod_4;
- int half_column_num;
- int result;
- int row_num;
- int x_out;
- int y_out;
-
- y_out=(int) x;
- if (y_out < 0)
- result=FALSE;
- else
- if (y_out > y_dot_max)
- result=FALSE;
- else
- {
- x_out=(int) y;
- if (x_out < 0)
- result=FALSE;
- else
- if (x_out > x_dot_max)
- result=FALSE;
- else
- if (page[y_out][x_out] == 'W')
- {
- result=FALSE;
- base_x=x_out/wall_thickness;
- half_column_num=base_x/8;
- base_x_mod_8=base_x-8*half_column_num;
- base_y=y_out/wall_thickness;
- row_num=base_y/4;
- base_y_mod_4=base_y-4*row_num;
- switch (base_y_mod_4)
- // 000
- // 1 1
- // 2 22
- // 3 3
- // 000
- {
- case 0:
- if (base_x_mod_8 < 3)
- // *00
- // 1 1
- // 2 22
- // 3 3
- // 000
- {
- if (row_num < num_rows)
- {
- if (room[row_num][2*half_column_num].mark()
- == 'S')
- result=TRUE;
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num].mark() == 'S')
- result=TRUE;
- }
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (half_column_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num-1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- }
- else
- if (base_x_mod_8 > 3)
- // 00*
- // 1 1
- // 2 22
- // 3 3
- // 000
- {
- if (row_num < num_rows)
- {
- if (room[row_num][2*half_column_num].mark()
- == 'S')
- result=TRUE;
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num].mark() == 'S')
- result=TRUE;
- }
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (2*half_column_num+1 < num_columns)
- {
- if ((row_num-1) < (num_rows-1))
- {
- if (room[row_num-1]
- [2*half_column_num+1].mark()
- == 'S')
- result=TRUE;
- }
- }
- }
- }
- }
- else
- // 0*0
- // 1 1
- // 2 22
- // 3 3
- // 000
- {
- if (row_num < num_rows)
- {
- if (room[row_num][2*half_column_num].mark()
- == 'S')
- result=TRUE;
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num].mark() == 'S')
- result=TRUE;
- }
- }
- }
- break;
- case 1:
- if (base_x_mod_8 < 3)
- // 000
- // * 1
- // 2 22
- // 3 3
- // 000
- {
- if (room[row_num][2*half_column_num].mark() == 'S')
- result=TRUE;
- if (! result)
- {
- if (row_num > 0)
- {
- if (half_column_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num-1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- }
- else
- // 000
- // 1 *
- // 2 22
- // 3 3
- // 000
- {
- if (room[row_num][2*half_column_num].mark() == 'S')
- result=TRUE;
- if (! result)
- {
- if (row_num > 0)
- {
- if (2*half_column_num+1 < num_columns)
- {
- if (room[row_num-1]
- [2*half_column_num+1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- }
- break;
- case 2:
- if (base_x_mod_8 < 3)
- // 000
- // 1 1
- // * 22
- // 3 3
- // 000
- {
- if (room[row_num][2*half_column_num].mark() == 'S')
- result=TRUE;
- else
- {
- if (half_column_num > 0)
- {
- if (row_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num-1].mark() == 'S')
- result=TRUE;
- }
- if (! result)
- {
- if (row_num < (num_rows-1))
- {
- if (room[row_num]
- [2*half_column_num-1].mark()
- == 'S')
- result=TRUE;
- }
- }
- }
- }
- }
- else
- if (base_x_mod_8 < 7) // case 6
- // 000
- // 1 1
- // 2 *2
- // 3 3
- // 000
- {
- if (room[row_num][2*half_column_num].mark()
- == 'S')
- result=TRUE;
- if (! result)
- {
- if (row_num < num_rows-1)
- {
- if (2*half_column_num+1 < num_columns)
- {
- if (room[row_num]
- [2*half_column_num+1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (2*half_column_num+1 < num_columns)
- {
- if (room[row_num-1]
- [2*half_column_num+1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- }
- else
- // 000
- // 1 1
- // 2 2*
- // 3 3
- // 000
- {
- if (row_num < (num_rows-1))
- {
- if (room[row_num][2*half_column_num+1].mark()
- == 'S')
- result=TRUE;
- }
- if (! result)
- {
- if (row_num > 0)
- {
- if (room[row_num-1]
- [2*half_column_num+1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- break;
- default:
- if (base_x_mod_8 < 3)
- // 000
- // 1 1
- // 2 22
- // * 3
- // 000
- {
- if (room[row_num][2*half_column_num].mark()
- == 'S')
- result=TRUE;
- else
- {
- if (half_column_num > 0)
- {
- if (row_num < (num_rows-1))
- {
- if (room[row_num]
- [2*half_column_num-1].mark() == 'S')
- result=TRUE;
- }
- }
- }
- }
- else
- // 000
- // 1 1
- // 2 22
- // 3 *
- // 000
- {
- if (room[row_num][2*half_column_num].mark()
- == 'S')
- result=TRUE;
- if (! result)
- {
- if (row_num < (num_rows-1))
- {
- if (2*half_column_num+1 < num_columns)
- {
- if (room[row_num]
- [2*half_column_num+1].mark()
- == 'S')
- result=TRUE;
- }
- }
- }
- }
- break;
- }
- }
- else
- result=FALSE;
- }
- return result;
- }
-
- void maze::set_point_on_page(
- int x,
- int y)
- // Place a section of wall on "page". Each section is "wall_thickness"
- // bricks long and "wall_thickness" bricks wide.
- {
- int x_offset;
- int x_out;
- int y_offset;
- int y_out;
-
- for (x_offset=0; x_offset < wall_thickness; x_offset++)
- {
- x_out=x+x_offset;
- for (y_offset=0; y_offset < wall_thickness; y_offset++)
- {
- y_out=y+y_offset;
- page[y_out][x_out]='W';
- }
- }
- return;
- }
-