-
Notifications
You must be signed in to change notification settings - Fork 1
/
GameServer.java
151 lines (135 loc) · 4.1 KB
/
GameServer.java
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
import java.awt.Toolkit;
import java.text.DecimalFormat;
import java.io.*;
//********************************************************************
// GameServer.java @version 1.08
// Game server for the solitaire game.
// Copyright (c) 2012 Daniel R. Collins. All rights reserved.
// See the bottom of this file for any licensing information.
//********************************************************************
public class GameServer implements PlayerCallbacks {
//--------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------
// Maximal margin-of-error for given number of games:
// 1K: 3%, 10K:1%; 100K: 0.3%; 1M: 0.1% (95% confidence)
// Approx. 500 games/sec on P4 1.6Ghz
final int NUM_GAMES = 100000;
final int CRIT_MOVES = 995;
final int MAX_MOVES = 1000;
final int PROGBAR_SIZE = 50;
final boolean VIEW_GAMES = false;
final boolean SHOW_PROGBAR = true;
//--------------------------------------------------------------------------
// Fields
//--------------------------------------------------------------------------
GameState game;
ViewerInterface view;
PlayerInterface player;
//--------------------------------------------------------------------------
// Methods
//--------------------------------------------------------------------------
/**
* Run series of different game options.
*/
public void runGameSeries () {
System.out.println("Number of games: " + NUM_GAMES);
runManyGames(1, 1);
runManyGames(3, 3);
runManyGames(3, Integer.MAX_VALUE);
runManyGames(1, Integer.MAX_VALUE);
}
/**
* Run many games.
*/
public void runManyGames (int cardsDrawn, int maxPasses) {
int numWins = 0;
int progBarCount = 0;
int progBarInc = NUM_GAMES/PROGBAR_SIZE;
if (SHOW_PROGBAR) {
for (int i = 0; i < PROGBAR_SIZE; i++)
System.out.print(".");
System.out.println();
}
for (int i = 0; i < NUM_GAMES; i++) {
boolean won = runOneGame(cardsDrawn, maxPasses);
if (won) numWins++;
if (SHOW_PROGBAR) {
progBarCount++;
if (progBarCount >= progBarInc) {
progBarCount = 0;
System.out.print("=");
}
}
}
if (SHOW_PROGBAR)
System.out.println();
double percent = (double) numWins/NUM_GAMES * 100;
System.out.print("Draw " + cardsDrawn);
System.out.print(", pass " +
(maxPasses < Integer.MAX_VALUE ? maxPasses : "inf"));
DecimalFormat df = new DecimalFormat("#0.0");
System.out.println(": won " + df.format(percent) + "%");
}
/**
* Run one game; return if game won.
*/
public boolean runOneGame (int cardsDrawn, int maxPasses) {
game = new GameState(cardsDrawn, maxPasses);
game.setupNewGame();
view = new ViewerText();
try {
view.open();
}
catch (IOException exception) {
System.err.println("Error: Could not open game viewer.");
return false;
}
player = new PlayerComputer(this);
int numMoves = 0;
while (!game.isOver()) {
if (VIEW_GAMES) {
view.update(game);
// Thread.sleep(2000);
}
player.askNextMove();
numMoves++;
// Move cap warning/limit
if (numMoves > CRIT_MOVES) {
System.out.println();
view.update(game);
}
if (numMoves > MAX_MOVES) {
game.handleMoveSurrender(0, 0);
}
}
view.close();
return game.isGameWon();
}
/**
* Player view game: return scrubbed copy of game state.
*/
public GameState playerViewGame () {
GameState scrubCopy = new GameState(game);
scrubCopy.scrubHiddenData();
return scrubCopy;
}
/**
* Player move callback: delegate to game object.
*/
public boolean playerMoveCall (int p1, int p2, int p3) {
boolean retval = game.playerMoveCall(p1, p2, p3);
if (!retval) {
System.err.println("Warning: Rejected move call.");
}
return retval;
}
/**
* Main method.
*/
public static void main (String[] args) {
GameServer server = new GameServer();
server.runGameSeries();
Toolkit.getDefaultToolkit().beep();
}
}