Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

everything is working except the reset button. Pushing now, but I wil… #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions harrison/dummy-game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var DummyGame = (function() {

function DummyGameCtor(cardset, size) {
//ignore cardset, but allow optional size parameter
this.size = function() {
return size || 16; //default to 16 if size is undefined or 0
}

var _gui = null; //private variable
this.gui = function(useGui) {
if (useGui === undefined) //no parameter; act as getter:
return _gui;
// else act as setter:
_gui = useGui;
}

this.lift = function(where) {
console.log("Attempted lift("+where+")");
}
}
// add these dummy methods to prototype to ensure complete interface:

DummyGameCtor.prototype.remaining = function() {}
DummyGameCtor.prototype.reset = function() {}
DummyGameCtor.prototype.faceupWhere = function() {}
DummyGameCtor.prototype.faceupValue = function() {}

return DummyGameCtor;
})();
76 changes: 76 additions & 0 deletions harrison/memory-cards.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#board {
width: 100px;
height: 100px;
}


table{
left: auto;
right: auto;
top: auto;
bottom: auto;
}
tr {
background-color: purple;
width: auto;
}

td {
width: 10px;
height: 10px;
text-align: center;
padding: 5px;
}

.face-up {
background-color: grey;
border: 1px dashed white;
height: 20px;
width: 10px;
}

.face-down {
background-color: red;
border: 2px solid white;
height: 20px;
width: 10px;
}

.face-up .cardText {
visibility: visible;
color: red;
padding: none;
margin: none;
font-size: 11px;
}

.face-down .cardText {
visibility: hidden;
padding: none;
margin: none;
font-size: 11px;
}

.matched {
background-color: white;
border: 1px dashed lightblue;
}

#reset {
display: inline-block;
position: absolute;
left: 200px;
top: 50px;
background-color: lightblue;
border-radius: 50%;
width: 100px;
height: 100px;
}

