<!DOCTYPE html>
<html data-ng-app="theGame">
<head>
<link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script data-require="angular.js@*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body data-ng-controller="warBrain">
<h1>War!</h1>
<h2 ng-if="game.winner">Winner is <span ng-bind="game.winner"></span>. <button type="button" class="btn btn-info" ng-click="restart()">Play Again?</button></h2>
<div ng-if="!game.winner">
<button type="button" class="btn btn-std" ng-click="game.rounds(1)">Play one round</button>
<button type="button" class="btn btn-warning" ng-click="game.rounds(10)">Play ten rounds</button>
<button type="button" class="btn btn-danger" ng-click="game.rounds(100)">Play one hundred rounds</button>
<hr>
<div class="player1">
<strong>Player 1 </strong> has {{ game.player1.totalCards() }} cards
</div>
<div class="player2">
<strong>Player 2 </strong> has {{ game.player2.totalCards() }} cards
</div>
</div>
<hr>
<div class="round-cards" data-ng-repeat="rnd in game.log | orderBy:'-number'">
<strong>Round {{rnd.number}} cards:</strong>
<ul>
<li data-ng-repeat="card in rnd.p1active">Player 1: {{card.display}}</li>
<li data-ng-repeat="card in rnd.p2active">Player 2: {{card.display}}</li>
</ul>
<strong>Round winner: {{rnd.round_winner}}</strong>
<ul>
<li>Resulting Cards Player 1: <strong>{{rnd.p1total}}</strong></li>
<li>Resulting Cards Player 2: <strong>{{rnd.p2total}}</strong></li>
</ul>
<hr>
</div>
<script src="script2.js"></script>
</body>
</html>
var theApp = angular.module("theGame",[]);
/*
@Stack class
*** is a stack of cards, can be shuffled, can absorb other stacks
*/
var Stack = function(arr){
this.els = arr || [];
this.shuffle = function(){
var i = 0, r, temp;
for(i = 0; i < this.els.length; i++){
r = Math.floor(Math.random()*(this.els.length-i));
temp = this.els[i];
this.els[i] = this.els[this.els.length-1-r];
this.els[this.els.length-1-r] = temp;
}
return this.els;
};
this.nextCard = function(){
if (!this.isEmpty()){
return this.els[this.els.length - 1];
} else {
return false;
}
};
this.addCards = function(arr){
this.els = this.els.concat(arr);
};
this.addStack = function(stack){
this.addCards(stack.els);
stack.els = [];
};
this.length = function(){
return this.els.length;
};
this.isEmpty = function(){
return this.els.length === 0;
};
this.drawCard = function(){
if (this.isEmpty()){
return false;
} else {
return this.els.pop();
}
};
this.drawCards = function(n){
var returnStack = new Stack([]);
for (var i = 0; i < n; i++){
var nextCard = this.drawCard();
if (!nextCard){
return returnStack;
} else {
returnStack.addCards([nextCard]);
}
}
return returnStack;
};
};
/*
@Player
*** Represents a War Player, has a deck, discard, active
*** Knows how to shuffle discard to replenish deck
*** if asked to draw more cards than is possible returns false
*/
var Player = function(){
this.deck = new Stack([]);
this.discard = new Stack([]);
this.active = new Stack([]);
this.drawCards = function(n){
var player = this;
var drawn = new Stack([]);
var deck_size = player.deck.length();
if (deck_size >= n){
drawn = player.deck.drawCards(n);
} else if (player.discard.length() + deck_size >= n) {
player.discard.shuffle();
player.deck.addStack(player.discard);
drawn = player.deck.drawCards(n);
} else {
player.discard.shuffle();
player.deck.addStack(player.discard);
drawn = player.deck.drawCards(player.deck.length());
player.active.addStack(drawn);
return false;
}
player.active.addStack(drawn);
return true;
};
this.totalCards = function(){
return this.deck.length() + this.discard.length();
};
this.winCards = function(stack){
this.discard.addStack(stack);
};
this.getCards = function(stack){
this.deck.addStack(stack);
};
};
/*
@WarGame
*** A war game model
*** creates a standard deck, distributes cards, logs rounds
*** in each round checks for a war and if so draws an extra four until
*** someone is exhausted or the war is resolved
*/
var WarGame = function(){
var game = this;
var game_over = new Event("game-over");
var ranks = ["2","3","4","5","6","7","8","9","T","J","Q","K","A"];
var suits = [" of hearts", " of diamonds", " of clubs", " of spades"];
var cards = [];
for (var i = 0; i < ranks.length; i++){
for (var j = 0; j < suits.length; j++){
cards.push({ display : ranks[i] + suits[j], value : i });
}
}
game.deck = new Stack(cards);
game.deck.shuffle();
game.player1 = new Player();
game.player2 = new Player();
game.log = [];
game.player1.getCards(game.deck.drawCards(26));
game.player2.getCards(game.deck.drawCards(26));
game.winner = false;
game.round_winner = false;
game.round_number = 0;
game.end = function(winner){
game.logRound();
game.winner = winner;
};
game.logRound = function(){
var prettyWinner = function(result){
if (result == 1){
return "Player 1";
} else if (result == -1){
return "Player 2";
} else {
return "NA";
}
};
var p1a = angular.copy(game.player1.active.els);
var p2a = angular.copy(game.player2.active.els);
if (game.round_winner == 1){
game.player1.winCards(game.player1.active);
game.player1.winCards(game.player2.active);
} else if (game.round_winner == -1) {
game.player2.winCards(game.player1.active);
game.player2.winCards(game.player2.active);
}
var thisRound = {
number : game.round_number,
p1active : p1a,
p1total : game.player1.totalCards(),
p2active : p2a,
p2total : game.player2.totalCards(),
round_winner : prettyWinner(game.round_winner)
};
game.log.push(thisRound);
};
game.rounds = function(n){
for (var i = 0; (i < n) && !game.winner; i++){
game.round();
}
};
game.round = function(){
game.round_number += 1;
var winner = function(){
var v1 = game.player1.active.nextCard().value;
var v2 = game.player2.active.nextCard().value;
if (v1 == v2){
return 0;
} else if (v1 > v2 ){
return 1;
} else if (v1 < v2 ){
return -1;
}
};
if (!game.player1.drawCards(1)){
game.round_winner = -1;
game.end("Player 2");
return;
}
if (!game.player2.drawCards(1)){
game.round_winner = 1;
game.end("Player 1");
return;
}
game.round_winner = winner();
var counter = 0;
var game_over = false;
while ((game.round_winner === 0) && counter < 100){
counter += 1;
if (!game.player1.drawCards(4)){
game.round_winner = -1;
game.end("Player 2");
game_over = true;
}
if (!game.player2.drawCards(4)){
game.round_winner = 1;
game.end("Player 1");
game_over = true;
}
if (game_over){
return;
}
game.round_winner = winner();
}
game.logRound();
};
};
/*
@WarBrain
*** This controller is the bridge between the data model
*** and the HTML display, index.html has most of the display
*** logic.
*/
theApp.controller("warBrain",["$scope", function($scope){
$scope.game = new WarGame();
$scope.restart = function(){
$scope.game = new WarGame();
};
}]);
/* Styles go here */
body {
margin-left: 2em;
}