|
|
|
1 |
/* |
/* |
2 |
==================== |
==================== |
3 |
BlotchMaker.cc |
BlotchMaker.cc |
4 |
==================== |
==================== |
|
|
|
|
BlotchMaker works with "Map". While Map builds the map structure for the game, |
|
|
BltochMaker fills it all out with terrain. |
|
|
|
|
|
To use Blotchmaker, first create a map object, then a Blotchmaker object. Use the main |
|
|
blotchmaking function. It will automagically interact with the map object and create a map on it. |
|
5 |
*/ |
*/ |
6 |
|
|
7 |
|
|
100 |
} |
} |
101 |
|
|
102 |
// other vars |
// other vars |
103 |
hbsize = 5; |
hbsize = 2; // makes a 5x5 map |
104 |
hbplacement = 0; |
hbplacement = 0; |
105 |
|
num_players = 0; |
106 |
// need at least two to play: |
// need at least two to play: |
107 |
hbtypes[0] = BLUE; |
SetAxisPalette(6,7,8,9); |
|
hbtypes[1] = GREEN; |
|
|
//hbtypes[2] = YELLOW; // FIXME |
|
|
//hbtypes[3] = RED; // FIXME |
|
108 |
|
|
109 |
map_init = EMPTY; |
map_init = EMPTY; |
110 |
|
|
171 |
attempts++; |
attempts++; |
172 |
} |
} |
173 |
|
|
174 |
while( (VerifyMap() == 0) && (attempts < 10) ); // timeout after 10 tries |
while( (VerifyMap() == 0) && (attempts < 5) ); // timeout after 10 tries |
|
|
|
175 |
|
|
176 |
// if we tried the best we could and still couldn't make a decent map: |
// if we tried the best we could and still couldn't make a decent map: |
177 |
// NOTE: in the future if path-cutting is implemented, this is where you would plug it in |
// NOTE: in the future if path-cutting is implemented, this is where you would plug it in |
178 |
if(attempts >= 10) { |
if(attempts >= 5) { |
179 |
if (verbose) {cout << "Bad Map - Try Again - Attempts: " << attempts << "\n" ;} |
cout << "Bad Map - Try Again - Attempts: " << attempts << "\n" ; |
180 |
return 0; |
return 0; |
181 |
} |
} |
182 |
else { |
else { |
183 |
if (verbose) {cout << "Yeah! Good Map!- Attempts: " << attempts << "\n" ;} |
cout << "Yeah! Good Map!- Attempts: " << attempts << "\n" ; |
184 |
return 1; // produced a good map |
return 1; // produced a good map |
185 |
} |
} |
186 |
|
|
756 |
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
757 |
|
|
758 |
void Blotchmaker::CreateHBs(){ |
void Blotchmaker::CreateHBs(){ |
|
// just fill in the corners for now: |
|
759 |
|
|
760 |
// #1 |
// in the future, we'll think of a more clever way to randomly |
761 |
if (hbtypes[0] != EMPTY) { |
// place these guys, but for now, just put them in pre-arranged configurations |
762 |
for (short int a = 0; a <= hbsize-1; a++) { |
|
763 |
for (short int b = 0; b <= hbsize-1; b++) { |
|
764 |
map->SetObst(a,b, hbtypes[0]); |
|
765 |
} |
// map border offset from hb center point |
766 |
} |
int offset = hbsize + 1; |
767 |
} |
|
768 |
// #2 |
// if two players: |
769 |
if (hbtypes[2] != EMPTY) { |
if (num_players == 2) { |
770 |
for (short int a = 0; a <= hbsize-1; a++) { |
// lower left |
771 |
for (short int b = map_rows - hbsize; b <= map_rows-1; b++) { |
hb_locs[0].x = 0 + offset; |
772 |
map->SetObst(a,b, hbtypes[2]); |
hb_locs[0].y = 0 + offset - 1; |
773 |
} |
// upper right |
774 |
} |
hb_locs[1].x = map_cols - offset; |
775 |
} |
hb_locs[1].y = map_rows - offset; |
776 |
// #3 |
} |
777 |
if (hbtypes[1] != EMPTY) { |
// if 3 players |
778 |
for (short int a = map_cols - hbsize; a <= map_cols-1; a++) { |
if (num_players == 3) { |
779 |
for (short int b = 0; b <= hbsize-1; b++) { |
// upper left |
780 |
map->SetObst(a,b, hbtypes[1]); |
hb_locs[0].x = 0 + offset; |
781 |
} |
hb_locs[0].y = map_rows - offset; |
782 |
} |
// upper right |
783 |
} |
hb_locs[1].x = map_cols - offset; |
784 |
// #4 |
hb_locs[1].y = map_rows - offset; |
785 |
if (hbtypes[3] != EMPTY) { |
// bottom side |
786 |
for (short int a = map_cols - hbsize; a <= map_cols-1; a++) { |
hb_locs[2].x = int(map_cols / 2); |
787 |
for (short int b = map_rows - hbsize; b <= map_rows-1; b++) { |
hb_locs[2].y = 0 + offset - 1; |
788 |
map->SetObst(a,b, hbtypes[3]); |
} |
789 |
|
// if 4 players |
790 |
|
if (num_players == 4) { |
791 |
|
// lower left |
792 |
|
hb_locs[0].x = 0 + offset; |
793 |
|
hb_locs[0].y = 0 + offset - 1; |
794 |
|
// upper right |
795 |
|
hb_locs[1].x = map_cols - offset; |
796 |
|
hb_locs[1].y = map_rows - offset; |
797 |
|
// lower right |
798 |
|
hb_locs[2].x = map_cols - offset; |
799 |
|
hb_locs[2].y = 0 + offset - 1; |
800 |
|
// upper left |
801 |
|
hb_locs[3].x = 0 + offset; |
802 |
|
hb_locs[3].y = map_rows - offset; |
803 |
|
} |
804 |
|
|
805 |
|
// now fill them in |
806 |
|
for (int x = 0; x < num_players; x++) { // foreach HB |
807 |
|
for (short int a = (hb_locs[x].x - hbsize); a <= (hb_locs[x].x + hbsize); a++) { |
808 |
|
for (short int b = (hb_locs[x].y - hbsize); b <= (hb_locs[x].y + hbsize); b++) { |
809 |
|
map->SetObst(a,b, hbtypes[x]); |
810 |
} |
} |
811 |
} |
} |
812 |
} |
} |
|
|
|
813 |
} |
} |
814 |
|
|
815 |
|
|
817 |
|
|
818 |
|
|
819 |
bool Blotchmaker::VerifyMap(){ |
bool Blotchmaker::VerifyMap(){ |
|
|
|
820 |
// Checks to make sure HBs are accessable by eachother. no blocking obstacles. |
// Checks to make sure HBs are accessable by eachother. no blocking obstacles. |
821 |
// returns 1 if success, zero if failed |
// returns 1 if success, zero if failed |
822 |
|
|
825 |
// if you are playing a 2player game, it will still check all four corners! |
// if you are playing a 2player game, it will still check all four corners! |
826 |
|
|
827 |
|
|
828 |
// list of corners to check through |
//pointer to the search |
829 |
pos coords[4] = { |
AStarSearch<MapSearchNode>* astarsearch; |
830 |
{0,0}, |
|
831 |
{0,map_rows-1}, |
//cout << "Begin Map Verification:\n"; |
|
{map_cols-1,0}, |
|
|
{map_cols-1,map_rows-1} |
|
|
}; |
|
832 |
|
|
833 |
// foreach corner position |
// foreach corner position |
834 |
for (short int here = 0; here < 4; here++) { |
int no_dbl_offset = 1; // so we don't check the same routes twice in the loops |
835 |
for (short int there = 0; there < 4; there++) { |
for (short int here = 0; here < num_players; here++) { |
836 |
|
for (short int there = no_dbl_offset; there < num_players; there++) { |
837 |
|
|
838 |
if (here == there) {continue;} //skip if finding path to self |
if (here == there) {continue;} //skip if finding path to self |
839 |
|
|
840 |
if (verbose) {cout << "Now Checking: (" << coords[here].x << ',' << coords[here].y << ") to (" << coords[there].x << ',' << coords[there].y << ") \n";} |
//cout << " Now Checking: (" << hb_locs[here].x << ',' << hb_locs[here].y << ") to (" << hb_locs[there].x << ',' << hb_locs[there].y << ") \n"; |
841 |
|
|
842 |
// Create an instance of the search class... |
// Create an instance of the search class... |
843 |
AStarSearch<MapSearchNode> astarsearch; |
astarsearch = new AStarSearch<MapSearchNode>; |
844 |
|
|
845 |
// set the pointer to the map |
// set the pointer to the map |
846 |
MapSearchNode::SetMapPointer(*map); |
MapSearchNode::SetMapPointer(*map); |
847 |
|
|
|
// Create a start state |
|
|
MapSearchNode nodeStart(coords[here].x, coords[here].y); |
|
848 |
|
|
849 |
// Define the goal state |
// Create and set start/goal states |
850 |
MapSearchNode nodeEnd(coords[there].x, coords[there].y); |
MapSearchNode nodeStart(hb_locs[here].x, hb_locs[here].y); |
851 |
|
MapSearchNode nodeEnd(hb_locs[there].x, hb_locs[there].y); |
852 |
|
astarsearch->SetStartAndGoalStates( nodeStart, nodeEnd ); |
853 |
|
|
854 |
// Set Start and goal states |
int SearchState; |
855 |
astarsearch.SetStartAndGoalStates( nodeStart, nodeEnd ); |
int SearchSteps = 0; |
|
|
|
|
unsigned int SearchState; |
|
|
unsigned int SearchSteps = 0; |
|
856 |
|
|
857 |
do { |
do { |
858 |
SearchState = astarsearch.SearchStep(); |
SearchState = astarsearch->SearchStep(); |
859 |
SearchSteps++; |
SearchSteps++; |
860 |
|
//cout << "*"; |
861 |
} |
} |
862 |
while( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING ); |
while( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING && |
863 |
|
SearchSteps < ((map_cols + map_rows) * 2)); |
864 |
|
|
865 |
// if solution found, display: |
// if solution found, display: |
866 |
if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED ) { |
if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED ) { |
867 |
// Once you're done with the solution you can free the nodes up |
// Once you're done with the solution you can free the nodes up |
868 |
astarsearch.FreeSolutionNodes(); |
astarsearch->FreeSolutionNodes(); |
869 |
if (verbose) {cout << "Succeeded\n";} |
//cout << "Succeeded\n"; |
870 |
} |
} |
871 |
// otherwise, kill and return 0 |
// otherwise, kill and return 0 |
872 |
else if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_FAILED ) { |
else if( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_FAILED ) { |
873 |
if (verbose) {cout << "Failed. " << SearchSteps << " steps searched on this route\n";} |
//cout << "Failed. " << SearchSteps << " steps searched on this route\n"; |
874 |
|
delete astarsearch; |
875 |
return 0; |
return 0; |
876 |
} |
} |
877 |
|
delete astarsearch; |
|
|
|
878 |
} |
} |
879 |
|
no_dbl_offset++; |
880 |
} |
} |
881 |
|
|
882 |
|
//cout << "End Map Verification:\n"; |
883 |
|
|
884 |
return 1; |
return 1; |
885 |
} |
} |
886 |
|
|
901 |
|
|
902 |
|
|
903 |
// loads the axis colors to place on the map |
// loads the axis colors to place on the map |
904 |
void Blotchmaker::SetAxisPalette(short int a, |
void Blotchmaker::SetAxisPalette(short int a, short int b, short int c, short int d, short int e, short int f, short int g, short int h) { |
905 |
short int b, |
num_players = 0; // in case of do-overs and such, don't just keep adding :-) |
906 |
short int c, |
|
|
short int d, |
|
|
short int e, |
|
|
short int f, |
|
|
short int g, |
|
|
short int h) { |
|
907 |
hbtypes[0] = obstacle(a); |
hbtypes[0] = obstacle(a); |
908 |
hbtypes[1] = obstacle(b); |
hbtypes[1] = obstacle(b); |
909 |
hbtypes[2] = obstacle(c); |
hbtypes[2] = obstacle(c); |
912 |
hbtypes[5] = obstacle(f); |
hbtypes[5] = obstacle(f); |
913 |
hbtypes[6] = obstacle(g); |
hbtypes[6] = obstacle(g); |
914 |
hbtypes[7] = obstacle(h); |
hbtypes[7] = obstacle(h); |
915 |
|
|
916 |
|
// count them up |
917 |
|
if (a != 0) { num_players++; } |
918 |
|
if (b != 0) { num_players++; } |
919 |
|
if (c != 0) { num_players++; } |
920 |
|
if (d != 0) { num_players++; } |
921 |
|
if (e != 0) { num_players++; } |
922 |
|
if (f != 0) { num_players++; } |
923 |
|
if (g != 0) { num_players++; } |
924 |
|
if (h != 0) { num_players++; } |
925 |
} |
} |
926 |
|
|
927 |
|
|