-
Notifications
You must be signed in to change notification settings - Fork 1
/
driver.xc
129 lines (123 loc) · 4.35 KB
/
driver.xc
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
#include <state.xh>
#include <driver.xh>
#include <stdbool.h>
#include <assert.h>
TurnInfo nextTurn(TurnInfo turn, unsigned numPlayers, _Bool redeal, _Bool newDeck) {
if (redeal) {
if (newDeck) {
turn.dealer = (turn.dealer + 1) % numPlayers;
turn.handNum = 0;
} else {
turn.handNum++;
}
turn.startingPlayer = (turn.dealer + turn.handNum + 1) % numPlayers;
turn.player = turn.startingPlayer;
turn.turnNum = 0;
} else {
turn.player = (turn.player + 1) % numPlayers;
turn.turnNum++;
}
return turn;
}
PlayerId playGame(
unsigned numPlayers, bool partners, bool openHands, Player players[numPlayers],
closure<(PlayerId) -> void> updateTurn,
closure<(PlayerId, Hand) -> void> updateHand,
closure<(State) -> void> updateState,
closure<(PlayerId, unsigned) -> void> handleDeal,
closure<(PlayerId, Action) -> void> handleAction,
closure<(PlayerId) -> void> handleWin) {
if (numPlayers < 1 || numPlayers > MAX_PLAYERS || partners && numPlayers % 2 != 0) {
fprintf(stderr, "Invalid number of players %d\n", numPlayers);
exit(1);
}
State s = initialState(numPlayers, partners);
Hand deck = {0}, discard = {0};
Hand hands[numPlayers];
TurnInfo turn = {1 % numPlayers, 0, 0, 1 % numPlayers, 0};
initializeDeck(deck);
deal(MIN_HAND, MAX_HAND, deck, numPlayers, hands);
handleDeal(turn.dealer, turn.handNum);
for (PlayerId p = 0; p < numPlayers; p++) {
updateHand(p, hands[p]);
}
while (!isWon(s)) {
updateState(s);
updateTurn(turn.player);
vector<Action> actions = getActions(s, turn.player, hands[turn.player]);
Player p = players[turn.player];
unsigned handSizes[numPlayers];
for (PlayerId p = 0; p < numPlayers; p++) {
handSizes[p] = getDeckSize(hands[p]);
}
unsigned actionNum = p.getAction(
s,
hands[turn.player],
openHands? hands : NULL,
discard, handSizes, turn, actions);
assert(actionNum < actions.size);
Action a = actions[actionNum];
handleAction(turn.player, a);
for (PlayerId p = 0; p < numPlayers; p++) {
players[p].notifyAction(s, turn, a);
}
s = applyAction(a, s, hands[turn.player], discard);
updateHand(turn.player, hands[turn.player]);
handSizes[turn.player]--;
bool redeal = false, newDeck = false;
if (handSizes[(turn.player + 1) % numPlayers] == 0) {
redeal = true;
if (getDeckSize(deck) < numPlayers * MIN_HAND) {
newDeck = true;
memset(discard, 0, sizeof(Hand));
initializeDeck(deck);
}
deal(MIN_HAND, MAX_HAND, deck, numPlayers, hands);
for (PlayerId p = 0; p < numPlayers; p++) {
updateHand(p, hands[p]);
}
}
turn = nextTurn(turn, numPlayers, redeal, newDeck);
if (redeal) {
handleDeal(turn.dealer, turn.handNum);
}
}
PlayerId winner = getWinner(s);
updateState(s);
handleWin(winner);
return winner;
}
PlayerId playQuietGame(unsigned numPlayers, bool partners, bool openHands, Player players[numPlayers]) {
return playGame(
numPlayers, partners, openHands, players,
lambda (PlayerId p) -> void {},
lambda (PlayerId p, Hand h) -> void {},
lambda (State s) -> void {},
lambda (PlayerId p, unsigned h) -> void {},
lambda (PlayerId p, Action a) -> void {},
lambda (PlayerId p) -> void {});
}
PlayerId playConsoleGame(unsigned numPlayers, bool partners, bool openHands, Player players[numPlayers], FILE *out) {
assert(out != NULL);
return playGame(
numPlayers, partners, openHands, players,
lambda (PlayerId p) -> void {
fprintf(out, "%s %s's turn\n", players[p].name, showPlayerId(p).text);
},
lambda (PlayerId p, Hand h) -> void {},
lambda (State s) -> void { fprintf(out, "\n\n%s\n", show(s).text); },
lambda (PlayerId p, unsigned handNum) -> void {
fprintf(out, "Hand %d for dealer %s\n", handNum, showPlayerId(p).text);
},
lambda (PlayerId p, Action a) -> void {
fprintf(out, "%s: %s\n", showPlayerId(p).text,
showAction(a, p, partners? partner(numPlayers, p) : PLAYER_ID_NONE).text);
},
lambda (PlayerId p) -> void {
if (partners) {
fprintf(out, "%s and %s won!\n", showPlayerId(p).text, showPlayerId(partner(numPlayers, p)).text);
} else {
fprintf(out, "%s won!\n", showPlayerId(p).text);
}
});
}