Last active
March 8, 2024 10:41
-
-
Save Nico-kun123/4408d26a4aad782130f76c6b80e25391 to your computer and use it in GitHub Desktop.
Задание 1. Разработать функцию определения счета в игре | Задание 2. Разработать тесты для функции определения счета в игре
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const TIMESTAMPS_COUNT = 50000; | |
const PROBABILITY_SCORE_CHANGED = 0.0001; | |
const PROBABILITY_HOME_SCORE = 0.45; | |
const OFFSET_MAX_STEP = 3; | |
type Score = { | |
home: number; | |
away: number; | |
}; | |
type Stamp = { | |
offset: number; | |
score: Score; | |
}; | |
const emptyScoreStamp: Stamp = { | |
offset: 0, | |
score: { | |
home: 0, | |
away: 0, | |
}, | |
}; | |
export const generateStamps = (): Stamp[] => { | |
const scoreStamps = Array(TIMESTAMPS_COUNT) | |
.fill(emptyScoreStamp) | |
.map( | |
((acc) => () => { | |
const scoreChanged = Math.random() > 1 - PROBABILITY_SCORE_CHANGED; | |
const homeScoreChange = | |
scoreChanged && Math.random() < PROBABILITY_HOME_SCORE ? 1 : 0; | |
const awayScoreChange = scoreChanged && !homeScoreChange ? 1 : 0; | |
return { | |
offset: (acc.offset += | |
Math.floor(Math.random() * OFFSET_MAX_STEP) + 1), | |
score: { | |
home: (acc.score.home += homeScoreChange), | |
away: (acc.score.away += awayScoreChange), | |
}, | |
}; | |
})(emptyScoreStamp) | |
); | |
return scoreStamps; | |
}; | |
export const getScore = (gameStamps: Stamp[], offset: number): Score => { | |
if (isNaN(offset)) { | |
throw new Error("Offset must be a number (got 'NaN' instead)!"); | |
} | |
if (offset < 0) { | |
throw new Error("Offset value cannot be less than '0'!"); | |
} | |
const stampsLength: number = gameStamps.length; | |
if (offset > gameStamps[stampsLength - 1].offset) { | |
throw new Error("Score with this offset doesn't exist!"); | |
} | |
// Бинарный поиск | |
let left = 0; | |
let right = stampsLength - 1; | |
while (left <= right) { | |
const middle = Math.floor((left + right) / 2); | |
if (gameStamps[middle].offset === offset) { | |
return gameStamps[middle].score; | |
} else if (gameStamps[middle].offset < offset) { | |
left = middle + 1; | |
} else { | |
right = middle - 1; | |
} | |
} | |
if (right >= 0) { | |
return gameStamps[right].score; | |
} | |
// если offset равен 0 | |
return { home: 0, away: 0 }; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { generateStamps, getScore } from "../game"; | |
const gameScores = generateStamps(); | |
describe("Проверка НЕКОРРЕКТНЫХ значений offset", () => { | |
test("Значение offset — 'NaN'", () => { | |
expect(() => { | |
getScore(gameScores, NaN); | |
}).toThrow(); | |
}); | |
test("Значение offset строго меньше нуля", () => { | |
expect(() => { | |
getScore(gameScores, -100); | |
}).toThrow(); | |
}); | |
test("Значение offset слишком большое", () => { | |
expect(() => { | |
getScore(gameScores, 999999); | |
}).toThrow(); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { getScore } from "../game"; | |
const testStamps = [ | |
{ offset: 3, score: { home: 0, away: 0 } }, | |
{ offset: 5, score: { home: 0, away: 0 } }, | |
{ offset: 8, score: { home: 0, away: 0 } }, | |
{ offset: 7714, score: { home: 1, away: 0 } }, | |
{ offset: 7717, score: { home: 1, away: 0 } }, | |
{ offset: 7718, score: { home: 1, away: 0 } }, | |
{ offset: 26975, score: { home: 1, away: 2 } }, | |
{ offset: 26976, score: { home: 1, away: 2 } }, | |
{ offset: 26979, score: { home: 1, away: 2 } }, | |
{ offset: 99929, score: { home: 1, away: 1 } }, | |
{ offset: 99930, score: { home: 1, away: 1 } }, | |
{ offset: 99931, score: { home: 1, away: 1 } }, | |
]; | |
test("Проверка значений offset, которые точно есть в списке stamps", () => { | |
testStamps.forEach((obj) => { | |
expect(getScore(testStamps, obj.offset)).toBe(obj.score); | |
}); | |
}); | |
test("Проверка промежуточных значений offset", () => { | |
// Значения offset=6 нет. Он берёт предыдущее значение (offset=5) | |
expect(getScore(testStamps, 6)).toBe(testStamps[1].score); | |
expect(getScore(testStamps, 6)).not.toBe(testStamps[2].score); | |
}); | |
test("Проверка значения offset=0", () => { | |
const defaultScore = { home: 0, away: 0 }; | |
expect(getScore(testStamps, 0)).toStrictEqual(defaultScore); | |
}); | |
test("Значение offset является числом с плавающей запятой", () => { | |
expect(getScore(testStamps, 6.0)).toBe(testStamps[1].score); | |
expect(getScore(testStamps, 6.9)).toBe(testStamps[1].score); | |
expect(getScore(testStamps, 6.000000000000000001)).toBe(testStamps[1].score); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { generateStamps, getScore } from "../game"; | |
test.concurrent("1000 случайных значений offset", async () => { | |
const TIMESTAMPS_COUNT = 50000; | |
const gameScores = generateStamps(); | |
// Генерируем случайные offset | |
const randOffset: number[] = []; | |
for (let index = 0; index < 1000; index++) { | |
randOffset.push(Math.floor(Math.random() * TIMESTAMPS_COUNT)); | |
} | |
// Проверка | |
randOffset.forEach((offset) => { | |
const score = getScore(gameScores, offset); | |
const stamp = gameScores.find((stamp) => { | |
stamp.offset === offset; | |
}); | |
if (stamp !== undefined) { | |
expect(score).toEqual(stamp.score); | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Содержание файла package.json:
Unit-тесты:
Содержание файла jest.config.js: