-
Notifications
You must be signed in to change notification settings - Fork 3
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
Natalie's HW 7 submission #3
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
|
||
// ----Example set 1:---- | ||
|
||
var FoodCards = (function() { | ||
// card values: | ||
var food = ['apple','artichoke','banana','blueberry','carrot','cranberry']; | ||
|
||
function Ctor() { | ||
this.values = function() { | ||
return food.slice(); //return copy of values | ||
}; | ||
this.match = function(str1,str2) { | ||
return str1[0]===str2[0]; //match if same initial letter | ||
}; | ||
this.display = function(val) { | ||
return val; //display value is just card val | ||
}; | ||
} | ||
|
||
return Ctor; | ||
|
||
})(); | ||
|
||
|
||
// ----Example set 2:---- | ||
|
||
var AnimalCards = (function() { | ||
|
||
// card values (each card is a pair, array [name,num]) : | ||
var animals = [ ['dog',1],['puppy',1], | ||
['cat',2],['kitten',2], | ||
['frog',3],['tadpole',3], | ||
['bird',4],['chick',4] ]; | ||
|
||
function Ctor() { | ||
this.values = function() { | ||
return animals.slice(); | ||
}; | ||
this.match = function(pair1,pair2) { //each pair is [name,num] | ||
return (pair1[1]===pair2[1]); // check if num matches | ||
}; | ||
this.display = function(val) { //val is pair [name,num] | ||
return val[0]; //display just the animal name | ||
}; | ||
} | ||
|
||
return Ctor; | ||
|
||
})(); | ||
|
||
// ----Example set 3:---- | ||
|
||
var AlphabetCards = (function() { | ||
// produces pairs 'a'=='A','b'=='B',... | ||
var alphabet = ' abcdefghijklmnopqrstuvwxyz'; | ||
|
||
function Ctor(numPairs) { //numPairs is optional; defaults to 26 | ||
if (numPairs < 1) numPairs = 1; | ||
if (!numPairs || (numPairs > 26)) numPairs = 26; | ||
|
||
// Generate subset of alphabet in pairs: | ||
var _values = []; //private array | ||
while (numPairs) { | ||
_values.push(alphabet[numPairs]); //'a'... | ||
_values.push(alphabet[numPairs].toUpperCase());//'A'... | ||
--numPairs; | ||
} | ||
|
||
// Instance methods: | ||
this.values = function() { | ||
return _values.slice(); | ||
} | ||
this.match = function(a,b) { | ||
return a.toUpperCase() == b.toUpperCase(); | ||
} | ||
this.display = function(val) { | ||
return val; | ||
} | ||
} | ||
|
||
return Ctor; | ||
|
||
})(); |
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; | ||
})(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// See cardset-example.js for examples | ||
|
||
var MemoryCards = (function() { | ||
|
||
// card values (each card is a pair, array [name,num]) : | ||
var animals = [ ['dog',1],['woofwoof!',1], | ||
['cat',2],['meowww',2], | ||
['frog',3],['ribbit',3], | ||
['horse',4],['neigh!!',4], | ||
['pig',5],['oink oink',5], | ||
['cow',6],['mmmooooo!',6], | ||
['donkey',7],['yeehaawww!',7], | ||
['duck',8],['quackkk',8] ]; | ||
|
||
function Ctor() { | ||
this.values = function() { | ||
return animals.slice(); | ||
}; | ||
this.match = function(pair1,pair2) { //each pair is [name,num] | ||
return (pair1[1]===pair2[1]); // check if num matches | ||
}; | ||
this.display = function(val) { //val is pair [name,num] | ||
return val[0]; //display just the animal name | ||
}; | ||
} | ||
|
||
return Ctor; | ||
|
||
})(); | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// This module is completely finished! You just need to understand how it works, then integrate it. | ||
|
||
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 | ||
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; | ||
})(); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* Whatever CSS you want for GUI...*/ | ||
|
||
|
||
#memorygame { | ||
width: 600px; | ||
margin-left: auto; | ||
margin-right: auto; | ||
text-align: center; | ||
font-family: 'Indie Flower', cursive; | ||
} | ||
|
||
h1 { | ||
font-size: 3em; | ||
} | ||
|
||
.cards { | ||
width: 125px; | ||
height: 106px; | ||
margin: 10px; | ||
float: left; | ||
border-radius: 15px; | ||
} | ||
.faceDown { | ||
background-image: url(kitty.jpg); | ||
background-size: 125px 106px; | ||
} | ||
|
||
.faceDown:hover { | ||
-ms-transform: rotate(-10deg); | ||
-webkit-transform: rotate(-10deg); | ||
-moz-transform: rotate(-10deg); | ||
-o-transform: rotate(-10deg); | ||
transform: rotate(-10deg); | ||
} | ||
|
||
.faceUp { | ||
background: #fb445a; | ||
vertical-align: middle; | ||
font-size: 1.2em; | ||
line-height: 106px; | ||
} | ||
|
||
.removed { | ||
background: white; | ||
} | ||
|
||
.resetButton { | ||
background: #fb445a; | ||
font-size: 1.2em; | ||
font-family: 'Indie Flower', cursive; | ||
border-radius: 5px; | ||
border: 1px solid black; | ||
margin-top: 10px; | ||
} | ||
|
||
.resetButton:hover { | ||
border: 2px solid black; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
var MemoryGUI = (function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your game looks great! I like the cards and the added hover effect in your css. The code is laid out appropriately, and your GUI is just responding to the wishes of the games logic and not making its own decisions, which is perfect. A few suggestions for enhancement: Currently you can have a number of cards face up at a time, I think I managed to face up about 5-6 of them in one go before they started disappearing. Try tinkering with the timeout delay value, or possibly disabling clicking while two cards are face up. Your code is pretty easy to read, especially considering that we're all aware of what we're about to walk into given that it's the homework! Try getting into the habit of leaving more comments however, as in the future this will help both you and anyone that needs to go over your code in knowing what they're looking at. And finally, a quirky little bug! Try clicking on one of your cards and then pressing reset. If you look above the cat's head you'll notice that the name of the previous card now appears above, faintly. This is regardless of whatever card happens to actually exist there. My assumption is that the bug lies in your reset function, which doesn't clear the inner html of the cards. Try to see if you can find out what's causing this! Great work overall. |
||
|
||
//... | ||
|
||
function GuiCtor(container,game) { | ||
game.gui(this); // link game to this gui | ||
//... | ||
|
||
// public instance methods | ||
// (you may instead attach these to a prototype if you prefer) | ||
this.reset = function() { | ||
game.reset(); | ||
var cardReset = document.getElementsByClassName('cards'); | ||
for (var i=0; i<cardReset.length; i++){ | ||
cardReset[i].setAttribute('class', 'cards faceDown'); | ||
} | ||
} | ||
|
||
this.show = function(where,displayString) { | ||
var showCard = document.getElementById(where); | ||
showCard.classList.remove('faceDown'); | ||
showCard.classList.add('faceUp'); | ||
showCard.innerHTML = displayString; | ||
} | ||
this.removeSoon = function(whereArr) { | ||
window.setTimeout(function() { | ||
whereArr.forEach(function(where) { | ||
var removeCard = document.getElementById(where) | ||
removeCard.innerHTML = ''; | ||
removeCard.classList.remove('faceUp'); | ||
removeCard.classList.add('removed'); | ||
}) | ||
}, 1000) | ||
} | ||
this.hideSoon = function(whereArr) { | ||
window.setTimeout(function() { | ||
whereArr.forEach(function(where) { | ||
var hideCard = document.getElementById(where) | ||
hideCard.innerHTML = ''; | ||
hideCard.classList.remove('faceUp'); | ||
hideCard.classList.add('faceDown'); | ||
}) | ||
}, 1000) | ||
} | ||
for(var i=0; i<game.size(); i++) { | ||
var div = document.createElement('div'); | ||
div.setAttribute('id', i); | ||
div.classList.add('faceDown'); | ||
div.classList.add('cards'); | ||
div.addEventListener('click', function() { | ||
var id = this.getAttribute('id'); | ||
game.lift((id*1)); | ||
}); | ||
document.getElementById(container).appendChild(div); | ||
} | ||
} | ||
|
||
return GuiCtor; | ||
})(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job! I love the CSS effects you added. You code is really easy to read and works well.