Javascript a game of q and a - javascript

Using JavaScript only.
I have an array of four questions and an array of four answers and an array of four wrong answers.
I use an array due to order.
When the first question appears, the computer will generate a random number and based on this number put the correct answer in the left or right and put the wrong answer in the other spot.
I register two event handlers on the left and right div's containing those answers.
The individual will select the left or right div based on the question and after the four questions, I will tell you how well you did.
My issue is how to determine which side they chose and if it is right or wrong. I can use event.target.id to determine what the person selected, but how to compare that to the right answer knowing it is random??
I am so new... did I say new.. here is my code to show I tried.. I think its simple, but mind block
I did not finish the rightwrong eventlistener. AND I know the camelCasing, but I wanted to get a rough cut first
window.onload = function () {
var questions = new Array();
questions[0] = "This is the first question";
questions[1] = "This is the second question";
questions[2] = "This is the third question";
questions[3] = "This is the fourth question";
var answers = new Array();
answers[0] = "first answer";
answers[1] = "second answer";
answers[2] = "third answer";
answers[3] = "fourth answer";
var garbage = new Array();
garbage[0] = "first garbage";
garbage[1] = "second garbage";
garbage[2] = "third garbage";
garbage[3] = "fourth garbage";
var k = 0;
var q = document.getElementById("questionId");
var a = document.getElementById("left");
var g = document.getElementById("right");
var nxtquestion = document.getElementById('nextquestion');
nxtquestion.addEventListener('mousedown', nextquestion, false);
a.addEventListener('mousedown', rightwrong, false);
g.addEventListener('mousedown', rightwrong, false);
function nextquestion() {
for (var i = 0; i < questions.length; i++) {
q.innerHTML = questions[k];
}
randomize(k);
k++;
if (k > questions.length) {
q.innerHTML = "Great, you have finished. Please reload the page to play again!";
a.innerHTML = "";
g.innerHTML = "";
nxtquestion.style.display = "none";
}
return;
}
function randomize(k) {
var randomizer = Math.floor((Math.random() * 10) + 1);
if (randomizer <= 5) {
a.innerHTML = answers[k];
g.innerHTML = garbage[k];
} else {
g.innerHTML = answers[k];
a.innerHTML = garbage[k];
}
}
}
Here is the HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>chapter 1</title>
<link rel="stylesheet" type="text/css" href="regart.css">
<script src="regart.js">
</script>
</head>
<body>
<header>
<img class="center" src="regart.jpg" width="278" height="113" alt="regart" />
</header>
<div class="middlesection">
<p id="questionId" class="question">Let's Play RegArt!<br /> Choose either left or right for the correct answer.<br /> To begin, click on the 'Next Question' button. </p><input type="button" id="nextquestion" value="Next Question" />
<p id="howmany"></p>
</div>
<div>
<div class="answerleft" id="left"><p>Left</p></div> <div class="answerright" id="right"><p>Right</p></div>
</div>
<footer>
</footer>
</body>
</html
Here is the CSS... the image will be missing but not important
header, footer, nav
{ display:block; }
html,ul, li, div, h1, h2, h3, p, img
{margin:0; padding:0;}
body
{ width:80%; margin:auto; max-width:960px; font-size:100%; background-color:#401d36;}
header { height:120px; background-color:#0f9fbf; }
img.center {display:block;margin:0 auto;}
.middlesection { background-color:#f2e085; padding:20px 20px 0 20px; height:200px;border-style:dashed; color:#401d36; border-width:thin;}
p {font-family:Baskerville, "Palatino Linotype", Palatino, "Century Schoolbook L", "Times New Roman", serif; font-size:1.2em; padding-left:10px; padding-bottom:30px;}
.answerleft {border-style:dashed; color:#0f9fbf; float:left; width:35%; padding:5%; height:200px; font-size:3em; }
.answerright {border-style:dashed; color:#0f9fbf; float:right; width:35%; padding:5%; height:200px; font-size:3em; }

the code you provided misses one vital function. however I have created a fiddle you can check. This I think will solve your problem and you can carry on from there.
function randomize(k) {
var randomizer = Math.floor((Math.random() * 10) + 1);
if (randomizer <= 5) {
a.innerHTML = answers[k];
g.innerHTML = garbage[k];
a.addEventListener('mousedown', rightAnswer, false);
g.addEventListener('mousedown', wrongAnswer, false);
} else {
g.innerHTML = answers[k];
a.innerHTML = garbage[k];
g.addEventListener('mousedown', rightAnswer, false);
a.addEventListener('mousedown', wrongAnswer, false);
}
}
function rightAnswer(){
alert('You are right');
}
function wrongAnswer(){
alert('You are wrong');
}
http://jsfiddle.net/Pallab/ACXPN/embedded/result/

One way to do it would be to set something on the element itself and then check for that. Or use a different event handler for each element (you'd have to remove and then re-add them every time the right answer swapped sides).
But an easier way would be to just store the id of the correct element in a global variable then check that, something like this:
var rightAnswerId;
function rightwrong(e) {
if (e.target.id == rightAnswerId) {
alert("CORRECT");
} else {
alert("WRONG");
}
}
function randomize(k) {
var randomizer = Math.floor((Math.random() * 10) + 1);
if (randomizer <= 5) {
a.innerHTML = answers[k];
g.innerHTML = garbage[k];
rightAnswerId = 'left';
} else {
g.innerHTML = answers[k];
a.innerHTML = garbage[k];
rightAnswerId = 'right';
}
}
There are various other solutions, including storing the current question and comparing the clicked elements contents to the correct answer for that question.
I put my solution into a Fiddle, that might make it easier for someone to come up with something better.
(I changed the event from mousedown to click, which made more sense for the demo but it depends on exactly what you want to happen).
You also might want to call nextquestion on page load to go immediately to the first question. Again, depends on what you want to happen.

i'm quite shure you wanna use k instead of i as index in your for() statement...
anyway:
but how to compare that to the right answer knowing it is random??
use another variable to store the right answer's position
...
var right_side;
...
function randomize(k) {
var randomizer = Math.floor((Math.random() * 10) + 1);
if (randomizer <= 5) {
a.innerHTML = answers[k];
g.innerHTML = garbage[k];
right_side = "left";
} else {
g.innerHTML = answers[k];
a.innerHTML = garbage[k];
right_side = "right";
}
}
then in your rightwrong eventlistener check the right_side value

Related

Ascii Art Animation in Browser

I want to animate Ascii Art in the Browser.
The Ascii Art should be loaded via a text file. There are many libraries which convert but I have found none, which actually animates it.
By animation I mean a typewriter animation that speeds up over time and changes the 'zoom factor' so that the whole image is visible in the viewport at the end.
Hopefully anyone knows a libary for my problem.
I have a feeling SO doesn't like library recommendations, and actually I haven't found one, so here's some basic code to get you started.
It sets the typing speed to the old Teletype 10 chars per second and of course that can be changed, and an acceleration function can be added when you know what you want for that. Note: the txt file needs to be on the same domain to prevent CORS problems.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Typewriter print</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Courier, monospace;
font-size: 12px;
}
</style>
</head>
<body>
<div id="container">
<input id="file" type="text" value="" placeholder="Filename" />
<button onclick="loadFile()">Click to draw the file</button>
<div id="picture"></div>
</div>
<script>
let file = '';
let reader = new XMLHttpRequest();
function loadFile() {
file = document.getElementById('file').value;
reader.open('get', file, true);
reader.onreadystatechange = draw;
reader.send(null);
}
function draw() {
if (reader.readyState == 4) {
const picture = document.getElementById('picture');
picture.innerHTML = '';
let str = reader.responseText;
let chs = str.split('');
//set as the typing speed in characters
//per second 10 is the old teletype speed
let chsPerSec = 10;
let i = 0;
function reveal() {
if (i < chs.length) {
let nextch = chs[i];
if (nextch.charCodeAt(0) == 10) {
nextch = '<br>';
} else if (nextch.charCodeAt(0) == 32) {
nextch = '<span style="color:transparent;">.</span>';
}
picture.innerHTML = picture.innerHTML + nextch;
setTimeout(reveal, Math.floor(1000 / chsPerSec));
i++;
}
}
reveal();
}
}
</script>
</body>
</html>

Passing variables from JavaScript to HTML and HTML button inputs to JavaScript

I am trying to make a simple game using JavaScript and HTML.
The game consists of having two buttons on the screen with random numbers and clicking the one that is smaller.
At the end, you will get your results.
What I am having trouble with is getting the random number generated in JavaScript to print on the button and getting the data back to JavaScript from the button.
var number = prompt('Choose Your Difficulty, Easy, Normal, Or Hard?');
var number = number.toUpperCase(); //Chooses difficulty
if (number === 'EASY')//easy difficulty
{
var difficulty = 20;
}else if (number === 'NORMAL')//normal difficulty
{
var difficulty = 100;
}else if(number === 'HARD')//hard difficulty
{
var difficulty = 1000;
}else
{
alert('Please Enter A Valid Answer')//if value is not valid
}
var number1 = Math.floor((Math.random()* difficulty) + 1);//random number 1
var number2 = Math.floor((Math.random()* difficulty) + 1);//random number 2
//----------------------Code i found but im not sure now to use it--------------
// 1. Create the button
var button = document.createElement("button");
button.innerHTML = "Do Something";
// 2. Append somewhere
var body = document.getElementsByTagName("body")[0];
body.appendChild(button);
// 3. Add event handler
button.addEventListener("click", function() {
alert("did something");
});
//-----------------------------------------------------------------------------
button {
margin-top: 20px;
line-height: 60px;
font-weight: bold;
padding: 0 40px;
background: salmon;
border: none;
}
button:hover {
background: lightsalmon;
}
<!DOCTYPE html>
<html>
<head>
<title>
Speed Game
</title>
<link href="css/styles.css" rel="stylesheet"
type="text/css">
<script src="../script/script.js"></script>
</head>
<body>
<button id= "button">
Do Something!
</button>
</body>
</html>
How can I solve this problem?
First of all, welcome to the world of programming!
Second, here's the game you wanted. I've done everything using functions, so understanding it should be easy.
Try to play a few games first!
The concept is pretty simple, really, so after playing a bit, look at the code and try to figure it out on your own!
var number;
var difficulty = 0;
var randomNumOne;
var randomNumTwo;
var buttonOne = document.getElementById("buttonOne");
var buttonTwo = document.getElementById("buttonTwo");
var tempButton;
function requestDifficulty(){
number = prompt('Choose Your Difficulty, Easy, Normal, Or Hard?');
number = number.toUpperCase();
setDifficulty();
}
function setDifficulty(){
if (number === 'EASY'){
difficulty = 20;
startGame();
}else if (number === 'NORMAL'){
difficulty = 100;
startGame();
}else if(number === 'HARD'){
difficulty = 1000;
startGame();
}else{
alert('Please Enter A Valid Answer');
requestDifficulty()
}
}
function startGame(){
randomNumOne = Math.floor((Math.random()* difficulty) + 1);
randomNumTwo = Math.floor((Math.random()* difficulty) + 1);
buttonOne.innerHTML = randomNumOne;
buttonTwo.innerHTML = randomNumTwo;
}
function getResults(pressedButton){
tempButton = pressedButton;
if(tempButton == "buttonOne"){
if(randomNumOne < randomNumTwo){
alert("Correct!")
}else{
alert("False!")
}
}else if(tempButton == "buttonTwo"){
if(randomNumTwo < randomNumOne){
alert("Correct!")
}else{
alert("False!")
}
}
}
requestDifficulty();
button {
margin-top: 20px;
line-height: 60px;
font-weight: bold;
padding: 0 40px;
background: salmon;
border: none;
}
button:hover {
background: lightsalmon;
}
<!DOCTYPE html>
<html>
<head>
<title>
Speed Game
</title>
</head>
<body>
<button id="buttonOne" onclick="getResults('buttonOne');">
random number 1
</button>
<button id="buttonTwo" onclick="getResults('buttonTwo')">
random number 2
</button>
</body>
</html>

Javascript: Memory efficient way to do this effect

I wrote the code in Javascript but any good alternative would do.
EFFECT: onmousemove over the webpage circles of random colors should create wherever the mouse moves. and they have to be added behind a mask image(circles are visible only in the transparent portion of the image which is a logo. thus creating a color paint to create logo onmousemove.
it doesn't work in jsfidde because of its memory intensiveness.
WORKING LINK: http://goo.gl/DNRxO9
I pasted the exact code you can create a new html file with the following code and IT WORKS PERFECT IN FIREFOX ONLY because of its memory intensiveness(lots of divs added in very short time so DOM becomes very very heavy).
<html>
<head>
<style type="text/css">
body{
padding:0;
margin:0;
overflow: hidden;
}
#mask{
width:100%;
height:auto;
position:absolute;
z-index:10;
}
#logo{
width:50%;
height:50%;
margin:auto;
}
.point{
width:0px;
height:0px;
background-color:#ff0000;
position:absolute;
z-index:5;
left:50px;top:50px;
border-width:50px;
border-style: solid;
border-color:red;
border-radius:50px;
opacity:1;
transition: border-width 3s ease-in-out;
}
.no-border{border-width:0px;}
</style>
<script type="text/javascript">
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
}
/* OptionalCode: for removing divs after a lot are created */
Element.prototype.remove = function() {
this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
for(var i = 0, len = this.length; i < len; i++) {
if(this[i] && this[i].parentElement) {
this[i].parentElement.removeChild(this[i]);
}
}
}
i=0;
function colors(event){
var x=event.clientX;
var y=event.clientY;
var point = document.getElementsByClassName('point');
document.body.innerHTML += "<div class='point'></div>";
point[i].style.borderColor = getRandomColor();
//point[i].className += ' no-border';
point[i].style.left = x + 'px';
point[i].style.top = y + 'px';
i++;
}
function position(){
var ht = window.getComputedStyle(document.getElementById("mask"), null).getPropertyValue("height");
var ht_num = Number(ht.slice(0,ht.length - 2));
margin_top = (Number(document.body.clientHeight) - ht_num)/2;
document.getElementById('mask').style.marginTop = margin_top + "px";
}
</script>
</head>
<body onload="position();" onmousemove="colors(event)">
<img id="mask" src="http://goo.gl/EqfJ0L">
</body>
</html>
There is one HUGE, HUGE, HUGE performance killer in your code:
document.body.innerHTML += "<div class='point'></div>";
This takes your entire document, throws it away and just inserts everything back again. This is horrible! Remember this for all times and never do this again! ;)
Keep the basic rule in mind, to never add Elements via .innerHTML!
The correct way to go is the following:
// create your new div element
var circleElement = document.createElement("div");
// add all the stuff needed
circleElement.classList.add("point");
circleElement.style.borderColor = getRandomColor();
circleElement.style.left = x + 'px';
circleElement.style.top = y + 'px';
// now append the element to the body
document.body.appendChild(circleElement);
This creates a single div and nicely inserts it as a child-element of the body.
Additionally you can decrease the number of divs drawn by introducing a threshhold:
var lastX=0,lastY=0;
function colors(event){
var x=event.clientX;
var y=event.clientY;
if (Math.abs(lastX - x) + Math.abs(lastY - y) <= 10 ) return;
/* do stuff */
lastX = x;lastY = y;
}
As a third measure you can decrease the size of the image to just hold the mask element and trigger the mousemove only on the image (because divs outside the mask are hidden anyway).
Ultimately, you could kill "old" div-elements when you have reached a certain amount.
I have not included these two last optimizations, but look at the already supersmooth example now!

"Member not found" error in IE6: from .style edit or getElementById or...?

I volunteered to develop this script for a small organisation (as part of my self-training in programming). It randomly selects a seat in a room (spending a few seconds keeping viewers guessing which seat was selected). Since I use a Mac, I tested mainly with Firefox, where it works like a charm. Turns out that the computer in their room runs Internet Explorer 6 on Windows XP (and they had to enable active content in local files).
They called me to inform me of an error and based on the information they gave, the guilty line is either RowNumberDisplay.style = "color: #FF0000"; or var RowNumberDisplay = document.getElementById("RowNumber");. Quick searches on Google and Stack Overflow for getElementById and .style problems in IE6 were fruitless (a common problem is false matches due to name attributes, but the div in question has no name attribute). Thanks in advance for any answers helping identify and address this error.
<!doctype html>
<html>
<head>
<title>The Lucky Person</title>
<style type="text/css">
input#SelectLuckyPerson
{
height: 150px;
font-size: 60px;
}
p#RowDetails, p#SeatDetails, div#RowNumber, div#SeatNumber
{
font-size: 100px;
display: inline;
}
div#RowNumber, div#SeatNumber
{
color: #0000FF;
}
</style>
</head>
<body>
<div id="LuckyPersonIs"><input type="button" id="SelectLuckyPerson" value="And the lucky person is..." onClick="GetResults();"></div>
<p id="RowDetails">Row number: <div id="RowNumber">0</div></p>
<p id="SeatDetails">Seat number: <div id="SeatNumber">0</div></p>
<script>
var MinRow = 2;
var MaxRow = 8;
var SeatsInRow = new Array();
SeatsInRow[1] = 25;
SeatsInRow[2] = 25;
SeatsInRow[3] = 27;
SeatsInRow[4] = 27;
SeatsInRow[5] = 27;
SeatsInRow[6] = 27;
SeatsInRow[7] = 29;
SeatsInRow[8] = 31;
SeatsInRow[9] = 31;
SeatsInRow[10] = 31;
SeatsInRow[11] = 31;
SeatsInRow[12] = 33;
SeatsInRow[13] = 33;
SeatsInRow[14] = 33;
var ShuffleSpeed = 200;
var RowNumberDisplay = document.getElementById("RowNumber");
var SeatNumberDisplay = document.getElementById("SeatNumber");
var ChosenRow, ChosenSeat
function GetResults()
{
var IsRunning = CheckStatus();
if (IsRunning)
{
ChosenRow = ChooseRow();
ChosenSeat = ChooseSeat();
RowNumberDisplay.style = "color: #FF0000";
SeatNumberDisplay.style = "color: #FF0000";
ShowRowResult = window.setInterval("TryRowResult()", ShuffleSpeed);
if (DelaySeats == false)
{
ShowSeatResult = window.setInterval("TrySeatResult()", ShuffleSpeed);
}
}
}
function ChooseRow()
{
return Math.floor(Math.random() * (MaxRow - MinRow)) + MinRow;
}
function ChooseSeat()
{
return Math.ceil(Math.random() * SeatsInRow[ChosenRow]);
}
function TryRowResult()
{
TryRow = ChooseRow();
RowNumberDisplay.innerHTML = TryRow;
if (TryRow == ChosenRow)
{
window.clearInterval(ShowRowResult);
document.getElementById("RowNumber").style = "color: #0000FF";
if (DelaySeats == true)
{
ShowSeatResult = window.setInterval("TrySeatResult()", ShuffleSpeed);
}
}
}
function TrySeatResult()
{
TrySeat = ChooseSeat();
SeatNumberDisplay.innerHTML = TrySeat;
if (TrySeat == ChosenSeat)
{
window.clearInterval(ShowSeatResult);
document.getElementById("SeatNumber").style = "color: #0000FF";
}
}
function CheckStatus()
{
if (RowNumberDisplay.style.color == "rgb(255, 0, 0)" || SeatNumberDisplay.style.color == "rgb(255, 0, 0)")
{
return false;
}
return true;
}
</script>
</body>
</html>
An element's style property is an object, not a string. To assign text to it like you would a CSS attribute, you should assign to element.style.cssText, this will parse out the string for you, and acts as a shortcut to defining multiple styles.
In this case, though, you can just use this:
ChosenRow.style.color = ChosenSeat.style.color = "#f00";

How can I know when there is a new line on a Wheel of Fortune Board?

I the following code here in which you can play a Wheel of Fortune-like game with one person (more of my test of javascript objects).
My issue is that when the screen is small enough, the lines do not seem to break correctly.
For example:
Where the circle is, I have a "blank" square. The reason why I have a blank square is so that when the screen is big enough, the square serves as a space between the words.
Is there a way in my code to efficiently know if the blank square is at the end of the line and to not show it, and then the window gets resized, to show it accordingly?
The only thought I had was to add a window.onresize event which would measure how big the words are related to how big the playing space is and decide based on that fact, but that seems very inefficient.
This is my code for creating the game board (starts # line 266 in my fiddle):
WheelGame.prototype.startRound = function (round) {
this.round = round;
this.lettersInPuzzle = [];
this.guessedArray = [];
this.puzzleSolved = false;
this.currentPuzzle = this.puzzles[this.round].toUpperCase();
this.currentPuzzleArray = this.currentPuzzle.split("");
var currentPuzzleArray = this.currentPuzzleArray;
var lettersInPuzzle = this.lettersInPuzzle;
var word = document.createElement('div');
displayArea.appendChild(word);
word.className = "word";
for (var i = 0; i < currentPuzzleArray.length; ++i) {
var span = document.createElement('div');
span.className = "wordLetter ";
if (currentPuzzleArray[i] != " ") {
span.className += "letter";
if (!(currentPuzzleArray[i] in lettersInPuzzle.toObject())) {
lettersInPuzzle.push(currentPuzzleArray[i]);
}
word.appendChild(span);
} else {
span.className += "space";
word = document.createElement('div');
displayArea.appendChild(word);
word.className = "word";
word.appendChild(span);
word = document.createElement('div');
displayArea.appendChild(word);
word.className = "word";
}
span.id = "letter" + i;
}
var clear = document.createElement('div');
displayArea.appendChild(clear);
clear.className = "clear";
};
Instead of JavaScript, this sounds more like a job for CSS, which solves this problem all the time when dealing with centered text.
Consider something like this:
CSS
#board {
text-align: center;
border: 1px solid blue;
font-size: 60pt;
}
.word {
display: inline-block;
white-space: nowrap; /* Don't break up words */
margin: 0 50px; /* The space between words */
}
.word span {
display: inline-block;
width: 100px;
border: 1px solid black
}
HTML
<div id="board">
<span class="word"><span>W</span><span>h</span><span>e</span><span>e</span><span>l</span></span>
<span class="word"><span>o</span><span>f</span></span>
<span class="word"><span>F</span><span>o</span><span>r</span><span>t</span><span>u</span><span>n</span><span>e</span></span>
</div>
Here's a fiddle (try resizing the output pane).
Here you go. Uses the element.offsetTop to determine if a .space element is on the same line as its parent.previousSibling.lastChild or parent.nextSibling.firstChild.
Relevant Code
Note: In the fiddle I change the background colors instead of changing display so you can see it work.
// hides and shows spaces if they are at the edge of a line or not.
function showHideSpaces() {
var space,
spaces = document.getElementsByClassName('space');
for (var i = 0, il = spaces.length ; i < il; i++) {
space = spaces[i];
// if still display:none, then offsetTop always 0.
space.style.display = 'inline-block';
if (getTop(nextLetter(space)) != space.offsetTop || getTop(prevLetter(space)) != space.offsetTop) {
space.style.display = 'none';
} else {
space.style.display = 'inline-block';
}
}
}
// navigate to previous letter
function nextLetter(fromLetter) {
if (fromLetter.nextSibling) return fromLetter.nextSibling;
if (fromLetter.parentElement.nextSibling)
return fromLetter.parentElement.nextSibling.firstChild;
return null;
}
// navigate to next letter
function prevLetter(fromLetter) {
if (fromLetter.previousSibling) return fromLetter.previousSibling;
if (fromLetter.parentElement.previousSibling)
return fromLetter.parentElement.previousSibling.lastChild;
return null;
}
// get offsetTop
function getTop(element) {
return (element) ? element.offsetTop : 0;
}
showHideSpaces();
if (window.addEventListener) window.addEventListener('resize', showHideSpaces);
else if (window.attachEvent) window.attachEvent('onresize', showHideSpaces);
jsFiddle

Categories

Resources