Skip to content

Commit

Permalink
Fixed bug
Browse files Browse the repository at this point in the history
  • Loading branch information
BuggerBugs committed Jun 12, 2024
1 parent cda66ce commit b9eab97
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 36 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@
"d3": "^7.8.5",
"node-zstandard": "^1.2.4",
"proper-lockfile": "^4.1.2",
"ts-node": "10.9.2"
"ts-node": "^10.9.2"
},
"devDependencies": {
"@babel/preset-typescript": "^7.23.0",
"@types/async": "3.2.24",
"@types/d3": "^7.4.1",
"@types/jest": "^29.5.5",
"@types/lodash": "^4.14.199",
"@types/node": "18.11.18",
"@types/proper-lockfile": "4.1.4",
"@types/async": "3.2.24",
"jest": "^29.7.0",
"ts-jest": "^29.1.1"
},
"scripts": {
"build": "tsc --build",
"start": "tsc --build && node dist/src/index.js",
"start": "tsc --build && node dist/src/index.js && ts-node src/zst_decompressor.ts",
"test": "tsc --build && jest ./dist",
"scratch": "tsc --build && node dist/src/scratch.js",
"run-zst-decompressor": "tsc --build && node dist/src/zst_decompressor.js",
Expand Down
64 changes: 32 additions & 32 deletions src/metrics/captures.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ALL_SQUARES, Piece, PrettyMove, UASymbol } from '../cjsmin/chess';
import { BoardAndPieceMap, UAPMap } from '../types';
import { createBoardAndPieceMap, createBoardMap, createUAPMap } from '../utils';
import { Metric } from './metric';
import { ALL_SQUARES, Piece, PrettyMove, UASymbol } from "../cjsmin/chess";
import { BoardAndPieceMap, UAPMap } from "../types";
import { createBoardAndPieceMap, createBoardMap, createUAPMap } from "../utils";
import { Metric } from "./metric";

