Skip to content

Commit 24c3dc1

Browse files
committed
(#22) Memory Game Module
1 parent d09a403 commit 24c3dc1

File tree

18 files changed

+266
-1
lines changed

18 files changed

+266
-1
lines changed

src/app/components/example-modules/example-modules.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
(click)="active = 2"
1616
[class.active]="active === 2">Tic tac toe</a>
1717
</li>
18+
<li>
19+
<a class="ac-button md-default-theme"
20+
[router-link]=" ['./memory'] "
21+
(click)="active = 2"
22+
[class.active]="active === 2">Memory Game</a>
23+
</li>
1824
</ul>
1925
</nav>
2026

src/app/components/example-modules/example-modules.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {RouteConfig, routerDirectives} from 'angular2/router';
66
// Modules
77
import {Tictactoe} from './tictactoe-module/tictactoe';
88
import {Search} from './search-module/search';
9+
import {Memory} from './memory-module/memory';
910
// View
1011
let template = require('./example-modules.html');
1112
let styles = require('./example-modules.css')
@@ -15,7 +16,8 @@ let styles = require('./example-modules.css')
1516
@RouteConfig([
1617
{ path: '/', redirectTo: '/search' },
1718
{ path: '/search', as: 'search', component: Search },
18-
{ path: '/tictactoe', as: 'tictactoe', component: Tictactoe }
19+
{ path: '/tictactoe', as: 'tictactoe', component: Tictactoe },
20+
{ path: '/memory', as: 'memory', component: Memory }
1921
])
2022
@View({
2123
directives: [ routerDirectives, CSSClass ],
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// <reference path="../../../../../typings/_custom.d.ts" />
2+
3+
// Angular 2
4+
import {Component, View, EventEmitter, coreDirectives} from 'angular2/angular2';
5+
6+
let styles = require('../views/css/memory.css');
7+
let template = require('../views/card.html');
8+
9+
@Component({
10+
selector: 'card',
11+
properties: [ 'card' ],
12+
events: [ 'select' ]
13+
})
14+
@View({
15+
directives: [ coreDirectives ],
16+
styles: [styles],
17+
template: template
18+
})
19+
export class Card {
20+
select: EventEmitter = new EventEmitter();
21+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/// <reference path="../../../../typings/_custom.d.ts" />
2+
3+
// Angular 2
4+
import {Component, View, coreDirectives} from 'angular2/angular2';
5+
6+
// Services
7+
import {Game} from './services/game';
8+
9+
// Directives
10+
import {Card} from './directives/card';
11+
12+
// View
13+
let view = require('./views/memory.html');
14+
15+
@Component({
16+
selector: 'memory',
17+
viewBindings: [Game]
18+
})
19+
@View({
20+
directives: [coreDirectives, Card],
21+
template: view
22+
})
23+
export class Memory {
24+
constructor(public game: Game) {
25+
26+
}
27+
28+
reset() {
29+
this.game = Game.create();
30+
}
31+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/// <reference path="../../../../../typings/_custom.d.ts" />
2+
3+
import {Injectable} from 'angular2/angular2';
4+
import {Tile} from '../services/tile';
5+
6+
var tileNames = ['8-ball', 'kronos', 'baked-potato', 'dinosaur', 'rocket', 'skinny-unicorn',
7+
'that-guy', 'zeppelin'];
8+
var message = {
9+
CLICK:'Click on a tile.',
10+
ONE_MORE:'Pick one more card',
11+
MISS: 'Try again',
12+
MATCH: 'Good job! Keep going.',
13+
WON: 'You win!'
14+
};
15+
16+
@Injectable()
17+
export class Game {
18+
tileDeck: Array<Tile>;
19+
firstPick: Tile;
20+
grid: any;
21+
secondPick: Tile;
22+
message: string;
23+
unmatchedPairs: number;
24+
25+
constructor(tileNames) {
26+
this.tileDeck = this.makeDeck(tileNames);
27+
this.message = message.CLICK;
28+
this.unmatchedPairs = tileNames.length;
29+
this.firstPick = null;
30+
this.secondPick = null;
31+
this.grid = this.makeGrid(this.tileDeck);
32+
}
33+
34+
public static create(): Game {
35+
return new Game(tileNames);
36+
}
37+
38+
makeDeck(tileNames) {
39+
var tileDeck: Array<Tile> = [];
40+
for (name in tileNames) {
41+
tileDeck.push(new Tile(name));
42+
tileDeck.push(new Tile(name));
43+
}
44+
45+
return tileDeck;
46+
}
47+
48+
makeGrid(tileDeck) {
49+
var gridDimension = Math.sqrt(tileDeck.length);
50+
var grid = [];
51+
52+
for (var row = 0; row < gridDimension; row++) {
53+
grid[row] = [];
54+
for (var col = 0; col < gridDimension; col++) {
55+
grid[row][col] = this.removeRandomTile(tileDeck);
56+
}
57+
}
58+
59+
return grid;
60+
}
61+
62+
removeRandomTile(tileDeck) {
63+
var i = Math.floor(Math.random()*tileDeck.length);
64+
return tileDeck.splice(i, 1)[0];
65+
}
66+
67+
flipTile(tile) {
68+
if (tile.flipped) {
69+
return;
70+
}
71+
72+
tile.flip();
73+
74+
if(!this.firstPick || this.secondPick) {
75+
76+
if (this.secondPick) {
77+
this.firstPick.flip();
78+
this.secondPick.flip();
79+
this.firstPick = this.secondPick = undefined;
80+
}
81+
82+
this.firstPick = tile;
83+
this.message = message.ONE_MORE;
84+
85+
} else {
86+
if (this.firstPick.title === tile.title) {
87+
this.unmatchedPairs--;
88+
if (this.unmatchedPairs > 0) {
89+
this.message = message.WON;
90+
}
91+
this.firstPick = this.secondPick = undefined;
92+
} else {
93+
this.secondPick = tile;
94+
this.message = message.MISS;
95+
}
96+
}
97+
}
98+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// <reference path="../../../../../typings/_custom.d.ts" />
2+
3+
import {Injectable} from 'angular2/angular2';
4+
5+
@Injectable()
6+
export class Tile {
7+
title: string;
8+
flipped: boolean;
9+
10+
constructor(title: string) {
11+
this.title = title;
12+
this.flipped = false
13+
}
14+
15+
flip() {
16+
this.flipped = !this.flipped;
17+
}
18+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<div class="container">
2+
<div class="card" ng-class="{flipped: tile.flipped}">
3+
<img class="front" ng-src="img/back.png">
4+
<img class="back" ng-src="img/{{tile.title}}.png">
5+
</div>
6+
</div>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
.container {
2+
width: 165px;
3+
height: 200px;
4+
position: relative;
5+
-webkit-perspective: 800px;
6+
-moz-perspective: 800px;
7+
-ms-perspective: 800px;
8+
-o-perspective: 800px;
9+
perspective: 800px;
10+
}
11+
12+
.card {
13+
width: 100%;
14+
height: 100%;
15+
-webkit-transition: -webkit-transform 1s;
16+
-moz-transition: -moz-transform 1s;
17+
-ms-transition: -ms-transform 1s;
18+
-o-transition: -o-transform 1s;
19+
transition: transform 1s;
20+
-webkit-transform-style: preserve-3d;
21+
-moz-transform-style: preserve-3d;
22+
-ms-transform-style: preserve-3d;
23+
-o-transform-style: preserve-3d;
24+
transform-style: preserve-3d;
25+
}
26+
27+
.card.flipped {
28+
-webkit-transform: rotateY( 180deg );
29+
-moz-transform: rotateY( 180deg );
30+
-ms-transform: rotateY( 180deg );
31+
-o-transform: rotateY( 180deg );
32+
transform: rotateY( 180deg );
33+
}
34+
35+
.card img {
36+
display: block;
37+
height: 100%;
38+
width: 100%;
39+
position: absolute;
40+
-webkit-backface-visibility: hidden;
41+
-moz-backface-visibility: hidden;
42+
-ms-backface-visibility: hidden;
43+
-o-backface-visibility: hidden;
44+
backface-visibility: hidden;
45+
}
46+
47+
48+
49+
.card .back {
50+
background: blue;
51+
-webkit-transform: rotateY( 180deg );
52+
-moz-transform: rotateY( 180deg );
53+
-ms-transform: rotateY( 180deg );
54+
-o-transform: rotateY( 180deg );
55+
transform: rotateY( 180deg );
56+
}
57+
58+
.message {
59+
width: 660px;
60+
text-align: center;
61+
}
15.6 KB
Loading
24.2 KB
Loading

0 commit comments

Comments
 (0)