#reset p {
position: relative;
font-size: 12px;
font-weight: bold;
text-align: center;
top: 10px;
}
31 changes: 31 additions & 0 deletions harrison/memory-cards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
var RussEng = (function() {
var letters = [ ['А/а', 1], ['A',1], ['Б/б', 2], ['B', 2],
['В/в', 3], ['V', 3], ['Г/г', 4], ['G', 4], ['Д/д', 5], ['D', 5],
['Е',6], ['ye',6], ['Ё/ё',7], ['yo', 7], ['Ж/ж',8], ['zh', 8],['З/з',9],
['И/и', 10], ['I', 10], ['Й/й', 11], ['Y', 11], ['К/к', 12], ['K', 13],
['Л/л', 14], ['L', 14], ['М/м',15], ['M', 15], ['Н/н', 16], ['N', 16],
['О/о', 17], ['O', 17], ['Р/р',18], ['R', 18], ['С/с', 19], ['S', 19],
['Т/т', 20], ['T', 20], ['У/у', 21], ['U', 22], ['Ф/ф', 23], ['F', 23],
['Х/х',24], ['Kh', 24], ['Ц/ц', 25], ['ts', 26], ['Ч/ч', 27], ['ch', 27],
['Ш/ш',28], ['sh', 28], ['Щ/щ', 29], ['shch', 29], ['Ъ/ъ', 30], ['Hard sign', 30],
['Ы/ы', 31], ['ui', 31], ['Ь/ь', 32], ['Soft sign', 32], ['Э/э', 33], ['E',33],
['Ю/ю', 34], ['yu', 34], ['Я/я', 35], ['ya', 35] ];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Points for having the craziest looking game array.

function Ctor() {
this.values = function() {
return letters.slice();
};

this.match = function(valA, valB) {
return (valA[1] === valB[1]);
};

this.display = function(val) {
return val[0];
};

};

return Ctor;

})();
119 changes: 119 additions & 0 deletions harrison/memory-game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
var MemoryGame = (function() {

function Ctor(cardset) {
var slots, //values of shuffled cards;
//sparse array: will have elements deleted as cards are removed
length,//total slots, including gaps
there, //position of face-up card if any, or false
_gui = null;

// Helper functions which need access to closure vars;
// some fns will be made public as instance methods:
var reset = function() {
slots = cardset.values();
length = slots.length;
there = false;
shuffle(slots);
}
reset();// reset now as part of init'ing

var gui = function() {//accessor fn
if (arguments.length === 0)
return _gui; //getter
_gui = arguments[0]; //setter
}

var size = function() {
return length;
}

var remainsAt = function(where) {//--> boolean
return slots[where]!==undefined;
}
var valueAt = function(where) {//--> card val
return slots[where];
}
var removeAt = function(where) {
delete slots[where];
}
var faceupValue = function() {//--> card val
return valueAt(there);
}
var faceupWhere = function() {//--> integer
return there;
}
var remaining = function() {//--> array of integers
return Object.keys(slots).map(Number);
}

var lift = function(here) {//--> display string
//if (!isValid(here,length)) return false;
if (!remainsAt(here)) return false;
if (there===here) return false;

// must be a face-down card here; proceed...
var valHere = valueAt(here),
displayHere = cardset.display(valHere);
if (there === false) {
// no current face-up
there = here; //turn here face-up

} else {
// check match with face-up
console.log(there);
if (cardset.match(valHere,valueAt(there))) {
// match; remove both:
removeAt(here);
removeAt(there);
if (_gui)
_gui.removeSoon([here,there]);
//optional: report match
console.log("Match!")
} else {
if (_gui)
_gui.hideSoon([here,there]);
}
//either way, turn face-up to face-down:
there = false;
}
if (_gui)
_gui.show(here,displayHere);
return displayHere;
}

// Make some functions public as instance methods:
this.reset = reset;
this.lift = lift;
this.faceupValue = faceupValue;
this.faceupWhere = faceupWhere;
this.remaining = remaining;
this.gui = gui;
this.size = size;
}//end ctor

// Private Functions shared by all boards:
// these could be placed inside ctor,
// but then they would be rebuilt for each instance
function isValid(where,length) {
return (typeof where === 'number')
&& (where%1 === 0)
&& (where>=0)
&& (where<length)
}

function shuffle(array) {
// Knuth-Fisher-Yates, modified from http://bost.ocks.org/mike/shuffle/
var end = array.length, temp, i;
// While there remain elements to shuffle…
while (end>1) {
// Pick a remaining element…
i = Math.floor(Math.random() * end--);
// And swap it with the current element.
temp = array[end];
array[end] = array[i];
array[i] = temp;
}
}

return Ctor;
})();
116 changes: 116 additions & 0 deletions harrison/memory-gui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
var MemoryGui = (function() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that you've made your cards interesting here. The only trouble is that they may be too interesting. For someone that doesn't know Russian, it's difficult to ascertain what is actually supposed to match to what here, and for testing purposes I found that I was just clicking randomly until I found something that actually matched. So, good cards, but remember that you're possibly making a game for people that don't know Russian!

Your cards are flipping, and then flipping back once two dissimilar cards are showing, which is great. There is the capability of flipping more than two cards at once, which is something you can fix by shortening the time of your hideSoon function, or by disabling clicking any time there are two cards showing.

At present your remove function doesn't seem to quite be working the way you want it to. It removes the background CSS, but retains the content of the card. Ultimately we want this function to remove the entirety of the cards content, leaving just a blank space (by removing it or rendering it invisible - and untouchable).

You're already aware of your reset button not working, but another issue with the button is that it is currently overlapping the game, so you can't help but press it while trying to get at some of the cards. I like that you've made it more interesting then just a tiny button to press, but you'll want to mess with your #reset CSS and adjust its position as necessary.

Beyond that, when I manually refresh the page the cards are being placed randomly, so that's working great.

Some minor tinkering you might do involves fixing the size of your cards. Right now they inflate or deflate based on the size of what's showing which gives the board a somewhat choppy, fluctuating quality. Minor issue, but something you can fix with a few adjustments.

Overall good work, and I hope you spend some time fixing some of these things. Let us know if you have questions!


function GuiCtor(container, game) {
game.gui(this);

//Make sure container is an HTML element, and convert it to one if not

if (typeof container === "string") {
container = document.getElementById(container);
}

//Various variables necessary for the constructor methods
var gridSize = game.size();

var numRows = Math.floor(Math.sqrt(gridSize));

var cardsPerRow = Math.floor(gridSize / numRows);

var grid = document.createElement('table');
container.appendChild(grid);

var idCounter = 0; //Intialize counter for assigning unique IDs to cards


//Instance methods

this.show = function(where, displayString) {
var elem = document.getElementById(where);
elem.setAttribute('class', 'face-up');
elem.innerHTML = "<p class = 'cardText'>" + displayString + "</p>";
// This ^ doesn't work, but I already created the text in my rendering code below
};

this.hideSoon = function(whereArray) {
function hide(val) {
document.getElementById(val).setAttribute('class', 'face-down');
};
function hideAll() {
whereArray.forEach(hide);
};
var timer = window.setTimeout(hideAll, 500);
};

this.removeSoon = function(whereArray) {
//Need a callback for Array.forEach()
function remove(val) {
document.getElementById(val).setAttribute('class', 'matched');
};
function removeAll() {
whereArray.forEach(remove);
}
var timer = window.setTimeout(removeAll, 500);
};

this.reset = function() {
$('td').css('class', 'face-down');
game.reset();
};





//Render the table:
this.render = function() {
for (var i = 0; i<numRows; i++) {
var tempRow = document.createElement('tr');
board.appendChild(tempRow);
for(var j = 0; j<cardsPerRow; j++) {
var tempCard = document.createElement('td');
tempCard.setAttribute('id', idCounter); //Give it a unique ID
tempCard.setAttribute('class', 'face-down'); //Make each face-down

tempCard.innerHTML = '<p class = "cardText">A</p>';

tempRow.appendChild(tempCard);
idCounter++;
}
}
};

this.render();

//Instance methods

//Click events:

/*$('td').click(function() { // A function to make sure clicking is working
console.log('hello, I am card # ' + this.getAttribute('id'));
}); */

//The click (it could be in plain JS too) MUST GO here
// because the IIFE runs way too early for it to work outside
//the constructor. That's because the IIFE runs as soon as the
//file is mentioned, but the constructor isn't called that early
//The memory-main.js file delays the execution of the constructors
//until the document has loaded!
//And you CAN'T INTERACT WITH THE ELEMENTS BEFORE THEY'RE CREATED!!!

//Click event to trigger game.lift()

$('td').click(function(){ //Works when game is the DummyGame.js module
game.lift( parseInt(this.getAttribute('id') ) );
});

$("#reset").click(function(){
gui.reset();
console.log('Clicked reset')
});

}; //End Ctor



return GuiCtor;
})(); //End IIFE
9 changes: 9 additions & 0 deletions harrison/memory-main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var cards,game,gui; //global vars can been inspected in console, making debugging easier
function go() {
// you'll need to study the modules to understand how to plug them in...
cards = new RussEng();
game = new MemoryGame(cards);
gui = new MemoryGui('board',game); //'memorygame' is the id of div where gui should be inserted'
}

window.addEventListener("load",go);
Loading