export class KillStreakMetric implements Metric {
killStreakMap: {
Expand Down Expand Up @@ -37,7 +37,7 @@ export class KillStreakMetric implements Metric {
}

logResults(): void {
console.log('Kill streak map', this.killStreakMap);
console.log("Kill streak map", this.killStreakMap);
console.log(`Max Kill Streak: ${this.maxKillStreak}`);
console.log(`Max Kill Streak Piece: ${this.maxKillStreakPiece}`);
console.log(`Game(s) with max kill streak(s): ${this.maxKillStreakGame}`);
Expand All @@ -55,7 +55,7 @@ export class KillStreakMetric implements Metric {
while (i < game.length) {
const move = game[i].move;
// if the move is a capture or a mate, it counts towards kill streaks
if (move.capture || move.originalString.includes('#')) {
if (move.capture || move.originalString.includes("#")) {
// streak has been reset because new piece captures
if (streakLength === 0) {
streakPiece = move.uas;
Expand Down Expand Up @@ -107,8 +107,8 @@ export class KillStreakMetric implements Metric {
) {
const gameLink = metadata
.find((item) => item.startsWith('[Site "'))
?.replace('[Site "', '')
?.replace('"]', '');
?.replace('[Site "', "")
?.replace('"]', "");

this.getMaxKillStreak(game, 0, gameLink);
this.getMaxKillStreak(game, 1, gameLink);
Expand Down Expand Up @@ -140,31 +140,31 @@ export class KDRatioMetric implements Metric {

logResults(): void {
// KDR facts
console.log('KDR FACTS (INCLUDING CHECKMATES AS KILLS):');
console.log("KDR FACTS (INCLUDING CHECKMATES AS KILLS):");
console.log(
`Piece with the highest KD ratio: ${this.pieceWithHighestKDRatio}`
);
console.log(
'Kills, deaths, and revenge kills for each unambiguous piece:'
"Kills, deaths, and revenge kills for each unambiguous piece:"
),
console.table(this.KDMap);
console.log(
'Kill Death Ratios for each unambiguous piece: ' +
"Kill Death Ratios for each unambiguous piece: " +
JSON.stringify(this.kdRatios, null, 2)
);
console.log('\n');
console.log("\n");
console.log(
'KDRs TAKING INTO ACCOUNT PIECE VALUES (Pawn 1 point, Knight 3 points, Bishop 3 points, Rook 5 points, Queen 9 points, King 4 points): '
"KDRs TAKING INTO ACCOUNT PIECE VALUES (Pawn 1 point, Knight 3 points, Bishop 3 points, Rook 5 points, Queen 9 points, King 4 points): "
);
console.log(
`Piece with the highest KD ratio (taking into account piece values): ${this.pieceWithHighestKDRatioValues}`
);
console.log(
'Kills, Deaths, and for each unambiguous piece (taking into account piece values):'
"Kills, Deaths, and for each unambiguous piece (taking into account piece values):"
),
console.table(this.KDValuesMap);
console.log(
'Kill Death Ratios for each unambiguous piece (taking into account piece values): ' +
"Kill Death Ratios for each unambiguous piece (taking into account piece values): " +
JSON.stringify(this.kdRatiosValues, null, 2)
);
}
Expand Down Expand Up @@ -193,7 +193,7 @@ export class KDRatioMetric implements Metric {

// find the piece with the highest KD ratio
let maxKDRatio = 0;
let pieceWithHighestKDRatio = null;
let pieceWithHighestKDRatio: UASymbol[] = [];

for (const uas of Object.keys(KDRatios)) {
if (KDRatios[uas] > maxKDRatio) {
Expand All @@ -209,7 +209,7 @@ export class KDRatioMetric implements Metric {

// repeat for the KDRatios taking into account piece values
let maxKDRatioValues = 0;
let pieceWithHighestKDRatioValues = null;
let pieceWithHighestKDRatioValues: UASymbol[] = [];

for (const uas of Object.keys(KDRatiosValues)) {
if (KDRatiosValues[uas] > maxKDRatioValues) {
Expand Down Expand Up @@ -264,15 +264,15 @@ export class KDRatioMetric implements Metric {
this.KDValuesMap[move.capture.uas].deaths++;

// identify kill values based on captured piece type
if (move.capture.type === 'p') {
if (move.capture.type === "p") {
this.KDValuesMap[move.uas].valueKills++;
} else if (move.capture.type === 'n' || move.capture.type === 'b') {
} else if (move.capture.type === "n" || move.capture.type === "b") {
this.KDValuesMap[move.uas].valueKills += 3;
} else if (move.capture.type === 'k') {
} else if (move.capture.type === "k") {
this.KDValuesMap[move.uas].valueKills += 4; // king's fighting value valued around 4 points in https://en.wikipedia.org/wiki/Chess_piece_relative_value
} else if (move.capture.type === 'r') {
} else if (move.capture.type === "r") {
this.KDValuesMap[move.uas].valueKills += 5;
} else if (move.capture.type === 'q') {
} else if (move.capture.type === "q") {
this.KDValuesMap[move.uas].valueKills += 9;
}

Expand All @@ -286,13 +286,13 @@ export class KDRatioMetric implements Metric {

const lastMove = game[game.length - 1].move;
// Check if the game is in checkmate after the last move
if (lastMove.originalString.includes('#')) {
if (lastMove.originalString.includes("#")) {
const unambigMatingPiece = lastMove.uas;
this.KDMap[unambigMatingPiece].kills++;
this.KDValuesMap[unambigMatingPiece].valueKills++; // king kill counts as 1 point

// only kings can get mated, and we know whose move it is
const matedKing = lastMove.color === 'w' ? 'k' : 'K';
const matedKing = lastMove.color === "w" ? "k" : "K";
this.KDMap[matedKing].deaths++;
this.KDValuesMap[matedKing].deaths++;

Expand Down Expand Up @@ -354,35 +354,35 @@ export class MateAndAssistMetric implements Metric {
metadata?: string[]
) {
// Take no action if the game didn't end in checkmate
if (!game[game.length - 1].move.originalString.includes('#')) {
if (!game[game.length - 1].move.originalString.includes("#")) {
return;
}

const lastMove = game[game.length - 1].move;

// increment the mate count of the mating piece
this.mateAndAssistMap[lastMove.uas].mates++;
if (lastMove.uas === 'k' || lastMove.uas === 'K') {
if (lastMove.uas === "k" || lastMove.uas === "K") {
console.log(
`code identified a king as having a mate (caused by discovered check). move: ${lastMove.originalString}`
);
const gameLink = metadata
.find((item) => item.startsWith('[Site "'))
?.replace('[Site "', '')
?.replace('"]', '');
?.replace('[Site "', "")
?.replace('"]', "");
console.log(`game: ${gameLink}`);
}

// increment the mated (death) count of the mated king
this.matedCounts[lastMove.color === 'w' ? 'k' : 'K']++;
this.matedCounts[lastMove.color === "w" ? "k" : "K"]++;

// The fastest possible checkmate is in 2 moves, so we do have to check for out of bounds

// Look back 2 moves to see if there was an assist
if (game.length > 2) {
const assistMove = game[game.length - 3].move;
if (
assistMove.originalString.includes('+') &&
assistMove.originalString.includes("+") &&
assistMove.uas !== lastMove.uas
) {
this.mateAndAssistMap[assistMove.uas].assists++;
Expand All @@ -392,7 +392,7 @@ export class MateAndAssistMetric implements Metric {
if (game.length > 4) {
const hockeyAssistMove = game[game.length - 5].move;
if (
hockeyAssistMove.originalString.includes('+') &&
hockeyAssistMove.originalString.includes("+") &&
assistMove.uas !== lastMove.uas
) {
this.mateAndAssistMap[hockeyAssistMove.uas].hockeyAssists++;
Expand Down Expand Up @@ -479,7 +479,7 @@ export class MatingSquareMetric implements Metric {
// checks (currently we disregard this by just saying the last piece to move is the "mating piece")
processGame(game: { move: PrettyMove; board: Piece[] }[]) {
// Take no action if the game didn't end in checkmate
if (!game[game.length - 1].move.originalString.includes('#')) {
if (!game[game.length - 1].move.originalString.includes("#")) {
return;
}

Expand Down
49 changes: 49 additions & 0 deletions src/queue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RESULTS_PATH = void 0;
var asyncLib = require("async");
var fs = require("fs");
var net = require("net");
// will just write to wherever the process is running, but the server needs to be launched from the same directory so we use an abs path
exports.RESULTS_PATH = "".concat(__dirname, "/results.json");
function launchQueueServer() {
// ensure results.json exists
if (!fs.existsSync(exports.RESULTS_PATH)) {
fs.writeFileSync(exports.RESULTS_PATH, '{}');
}
// Create a write to result.json queue with a concurrency of 1
// Possibly the simplest fix would be to run this as a separate process, then we can enforce messages sent to this queue are processed in order
var queue = asyncLib.queue(function (task, callback) {
var analysisKey = task.analysisKey, results = task.results;
console.log('received task', analysisKey);
// read the results from aggregate results.json
var fileContent = fs.readFileSync(exports.RESULTS_PATH, 'utf8');
var existingResults = JSON.parse(fileContent);
existingResults[analysisKey] = results;
try {
fs.writeFileSync(exports.RESULTS_PATH, JSON.stringify(existingResults, null, 2));
console.log("\"".concat(analysisKey, "\" written to ").concat(exports.RESULTS_PATH));
callback();
}
catch (err) {
console.error('Error writing to results.json', err);
callback(err);
}
}, 1);
queue.drain(function () {
console.log('no more tasks to process');
});
// this event listener receives tasks from the parallel processes
var server = net.createServer(function (socket) {
socket.on('data', function (data) {
var task = JSON.parse(data.toString());
queue.push(task);
});
});
console.log('Queue server listening on port 8000');
server.listen(8000);
}
// for use with zst_decompresser.js
if (require.main === module) {
launchQueueServer();
}

0 comments on commit b9eab97

Please sign in to comment.