main function
void
main()
Implementation
void main() async {
// 1. Setup Architecture
final transformer = TransformerDecoder(vocabSize: 4098, embedSize: 128);
final model = MuZeroModel(transformer, 128);
// 2. Initialize the Search Engine
final searchEngine = MuZeroSearch(model);
// 3. Load Weights
print("Loading weights...");
await loadModuleParameters(transformer, "muzero_chess_v1.json");
// 4. Initialize Bishop Game
final game = Game(variant: Variant.standard());
List<int> history = [0];
print("\n--- Model Play Test (Thinking Mode) ---\n");
print(game.ascii());
for (int turn = 0; turn < 50; turn++) {
// 5. Get current latent state
final rootState = model.represent(history);
// 6. Get legal move indices for masking
final legalMoves = game.generateLegalMoves();
if (legalMoves.isEmpty) {
print("Game Over: ${game.result?.readable}");
break;
}
final List<int> legalActions = legalMoves
.map((m) => encodeMove(m, game))
.toList();
// 7. THINK: Run MCTS simulations
// This uses the Dynamics head to look ahead
print("Model is thinking...");
int bestActionIdx = searchEngine.search(
rootState,
legalActions,
numSimulations: 30, // Adjust this for "deeper" thought
);
// 8. Execute the best move found by MCTS
Move? chosenMove = decodeMove(bestActionIdx, game);
if (chosenMove != null) {
String san = game.toSan(chosenMove);
game.makeMove(chosenMove);
history.add(bestActionIdx);
if (history.length > 16) history.removeAt(0);
print("Turn ${turn + 1}: Model played $san");
print(game.ascii());
print("--------------------------------");
} else {
print("Error: Search returned an invalid move index.");
break;
}
}
print("\nFinal PGN: ${game.pgn()}");
}