1 //
2 // This file is part of Gambit
3 // Copyright (c) 1994-2016, The Gambit Project (http://www.gambit-project.org)
4 //
5 // FILE: src/tools/enumpoly/sfstrat.cc
6 // Implementation of sequence form strategy classes
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 //
22
23 #include "sfstrat.h"
24 #include "sfg.h"
25
26 //--------------------------------------
27 // Sequence: Member functions
28 //--------------------------------------
29
History(void) const30 Gambit::List<Gambit::GameAction> Sequence::History(void) const
31 {
32 Gambit::List<Gambit::GameAction> h;
33 Gambit::GameAction a = action;
34 const Sequence * s = (this);
35 while(a) {
36 h.Append(a);
37 s = s->parent;
38 a = s->GetAction();
39 }
40 return h;
41 }
42
43
44 //--------------------------------------
45 // SFSequenceSet: Member functions
46 //--------------------------------------
47
SFSequenceSet(const Gambit::GamePlayer & p)48 SFSequenceSet::SFSequenceSet(const Gambit::GamePlayer &p)
49 : efp(p), sequences()
50 {
51 Sequence *empty;
52 empty = new Sequence(p,0,0,1);
53 AddSequence(empty);
54 }
55
SFSequenceSet(const SFSequenceSet & s)56 SFSequenceSet::SFSequenceSet(const SFSequenceSet &s)
57 : efp(s.efp), sequences(s.sequences)
58 { }
59
~SFSequenceSet()60 SFSequenceSet::~SFSequenceSet()
61 {
62
63 // potential problem here? It is not clear this is where this belongs.
64 // What if there are multiple SFSequenceSets pointing to
65 // the same sequences?
66
67 for(int i=1;i<=sequences.Length();i++)
68 delete sequences[i];
69 }
70
operator =(const SFSequenceSet & s)71 SFSequenceSet &SFSequenceSet::operator=(const SFSequenceSet &s)
72 {
73 if (this != &s) {
74 efp = s.efp;
75 sequences = s.sequences;
76 }
77 return *this;
78 }
79
80
operator ==(const SFSequenceSet & s)81 bool SFSequenceSet::operator==(const SFSequenceSet &s)
82 {
83 if (sequences.Length() != s.sequences.Length()) return (false);
84 int i;
85 for (i = 1; i <= sequences. Length()
86 && sequences[i] == s.sequences[i]; i++);
87 if (i > sequences.Length()) return (true);
88 else return (false);
89 }
90
91 //------------------------------------------
92 // SFSequenceSet: Member functions
93 //------------------------------------------
94
95 // Append a sequences to the SFSequenceSet
AddSequence(Sequence * s)96 void SFSequenceSet::AddSequence(Sequence *s)
97 {
98 if (efp != s->Player()) {
99 throw Gambit::MismatchException();
100 }
101 sequences.Append(s);
102 }
103
104 // Removes a sequence pointer. Returns true if the sequence was successfully
105 // removed, false otherwise.
RemoveSequence(Sequence * s)106 bool SFSequenceSet::RemoveSequence( Sequence *s )
107 {
108 if (efp != s->Player()) {
109 throw Gambit::MismatchException();
110 }
111 int t;
112 t = sequences.Find(s);
113 if (t>0) sequences.Remove(t);
114 return (t>0);
115 }
116
117 // Finds the sequence pointer of sequence number j. Returns 0 if there
118 // is no sequence with that number.
Find(int j)119 Sequence *SFSequenceSet::Find( int j )
120 {
121 int t=1;
122 while(t <= sequences.Length()) {
123 if(sequences[t]->GetNumber() == j) return sequences[t];
124 t++;
125 }
126 return 0;
127 }
128
129 // Number of Sequences in a SFSequenceSet
NumSequences(void) const130 int SFSequenceSet::NumSequences(void) const
131 {
132 return (sequences.Length());
133 }
134
135 // Return the entire sequence set
GetSFSequenceSet(void) const136 const Gambit::Array<Sequence *> &SFSequenceSet::GetSFSequenceSet(void) const
137 {
138 return sequences;
139 }
140
141 //-----------------------------------------------
142 // SFSupport: Ctors, Dtor, Operators
143 //-----------------------------------------------
144
SFSupport(const Sfg & SF)145 SFSupport::SFSupport(const Sfg &SF) : bsfg(&SF), sups(SF.GetEfg()->NumPlayers())
146 {
147 for (int i = 1; i <= sups.Length(); i++)
148 sups[i] = new SFSequenceSet(SF.GetEfg()->GetPlayer(i));
149 }
150
SFSupport(const SFSupport & s)151 SFSupport::SFSupport(const SFSupport &s)
152 : bsfg(s.bsfg), sups(s.sups.Length())
153 {
154 for (int i = 1; i <= sups.Length(); i++)
155 sups[i] = new SFSequenceSet(*s.sups[i]);
156 }
157
~SFSupport()158 SFSupport::~SFSupport()
159 {
160 for (int i = 1; i <= sups.Length(); i++)
161 delete sups[i];
162 }
163
operator =(const SFSupport & s)164 SFSupport &SFSupport::operator=(const SFSupport &s)
165 {
166 if (this != &s && bsfg == s.bsfg) {
167 for (int i = 1; i <= sups.Length(); i++) {
168 delete sups[i];
169 sups[i] = new SFSequenceSet(*s.sups[i]);
170 }
171 }
172 return *this;
173 }
174
operator ==(const SFSupport & s) const175 bool SFSupport::operator==(const SFSupport &s) const
176 {
177 int i;
178 for (i = 1; i <= sups.Length() && *sups[i] == *s.sups[i]; i++);
179 return i > sups.Length();
180 }
181
operator !=(const SFSupport & s) const182 bool SFSupport::operator!=(const SFSupport &s) const
183 {
184 return !(*this == s);
185 }
186
187 //------------------------
188 // SFSupport: Members
189 //------------------------
190
Sequences(int pl) const191 const Gambit::Array<Sequence *> &SFSupport::Sequences(int pl) const
192 {
193 return (sups[pl]->GetSFSequenceSet());
194 }
195
NumSequences(int pl) const196 int SFSupport::NumSequences(int pl) const
197 {
198 return sups[pl]->NumSequences();
199 }
200
NumSequences(void) const201 const Gambit::Array<int> SFSupport::NumSequences(void) const
202 {
203 Gambit::Array<int> a(sups.Length());
204
205 for (int i = 1 ; i <= a.Length(); i++)
206 a[i] = sups[i]->NumSequences();
207 return a;
208 }
209
TotalNumSequences(void) const210 int SFSupport::TotalNumSequences(void) const
211 {
212 int total = 0;
213 for (int i = 1 ; i <= sups.Length(); i++)
214 total += sups[i]->NumSequences();
215 return total;
216 }
217
Find(Sequence * s) const218 int SFSupport::Find(Sequence *s) const
219 {
220 return sups[s->Player()->GetNumber()]->GetSFSequenceSet().Find(s);
221 }
222
AddSequence(Sequence * s)223 void SFSupport::AddSequence(Sequence *s)
224 {
225 sups[s->Player()->GetNumber()]->AddSequence(s);
226 }
227
RemoveSequence(Sequence * s)228 bool SFSupport::RemoveSequence(Sequence *s)
229 {
230 return sups[s->Player()->GetNumber()]->RemoveSequence(s);
231 }
232
233
234 // Returns true if all sequences in _THIS_ belong to _S_
IsSubset(const SFSupport & s) const235 bool SFSupport::IsSubset(const SFSupport &s) const
236 {
237 for (int i = 1; i <= sups.Length(); i++)
238 if (NumSequences(i) > s.NumSequences(i))
239 return false;
240 else {
241 const Gambit::Array<Sequence *> &strats =
242 sups[i]->GetSFSequenceSet();
243
244 for (int j = 1; j <= NumSequences(i); j++)
245 if (!s.sups[i]->GetSFSequenceSet().Find(strats[j]))
246 return false;
247 }
248 return true;
249 }
250
251
252
253
254