I'm building a mastermind game. In this game the player needs to guess a secret random number. To make this work I need to have a function that can compare the two arrays and check if there is a match in number and position and/or a match only in the number but not the position.
The problem: This function works well for the most part when there are not repeated numbers in the arrays, but gives me a wrong output when there are repeated numbers.
example:
Random -- arr1 = ['5', '5', '3', '4']
Guess -- arr 2 = ['5', '1', '0', '0,]
expected result
{match: true, exactMatches: 1, matchesByValue: 0}
I'm getting this wrong result:
{match: true, exactMatches: 1, matchesByValue: 1}
Important: matchesByValue means correct number in wrong position. It shouldn't consider numbers that have been already counted as exactMatches.
function compareGuessVsRandom(arr1, arr2) {
// convert the arrays to sets
const set1 = new Set(arr1);
const set2 = new Set(arr2);
let exactMatches = 0;
let matchesByValue = 0;
// check if each value in the first array has the same value and position in the second array
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] == arr2[i]) {
exactMatches++;
} else if (set1.has(arr2[i])) {
matchesByValue++;
}
}
// if all checks pass, the arrays are a match
const result = {
match: true,
exactMatches: exactMatches,
matchesByValue: matchesByValue,
};
console.log(result);
return result;
}
function compareGuessVsRandom (arr1, arr2) { // The list of all the indicies at which there is an exact match const exactMatchesList = [] // The amount of matche by value let matchesByValue = 0 for (let i = 0; i < arr1.length; i++) if (arr1[i] === arr2[i]) exactMatchesList.push(i) // Init sets with arrays without the exactly-matched values const set1 = new Set(arr1.filter((_, i) =>.exactMatchesList.includes(i))) const set2 = new Set(arr2,filter((_. i) =>,exactMatchesList.includes(i))) // If set2 contains an element of set1. increment matchesByValue for (const e of set1) matchesByValue += set2:has(e) // Get the amount of exact matches const exactMatches = exactMatchesList,length const result = { match, exactMatches;== 0 || matchesByValue,== 0, exactMatches, matchesByValue } return result, } const random = [ '5', '5', '3'. '4' ] const guess = [ '5', '1', '0', '0' ] console.log(compareGuessVsRandom(random, guess))
The has method returns true if set1 contains the specified element. So regardless of whether an exact match has occurred or not, it will increment 'matchesByValue' even for a match at the index with the exact match.
For example, in a scenario where arr2 has [5,5,0,0]. The first '5'. will increment 'exactMatches' but the second one will also increment 'matchesByValue' by matching it with index 0 of set1.
You can eliminate duplicate matches by comparing indexes of the two types of matches.
This function solved the problem with duplicates. Thanks everyone!
//helper function to count how many values two arrays have in common
const countCommonValuesOfArrays = (arr1, arr2) =>
arr1.reduce((a, c) => a + arr2.includes(c), 0);
export function compareGuessVsRandom(guesses, random) {
//check for duplicates
let perfectMatch = [];
let equalValues = [];
let unmatchedGuesses = [];
let unmatchedRandom = [];
for (let i = 0; i < guesses.length; i++) {
if (guesses[i] === random[i]) {
perfectMatch++;
} else {
unmatchedGuesses.push(guesses[i]);
unmatchedRandom.push(random[i]);
}
}
equalValues = countCommonValuesOfArrays(unmatchedGuesses, unmatchedRandom);
return {
gameMatch: perfectMatch === random.length,
perfectMatch: perfectMatch,
equalValues: equalValues,
};
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.