Search Algorithm Game

by CurtisDS

HTML

<button id="create">Create Guess</button> <button id="restart">Restart</button><br><br>
<div class="table-container">
	<table id="table">
		<thead>
			<tr>
				<th colspan="6">Table A</th>
				<th colspan="6">Table B</th>
				<th colspan="6">Table C</th>
			</tr>
			<tr id="numberHeading">
			</tr>
		</thead>
		<tbody>
			<tr>
				<td colspan="18">No Guesses Yet</td>
			</tr></tbody>
		<tfoot><tr></tr></tfoot>
	</table>
</div>
<pre>
+ = guess
? = unknown
X = known to not be correct
O = known to be correct
</pre>

CSS

body {
  padding: 20px;
  font-family: Helvetica;
}

.table-container {
	max-height: 700px;
	overflow: auto;
}

table {
	border-collapse: collapse;
}

thead {
	position: sticky;
	top: 0;
}

tfoot {    
	position: sticky;
  bottom: 0;
}

th {
	background-color: #bbb;
	box-shadow: -1px -1px 0px black inset, 1px 1px 0px black inset, 1px 1px 0px black, -1px -1px 0px black;
	border-top: none !important;
	border-right: none !important;
	border-bottom: none !important;
}


th:last-of-type,
thead tr:last-of-type th {
	box-shadow: -1px -1px 0px black inset, 1px 1px 0px black inset, -1px -1px 0px black;
}


tfoot td {
	background-color: #bbb;
	box-shadow: -1px -1px 0px black inset, 1px 1px 0px black inset, 1px 1px 0px black, -1px -1px 0px black;
	border-top: none !important;
	border-right: none !important;
	border-bottom: none !important;
}


tfoot td {
	box-shadow: -1px -1px 0px black inset, 1px 1px 0px black inset, -1px -1px 0px black;
}

th, td {
	border: 1px solid black;
	padding: 4px;
	min-width: 3em;
	text-align: center;
}

tfoot td {
	background-color: #bbb;
}

th:nth-of-type(6),
th:nth-of-type(12),
td:nth-of-type(6),
td:nth-of-type(12),
tr:first-of-type th:not(:last-of-type) {
	border-right-width: 2px;
}

tr.dim td {
	opacity: 0.5;
	color: red;
}

tbody tr:nth-child(odd) td {
	background: #ddd;
}

tbody tr:first-of-type:not(:last-of-type) {
	display: none;
}

.chosen {
	background: goldenrod;
}

.X {
	background: red;
}

.O {
	background: green;
}

JavaScript

const possibleValues = Array(18).fill().map((v,i)=>i+1); // an array with values 1 - 18
const maxColumns = possibleValues.length;
const chosenNumbers = chooseThreeNumbersFromTable();
const listOfGuesses = [];
const knownColumns = [];

// ###################################################################################################################################
// ################################################### Algorithm logic  ##############################################################
// ###################################################################################################################################

function doAlgorith() {
	let seenGuessedNumbers = [];
	
	// loop through all the guesses to search for any 2 other guesses who do not share any number between them
	listOfGuesses.forEach((guess1, index1) => {
	
		seenGuessedNumbers = [...new Set([...guess1,...seenGuessedNumbers])]; // keep track of all guessed numbers so we know when to end the game
		
		listOfGuesses.forEach((guess2, index2) => {
		
			if(index1 < index2) return; // only search forward in the array
			let intersection1X2 = [...new Set([...guess1].filter(x => guess2.includes(x)))];
			if(intersection1X2.length > 0) return; // the sets overlapped, skip to next index			
			let merged1_2 = [...new Set([...guess1, ...guess2])]; // merge the sets to for further tests, guesses must not overlap the merged set
			
			listOfGuesses.forEach((guess3, index3) => {
			
				if(index2 < index3) return; // only search forward in the array
				let intersection1_2X3 = [...new Set([...merged1_2].filter(x => guess3.includes(x)))];
				if(intersection1_2X3.length > 0) return; // the sets overlapped, skip to next index
				let merged1_2_3 = [...new Set([...merged1_2, ...guess3])]; // merge all three non overlapping sets
				
				possibleValues.filter(n => !merged1_2_3.includes(n)).forEach(n => {
					// knownColumns array stores true, false, or undefined at the index locations of the...