File size: 3,381 Bytes
15f353f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env node
/**
 * Convert TGN files to move sequences (JSON format)
 *
 * Output format for C++ consumption:
 * {
 *   "boardShape": { "x": 5, "y": 5, "z": 1 },
 *   "moves": [
 *     { "x": 1, "y": 2, "z": 0, "player": 1 },  // BLACK = 1
 *     { "x": 2, "y": 2, "z": 0, "player": 2 },  // WHITE = 2
 *     null,  // pass move
 *     ...
 *   ]
 * }
 */

import { TrigoGame, StoneType, StepType } from "@inc/trigo/game.js";
import { calculateTerritory } from "@inc/trigo/gameUtils.js";
import { initializeParsers } from "@inc/trigo/parserInit.js";
import * as fs from "fs";
import * as path from "path";


interface MoveSequenceOutput {
	tgnFile: string;
	boardShape: { x: number; y: number; z: number };
	moves: Array<{ x: number; y: number; z: number; player: number } | null>;
	finalBoard: number[][][];
	territory: {
		black: number;
		white: number;
		neutral: number;
	};
	error?: string;
}


function convertTgnToMoveSequence(tgnFilePath: string): MoveSequenceOutput {
	try {
		const tgnContent = fs.readFileSync(tgnFilePath, "utf-8");

		// Parse TGN
		const game = TrigoGame.fromTGN(tgnContent);

		const shape = game.getShape();
		const history = game.getHistory();

		// Convert steps to simple move format
		const moveSequence = history
			.filter(step => step.type === StepType.DROP || step.type === StepType.PASS)
			.map(step => {
				if (step.type === StepType.PASS) {
					return null;  // Pass move
				}

				if (step.type === StepType.DROP && step.position) {
					return {
						x: step.position.x,
						y: step.position.y,
						z: step.position.z,
						player: step.player === StoneType.BLACK ? 1 : 2  // BLACK = 1, WHITE = 2
					};
				}

				return null;
			});

		// Get final board state and territory
		const board = game.getBoard();
		const territory = calculateTerritory(board, shape);

		return {
			tgnFile: path.basename(tgnFilePath),
			boardShape: shape,
			moves: moveSequence,
			finalBoard: board,
			territory: {
				black: territory.black,
				white: territory.white,
				neutral: territory.neutral
			}
		};
	} catch (error) {
		return {
			tgnFile: path.basename(tgnFilePath),
			boardShape: { x: 0, y: 0, z: 0 },
			moves: [],
			finalBoard: [],
			territory: { black: 0, white: 0, neutral: 0 },
			error: error instanceof Error ? error.message : String(error)
		};
	}
}


function main() {
	const args = process.argv.slice(2);

	if (args.length === 0) {
		console.error("Usage: tgnToMoveSequence.ts <tgn_file> [<tgn_file> ...]");
		console.error("");
		console.error("Converts TGN files to move sequences for C++ validation.");
		console.error("Outputs JSON to stdout.");
		process.exit(1);
	}

	// Initialize parsers first
	initializeParsers().then(() => {
		const results: MoveSequenceOutput[] = [];

		for (const tgnFile of args) {
			if (!fs.existsSync(tgnFile)) {
				console.error(`File not found: ${tgnFile}`);
				results.push({
					tgnFile: path.basename(tgnFile),
					boardShape: { x: 0, y: 0, z: 0 },
					moves: [],
					finalBoard: [],
					territory: { black: 0, white: 0, neutral: 0 },
					error: "File not found"
				});
				continue;
			}

			const result = convertTgnToMoveSequence(tgnFile);
			results.push(result);
		}

		// Output as JSON
		console.log(JSON.stringify(results, null, 2));
	}).catch(error => {
		console.error("Error initializing parsers:", error);
		process.exit(1);
	});
}


main();