saolsen-connect4_agent_mcts.web.val.run
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
import { agentHandler } from "https://esm.town/v/saolsen/gameplay_agent";
import {
COLS,
Connect4,
Connect4Action,
Connect4AgentResponse,
Connect4State,
} from "https://esm.town/v/saolsen/gameplay_connect4";
import { GameError, GameKind, ResultKind, StatusKind } from "https://esm.town/v/saolsen/gameplay_games";
const SIMULATIONS = 10000;
function rand_action(state: Connect4State): Connect4Action {
const player = state.active_player;
while (true) {
const column = Math.floor(Math.random() * COLS);
const action: Connect4Action = { column };
if (!(Connect4.checkAction(state, player, action) instanceof GameError)) {
return action;
}
}
}
function score_action(
current_state: Connect4State,
action: Connect4Action,
): number {
const player = current_state.active_player;
// Create a new match with the action applied.
const next_state = JSON.parse(JSON.stringify(current_state));
let status = Connect4.applyAction(next_state, player, action);
// Simulate random games from this state.
let score = 0;
for (let i = 0; i < SIMULATIONS; i++) {
const sim_state = JSON.parse(JSON.stringify(next_state));
// Play out the rest of the game randomly.
if (status instanceof GameError) {
throw status;
}
while (status.status === StatusKind.InProgress) {
const sim_action = rand_action(sim_state);
const next_status = Connect4.applyAction(
sim_state,
sim_state.active_player,
sim_action,
);
if (next_status instanceof GameError) {
throw next_status;
}
status = next_status;
}
if (status.result.kind === ResultKind.Winner) {
if (status.result.players.includes(player)) {
score += 1;
} else {
score -= 1;
}
}
}
return score / SIMULATIONS;
}
function agent(state: Connect4State): Connect4AgentResponse {
// For each action we could take, simulate multiple random games from the resulting state.
// Keep track of the number of wins for each action.
// Pick the action with the highest win rate.
let max_score = Number.MIN_VALUE;
let best_action: Connect4Action = { column: 0 };
for (let col = 0; col < COLS; col++) {
const action: Connect4Action = { column: col };
const check = Connect4.checkAction(state, state.active_player, action);
if (!(check instanceof GameError)) {
const score = score_action(state, action);
if (score > max_score) {
max_score = score;
best_action = action;
}
}
}
return { action: best_action };
}
export default agentHandler(
[
{
game: GameKind.Connect4,
agentname: "mcts",
agent: agent,
},
],
);
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
v9
April 28, 2024