// Allow adding words to either word list:
$(".add-word").on("change keydown", function (e) {
if (e.which && e.which != 13) return;
$(this).before($("<span>").text($(this).val()));
$(this).val('');
});
// Allow selecting words by clicking them
$(".word-list").on("click", "span", function () {
$(".selected", $(this).parent()).removeClass("selected");
$(this).addClass("selected");
showButton();
});
// Allow forbidding pairs of selected words:
$("#forbid").click(function () {
$(".forbidden").append(
$("<div>").append(
$(".selected").removeClass("selected").clone(),
$("<button>").addClass("del").text("Del")
)
);
showButton();
});
// Remove forbidden pair:
$(document).on("click", ".del", function () {
$(this).parent().remove();
});
// Hide/show button depending on whether we have enough selected words:
function showButton() {
$("#forbid").toggle($(".selected").length == 2);
}
// Main algorithm:
$(".random-word").click(function () {
var index = $(this).index(".random-word");
// Get word that is not clicked:
var otherword = $(".random-word").eq(1-index).text();
// Get all words from corresponding list
var words = $("span", $(".word-list").eq(index)).map(function () {
return $(this).text();
}).get();
// Get list of forbidden words that are linked with the other (non-clicked) word
var forbidden = $('.forbidden div').filter(function () {
return $('span', this).eq(1-index).text() == otherword;
}).map(function () {
return $('span', this).eq(index).text();
}).get();
// Derive the list of allowed words, taking all words, filtering out what is forbidden
var allowed = words.filter(function (txt) {
return forbidden.indexOf(txt) == -1;
});
// Pick a random from these allowed words:
$(this).text(allowed.length
? allowed[Math.floor(Math.random() * allowed.length)]
: "(none)"
);
});
showButton();
// *** Upon special request following was added ***
// Algorithm for choosing random pair in one go:
$("#choose").click(function () {
// Get all words from both lists
var words = $(".word-list").get().map(function (list) {
return $("span", list).get().map(function (span) {
return $(span).text();
});
});
// Get list of forbidden words pairs
var forbidden = $('.forbidden div').get().map(function (div) {
return $('span', div).get().map(function (span) {
return $(span).text();
});
});
// Derive the list of allowed pairs, taking all pairs, filtering out what is forbidden
var allowed = words[0].reduce(function (pairs, word) {
// Get list of forbidden second words, given the first word
var exclude = forbidden.filter(function(pair) {
return pair[0] == word;
}).map(function (pair) {
return pair[1]; // extract second word of the pair
});
// Filter all second words, excluding those that are forbidden pairs with first word.
return pairs.concat(words[1].filter(function (word2) {
return exclude.indexOf(word2) == -1;
}).map(function (word2) {
return [word, word2];
}));
}, []);
// Pick a random pair from these allowed pairs:
var randomPair = allowed.length
? allowed[Math.floor(Math.random() * allowed.length)]
: ["(none)", "(none)"];
// Display the pair
$(".random-word").each(function (i) {
$(this).text(randomPair[i]);
});
});
span {margin-left: 2px; margin-right: 2px}
span.selected {background-color: yellow}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b>First word list:</b>
<div class="word-list">
<span>apple</span>
<span>sea</span>
<span>ship</span>
<input class="add-word" size=10>
</div>
<b>Second word list:</b>
<div class="word-list">
<span>duck</span>
<span>tale</span>
<span>jewelry</span>
<input class="add-word" size=10>
</div>
<button id="forbid">Add combination as forbidden</button><br>
<b>Forbidden combinations:</b>
<div class="forbidden">
</div>
<b>Random Pair (click a word to reselect a random, allowed word):</b>
<div class="random-word">sea</div><div class="random-word">tale</div>
<button id="choose">Random Pick Both</button>