main.cpp 5.76 KB
Newer Older
Sam Moore's avatar
Sam Moore committed
1
2
3
4
5
6
7
8
#include <stdlib.h>
#include <stdio.h>






9
#include "game.h"
10

11
using namespace std;
12

13
Piece::Colour SetupGame(int argc, char ** argv);
14
void DestroyGame();
15
void PrintResults(const MovementResult & result, string & buffer);
16

Sam Moore's avatar
Sam Moore committed
17
18
int main(int argc, char ** argv)
{
19
20
21
22
23
24
25
26
27
28
	


	if (argc == 1)
	{
		fprintf(stderr, "Usage: stratego [options] red blue\n");
		fprintf(stderr, "       stratego --help\n");
		exit(EXIT_SUCCESS);
		
	}
29
30
31
32
33
	

	Piece::Colour setupError = SetupGame(argc, argv);
	MovementResult result = MovementResult::OK;
	if (setupError == Piece::NONE)
34
	{
35
		result = Game::theGame->Play();
36
	}
37
38
39
40
41
42
	else
	{
		result = MovementResult::BAD_SETUP;
		Game::theGame->ForceTurn(setupError);
	}
	
43
	Game::theGame->PrintEndMessage(result);
44
45
46
47
48
49
50
51
52
53
54
55
56

	string buffer = "";
	PrintResults(result, buffer);

	//Message the AI's the quit message
	Game::theGame->red->Message("QUIT " + buffer);
	Game::theGame->blue->Message("QUIT " + buffer);

	//Log the message
	if (Game::theGame->GetLogFile() != stdout)
		Game::theGame->logMessage("%s\n", buffer.c_str());

	fprintf(stdout, "%s\n", buffer.c_str());
57
58
59
60

	exit(EXIT_SUCCESS);
	return 0;
}
61

62
Piece::Colour SetupGame(int argc, char ** argv)
63
{
64
	char * red = NULL; char * blue = NULL; double timeout = 0.00001; bool graphics = false; bool allowIllegal = false; FILE * log = NULL;
65
	Piece::Colour reveal = Piece::BOTH; char * inputFile = NULL; int maxTurns = 5000; bool printBoard = false;
66
	for (int ii=1; ii < argc; ++ii)
Sam Moore's avatar
Sam Moore committed
67
	{
68
		if (argv[ii][0] == '-')
Sam Moore's avatar
Sam Moore committed
69
		{
70
71
72
73
74
			switch (argv[ii][1])
			{
				case 't':
					if (argc - ii <= 1)
					{
75
						fprintf(stderr, "ARGUMENT_ERROR - Expected timeout value after -t switch!\n");
76
77
						exit(EXIT_FAILURE);
					}
78
79
80
81
					if (strcmp(argv[ii+1], "inf") == 0)
						timeout = -1;
					else
						timeout = atof(argv[ii+1]);
82
83
84
					++ii;
					break;
				case 'g':
85
86
87
88
					graphics = !graphics;
					break;
				case 'p':
					printBoard = !printBoard;
89
90
					break;
				case 'i':
Sam Moore's avatar
Sam Moore committed
91
					allowIllegal = true;
92
93
94
95
96
					break;

				case 'o':
					if (argc - ii <= 1)
					{
97
						fprintf(stderr, "ARGUMENT_ERROR - Expected filename or \"stdout\" after -o switch!\n");
98
99
100
101
						exit(EXIT_FAILURE);
					}
					if (log != NULL)
					{
102
						fprintf(stderr, "ARGUMENT_ERROR - Expected at most ONE -o switch!\n");
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
						exit(EXIT_FAILURE);
					}
					if (strcmp(argv[ii+1], "stdout") == 0)
						log = stdout;
					else
						log = fopen(argv[ii+1], "w");
					setbuf(log, NULL);
				
					++ii;
					break;	

				case 'r':
					if (reveal == Piece::BOTH)
						reveal = Piece::BLUE;
					else
						reveal = Piece::NONE;
					break;			
				case 'b':
					if (reveal == Piece::BOTH)
						reveal = Piece::RED;
					else
						reveal = Piece::NONE;
					break;
126
127
128
				case 'm':
					if (argc - ii <= 1)
					{
129
						fprintf(stderr, "ARGUMENT_ERROR - Expected max_turns value after -m switch!\n");
130
131
						exit(EXIT_FAILURE);
					}
132
					if (strcmp(argv[ii+1], "inf") == 0)
133
134
135
136
137
138
139
140
						maxTurns = -1;
					else
						maxTurns = atoi(argv[ii+1]);
					++ii;
					break;
				case 'f':
					if (argc - ii <= 1)
					{
141
						fprintf(stderr, "ARGUMENT_ERROR - Expected filename after -f switch!\n");
142
143
144
145
						exit(EXIT_FAILURE);
					}
					if (log != NULL)
					{
146
						fprintf(stderr, "ARGUMENT_ERROR - Expected at most ONE -f switch!\n");
147
148
149
150
151
152
153
						exit(EXIT_FAILURE);
					}
					red = (char*)("file");
					blue = (char*)("file");
					inputFile = argv[ii+1];
					++ii;
					break;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
				case 'h':
					system("clear");	
					system("less manual.txt");
					exit(EXIT_SUCCESS);
					break;
				case '-':
					if (strcmp(argv[ii]+2, "help") == 0)
					{
						system("clear");	
						system("less manual.txt");
						exit(EXIT_SUCCESS);
					}
					else
					{
168
						fprintf(stderr, "ARGUMENT_ERROR - Unrecognised switch \"%s\"...\n", argv[ii]);
169
170
171
172
						exit(EXIT_FAILURE);
					}
			}
			
Sam Moore's avatar
Sam Moore committed
173
		}
174
		else
Sam Moore's avatar
Sam Moore committed
175
		{
176
177
178
179
180
181
			if (red == NULL)
				red = argv[ii];
			else if (blue == NULL)
				blue = argv[ii];
			else
			{
182
				fprintf(stderr, "ARGUMENT_ERROR - Unexpected argument \"%s\"...\n", argv[ii]);
183
184
				exit(EXIT_FAILURE);
			}
Sam Moore's avatar
Sam Moore committed
185
186
		}
	}
187

188
189


190
	if (inputFile == NULL)
Sam Moore's avatar
Sam Moore committed
191
	{
192
193
194
195
196
		if (red == NULL || blue == NULL) //Not enough arguments
		{
			fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n");	
			exit(EXIT_FAILURE);	
		}
197
		Game::theGame = new Game(red,blue, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard);
Sam Moore's avatar
Sam Moore committed
198
	}
199
200
201
202
	else
	{
		Game::theGame = new Game(inputFile, graphics, timeout, allowIllegal,log, reveal,maxTurns, printBoard);
	}
203
204

	if (Game::theGame == NULL)
Sam Moore's avatar
Sam Moore committed
205
	{
206
207
		fprintf(stderr,"INTERNAL_ERROR - Error creating Game!\n");
		exit(EXIT_FAILURE);
Sam Moore's avatar
Sam Moore committed
208
	}
209
	atexit(DestroyGame);
210
211
212
	
	return Game::theGame->Setup(red, blue);
	
Sam Moore's avatar
Sam Moore committed
213

214
}
Sam Moore's avatar
Sam Moore committed
215

