forked from plutoscarab/Rails
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Strategy.cs
185 lines (160 loc) · 4.46 KB
/
Strategy.cs
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Strategy.cs
/*
* This class stores the sequence of instructs for a computer player to carry out.
* The actual strategy logic is in Game.cs--this class just stores the result.
*
*/
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
namespace Rails
{
// one step in the series of instructions
[Serializable]
public class Step
{
public bool PickUp; // or deliver
public int Contract; // which contract
public int Source; // and where to get the commodity (-1 = already on-board)
// read the step from the game save file
public Step(BinaryReader reader)
{
int version = reader.ReadInt32();
PickUp = reader.ReadBoolean();
Contract = reader.ReadInt32();
Source = reader.ReadInt32();
}
// write the step to the game save file
public void Save(BinaryWriter writer)
{
writer.Write((int) 0);
writer.Write(PickUp);
writer.Write(Contract);
writer.Write(Source);
}
// create a "pick up" step
public Step(int contract, int source)
{
PickUp = true;
Contract = contract;
Source = source;
}
// create a "deliver" step
public Step(int contract)
{
PickUp = false;
Contract = contract;
Source = int.MinValue;
}
}
[Serializable]
public class Strategy
{
public ArrayList Steps; // the list of steps in the instructions
public double PayoffRate; // the rate of income, which is (payoff - cost) / time
public bool Reconsider;
// read the steps from the game save file
public Strategy(BinaryReader reader)
{
int version = reader.ReadInt32();
int count = reader.ReadInt32();
Steps = new ArrayList(count);
for (int i=0; i<count; i++)
Steps.Add(new Step(reader));
PayoffRate = reader.ReadDouble();
if (version >= 1)
Reconsider = reader.ReadBoolean();
else
Reconsider = true;
}
// write the steps to the game save file
public void Save(BinaryWriter writer)
{
writer.Write((int) 1);
writer.Write(Steps.Count);
foreach (Step step in Steps)
step.Save(writer);
writer.Write(PayoffRate);
writer.Write(Reconsider);
}
// create a new, blank list
public Strategy()
{
Steps = new ArrayList();
}
// add a step to the list
public void AddStep(Step step)
{
Steps.Add(step);
}
// create and add a pickup step
public void AddStep(int contract, int source)
{
Steps.Add(new Step(contract, source));
}
// create and add a delivery step
public void AddStep(int contract)
{
Steps.Add(new Step(contract));
}
// given two contracts and two commodity sources, generate all the different orders that
// the steps could be performed, with pickups coming before deliveries
public static Strategy[] CreateCombos(Options options, int contract1, int source1, int contract2, int source2)
{
ArrayList combos = new ArrayList();
Strategy s;
// evaluate earliest-delivery combos first in case of ties
if (options.GroupedContracts || (contract2 < Player.NumContracts - 2))
{
s = new Strategy();
s.AddStep(contract1, source1);
s.AddStep(contract1);
s.AddStep(contract2, source2);
s.AddStep(contract2);
combos.Add(s);
}
if (options.GroupedContracts || (contract1 < Player.NumContracts - 2))
{
s = new Strategy();
s.AddStep(contract2, source2);
s.AddStep(contract2);
s.AddStep(contract1, source1);
s.AddStep(contract1);
combos.Add(s);
}
// and then evaluate the earliest-picked combos
if (options.GroupedContracts || (contract2 < Player.NumContracts - 2))
{
s = new Strategy();
s.AddStep(contract1, source1);
s.AddStep(contract2, source2);
s.AddStep(contract1);
s.AddStep(contract2);
combos.Add(s);
s = new Strategy();
s.AddStep(contract2, source2);
s.AddStep(contract1, source1);
s.AddStep(contract1);
s.AddStep(contract2);
combos.Add(s);
}
if (options.GroupedContracts || (contract1 < Player.NumContracts - 2))
{
s = new Strategy();
s.AddStep(contract1, source1);
s.AddStep(contract2, source2);
s.AddStep(contract2);
s.AddStep(contract1);
combos.Add(s);
s = new Strategy();
s.AddStep(contract2, source2);
s.AddStep(contract1, source1);
s.AddStep(contract2);
s.AddStep(contract1);
combos.Add(s);
}
return (Strategy[]) combos.ToArray(typeof(Strategy));
}
}
}