-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathpath.cc
More file actions
112 lines (93 loc) · 2.73 KB
/
path.cc
File metadata and controls
112 lines (93 loc) · 2.73 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* Package : libhex
* path.cc Created : 2007/10/11
* Author : Alex Tingle
*
* Copyright (C) 2007-2008, Alex Tingle.
*
* This file is part of the libhex application.
*
* libhex is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* libhex is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hex.h"
#include <cassert>
namespace hex {
Area
Path::to_area(void) const
{
std::set<Hex*> result;
std::copy(_hexes.begin(), _hexes.end(), std::inserter(result,result.end()));
return result;
}
size_t
Path::length(void) const
{
return _hexes.size();
}
std::string
Path::steps(void) const
{
std::string result ="";
const Hex* curr =NULL;
for(std::list<Hex*>::const_iterator h=_hexes.begin(); h!=_hexes.end(); ++h)
{
if(curr)
result += hex::steps(curr,*h);
curr = *h;
}
return result;
}
std::string
Path::str(void) const
{
assert(!this->_hexes.empty());
std::string result =this->_hexes.front()->str();
result+=":"+this->steps();
return result;
}
/** Helper: populate _hexes from steps. */
inline std::list<Hex*>
path(Hex* start, const std::string& steps)
throw(hex::out_of_range,hex::invalid_argument)
{
// See also: go(int&,int&,const std::string&)
std::list<Hex*> hexes;
hexes.push_back(start);
std::string::size_type cur =0;
while(cur<steps.size() && steps[cur]!='?')
{
// Find direction
Direction dir =to_direction( steps[cur] );
++cur;
bool repeat =(cur<steps.size() && steps[cur]=='*');
do{
Hex* next =hexes.back()->go( dir );
if(next)
hexes.push_back( next );
else if(*steps.rbegin()=='?' || repeat)
return hexes; // bail out instead of throwing
else
throw hex::out_of_range(start->str()+":"+steps);
} while(repeat);
}
return hexes;
}
Path::Path(Hex* start, const std::string& steps)
throw(hex::out_of_range,hex::invalid_argument)
: _hexes( path(start,steps) )
{}
Path::Path(Hex* from, const Hex* to) throw()
: _hexes( path(from,hex::steps(from,to)) )
{}
} // end namespace hex