216
void PrintResults(const MovementResult & result, string & buffer)
217
{
218
219
	stringstream s("");
	switch (Game::theGame->Turn())
Sam Moore's avatar
Sam Moore committed
220
	{
221
		case Piece::RED:
222
			s << Game::theGame->red->name << " RED ";
Sam Moore's avatar
Sam Moore committed
223
			break;
224
		case Piece::BLUE:
225
			s << Game::theGame->blue->name << " BLUE ";
Sam Moore's avatar
Sam Moore committed
226
			break;
227
		case Piece::BOTH:
228
			s << "neither BOTH ";
Sam Moore's avatar
Sam Moore committed
229
			break;
230
		case Piece::NONE:
231
			s << "neither NONE ";
Sam Moore's avatar
Sam Moore committed
232
			break;
233
	}
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
	if (!Board::LegalResult(result) && result != MovementResult::BAD_SETUP)
		s << "ILLEGAL ";
	else if (!Board::HaltResult(result))
		s << "INTERNAL_ERROR ";
	else
	{
		switch (result.type)
		{
			case MovementResult::VICTORY:
				s <<  "VICTORY ";
				break;
			case MovementResult::SURRENDER:
				s << "SURRENDER ";
				break;
			case MovementResult::DRAW:
				s << "DRAW ";
				break;
			case MovementResult::DRAW_DEFAULT:
				s << "DRAW_DEFAULT ";
				break;
			case MovementResult::BAD_SETUP:
				s << "BOTH_ILLEGAL ";
				break;	
			default:
				s << "INTERNAL_ERROR ";
				break;	
		}
Sam Moore's avatar
Sam Moore committed
262
	}
263
264
265
266
267
268
	
	s << Game::theGame->TurnCount() << " " << Game::theGame->theBoard.TotalPieceValue(Piece::RED) << " " << Game::theGame->theBoard.TotalPieceValue(Piece::BLUE);

	buffer = s.str();
	

Sam Moore's avatar
Sam Moore committed
269
270
}

271
272
273
274
275
void DestroyGame()
{
	delete Game::theGame;
	Game::theGame = NULL;
}