- fix formatting in css file

- add some templates for game lobbies
- client properly joins a game and shows the lobby!
- reconnect to in-progress game when refreshing page
This commit is contained in:
Andy Janata 2012-01-22 23:58:36 -08:00
parent 109a58444a
commit 8e3c1372dc
14 changed files with 618 additions and 155 deletions

View File

@ -25,8 +25,7 @@
*/ */
} }
#canvas { #canvas { /* * /
/* * /
display: none; display: none;
/* */ /* */
height: 750px; height: 750px;
@ -46,16 +45,17 @@
border: 1px solid black; border: 1px solid black;
} }
#main_holder {
width: 100%;
height: 100%;
}
#game_list { #game_list {
height: 100%; height: 100%;
width: 100%; width: 100%;
overflow: auto; overflow: auto;
} }
.template {
display: none;
}
.gamelist_lobby { .gamelist_lobby {
width: 32%; width: 32%;
height: 100px; height: 100px;
@ -94,6 +94,14 @@
color: #c0c0c0; color: #c0c0c0;
} }
#info_area {
width: 50%;
height: 215px;
border: 0px;
position: absolute;
bottom: 0px;
}
#chat_area { #chat_area {
width: 50%; width: 50%;
height: 215px; height: 215px;
@ -110,7 +118,7 @@
position: absolute; position: absolute;
bottom: 17px; bottom: 17px;
right: 0px; right: 0px;
overflow: auto; overflow-y: scroll;
} }
#chat { #chat {
@ -153,7 +161,13 @@ span.debug {
font-family: Arial, Verdana, san-serif; font-family: Arial, Verdana, san-serif;
font-size: 16pt; font-size: 16pt;
float: left; float: left;
zoom: .35;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
} }
.blackcard { .blackcard {
@ -186,8 +200,8 @@ span.debug {
.header { .header {
position: absolute; position: absolute;
top: 0px; bottom: 0px;
left: 0px; right: 5px;
} }
.game_hand { .game_hand {
@ -203,9 +217,34 @@ span.debug {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
height: 100%; height: 100%;
zoom: .35;
cursor: pointer;
} }
.card_holder { .card_holder {
float: left; float: left;
position: relative; position: relative;
} }
.scoreboard {
width: 150px;
height: 100%;
border: 1px solid black;
overflow-y: scroll;
}
.scorecard {
height: 36px;
padding: 2px;
border-bottom: 1px solid black;
font-size: 11pt;
}
.scorecard_status {
float: right;
margin-right: 5px;
}
.clear {
clear: both;
}

View File

@ -40,8 +40,10 @@
<div id="canvas"> <div id="canvas">
<div id="menubar"> <div id="menubar">
<div id="menubar_left"> <div id="menubar_left">
<input type="button" id="refresh_games" value="Refresh Games" /> <input type="button" id="refresh_games" class="hide" value="Refresh Games" />
<input type="button" id="create_game" value="Create Game" /> <input type="button" id="create_game" class="hide" value="Create Game" />
<input type="button" id="leave_game" class="hide" value="Leave Game" />
<input type="button" id="start_game" class="hide" value="Start Game" />
</div> </div>
<div id="menubar_right"> <div id="menubar_right">
<input type="button" id="logout" value="Log out" /> <input type="button" id="logout" value="Log out" />
@ -50,6 +52,10 @@
<div id="main"> <div id="main">
<div id="game_list" class="hide"> <div id="game_list" class="hide">
</div> </div>
<div id="main_holder">
</div>
</div>
<div id="info_area">
</div> </div>
<div id="chat_area"> <div id="chat_area">
<div id="log"></div> <div id="log"></div>
@ -59,7 +65,7 @@
</div> </div>
<!-- Template for game lobbies in the game list. --> <!-- Template for game lobbies in the game list. -->
<div id="gamelist_lobby_template" class="gamelist_lobby template"> <div id="gamelist_lobby_template" class="gamelist_lobby hide">
<div class="gamelist_lobby_left"> <div class="gamelist_lobby_left">
Game <span class="gamelist_lobby_id">###</span> Game <span class="gamelist_lobby_id">###</span>
<span class="gamelist_lobby_status">status</span> <span class="gamelist_lobby_status">status</span>
@ -74,35 +80,52 @@
</div> </div>
<!-- Template for face-up black cards. --> <!-- Template for face-up black cards. -->
<div id="black_up_template" class="card blackcard template"> <div id="black_up_template" class="card blackcard hide">
<span class="card_text">The quick brown fox jumped over the lazy dog.</span> <span class="card_text">The quick brown fox jumped over the lazy dog.</span>
<img src="img/cah-black.png" class="cah" alt="Cards Against Humanity" /> <img src="img/cah-black.png" class="cah" alt="Cards Against Humanity" />
</div> </div>
<!-- Template for face-down black cards. --> <!-- Template for face-down black cards. -->
<div id="black_down_template" class="card blackcard template"> <div id="black_down_template" class="card blackcard hide">
</div> </div>
<!-- Template for face-up white cards. --> <!-- Template for face-up white cards. -->
<div id="white_up_template" class="card whitecard template"> <div id="white_up_template" class="card whitecard hide">
<span class="card_text">The quick brown fox jumped over the lazy dog.</span> <span class="card_text">The quick brown fox jumped over the lazy dog.</span>
<img src="img/cah-white.png" class="cah" alt="Cards Against Humanity" /> <img src="img/cah-white.png" class="cah" alt="Cards Against Humanity" />
</div> </div>
<!-- Template for face-down white cards. --> <!-- Template for face-down white cards. -->
<div id="white_down_template" class="card whitecard template"> <div id="white_down_template" class="card whitecard hide">
</div> </div>
<!-- Template for game lobbies. We have a holder here for designing only. --> <!-- Template for game lobbies. We have a holder here for designing only. -->
<div style="width: 1000px; height: 506px; border: 1px solid black; position: relative;"> <div style="width: 1000px; height: 506px; border: 1px solid black; position: relative;"
<div id="game_template" class="game"> class="hide">
<div id="game_template" class="game hide">
<div class="game_hand"> <div class="game_hand">
<!-- <span class="header">Your Hand:</span> --> <span class="header">Your Hand</span>
<div class="game_hand_cards"> <div class="game_hand_cards">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Template for scoreboard container. Holder for design. -->
<div style="height: 215px; border: 1px solid black;" class="hide">
<div id="scoreboard_template" class="scoreboard hide">
</div>
</div>
<!-- Template for scoreboard score card. Holder for design. -->
<div class="scoreboard hide" style="height: 215px;">
<div id="scorecard_template" class="scorecard hide">
<span class="scorecard_player">PlayerName</span>
<div class="clear"></div>
<span class="scorecard_score">0</span> points
<span class="scorecard_status">Status</span>
</div>
</div>
</body> </body>
</html> </html>

View File

@ -29,6 +29,18 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
$("#nickbox").hide(); $("#nickbox").hide();
$("#canvass").show(); $("#canvass").show();
cah.ajax.after_registered(); cah.ajax.after_registered();
switch (data[cah.$.AjaxResponse.NEXT]) {
case cah.$.ReconnectNextAction.GAME:
cah.log.status("Reconnecting to game...");
cah.Game.joinGame(data[cah.$.AjaxResponse.GAME_ID]);
break;
case cah.$.ReconnectNextAction.NONE:
// pass
break;
default:
cah.log.error("Unknown reconnect next action " + data[cah.$.AjaxResponse.NEXT]);
}
} }
}; };
@ -67,10 +79,12 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GAME_LIST] = function(data) {
cah.GameList.instance.processUpdate(data); cah.GameList.instance.processUpdate(data);
}; };
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.CREATE_GAME] = function(data) {
// switch over to the game view and request information about it
};
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME] = function(data) { cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME] = function(data) {
cah.Game.joinGame(data[cah.$.AjaxResponse.GAME_ID]);
};
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.CREATE_GAME] = cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME];
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GET_GAME_INFO] = function(data) {
cah.currentGame.updateGameStatus(data);
}; };

View File

@ -175,14 +175,14 @@ cah.inherits(cah.card.BlackCard, cah.card.BaseCard);
cah.card.BlackCard.prototype.getFaceDown_ = function() { cah.card.BlackCard.prototype.getFaceDown_ = function() {
var temp = $("#black_down_template").clone()[0]; var temp = $("#black_down_template").clone()[0];
temp.id = "black_down_" + this.id_; temp.id = "black_down_" + this.id_;
$(temp).removeClass("template"); $(temp).removeClass("hide");
return temp; return temp;
}; };
cah.card.BlackCard.prototype.getFaceUp_ = function() { cah.card.BlackCard.prototype.getFaceUp_ = function() {
var temp = $("#black_up_template").clone()[0]; var temp = $("#black_up_template").clone()[0];
temp.id = "black_up_" + this.id_; temp.id = "black_up_" + this.id_;
$(temp).removeClass("template"); $(temp).removeClass("hide");
return temp; return temp;
}; };
@ -206,14 +206,14 @@ cah.inherits(cah.card.WhiteCard, cah.card.BaseCard);
cah.card.WhiteCard.prototype.getFaceDown_ = function() { cah.card.WhiteCard.prototype.getFaceDown_ = function() {
var temp = $("#white_down_template").clone()[0]; var temp = $("#white_down_template").clone()[0];
temp.id = "white_down_" + this.id_; temp.id = "white_down_" + this.id_;
$(temp).removeClass("template"); $(temp).removeClass("hide");
return temp; return temp;
}; };
cah.card.WhiteCard.prototype.getFaceUp_ = function() { cah.card.WhiteCard.prototype.getFaceUp_ = function() {
var temp = $("#white_up_template").clone()[0]; var temp = $("#white_up_template").clone()[0];
temp.id = "white_up_" + this.id_; temp.id = "white_up_" + this.id_;
$(temp).removeClass("template"); $(temp).removeClass("hide");
return temp; return temp;
}; };

View File

@ -10,6 +10,7 @@ cah.$.AjaxOperation.FIRST_LOAD = "firstload";
cah.$.AjaxOperation.LOG_OUT = "logout"; cah.$.AjaxOperation.LOG_OUT = "logout";
cah.$.AjaxOperation.GAME_LIST = "games"; cah.$.AjaxOperation.GAME_LIST = "games";
cah.$.AjaxOperation.JOIN_GAME = "join_game"; cah.$.AjaxOperation.JOIN_GAME = "join_game";
cah.$.AjaxOperation.GET_GAME_INFO = "get_game_info";
cah.$.AjaxOperation.REGISTER = "register"; cah.$.AjaxOperation.REGISTER = "register";
cah.$.AjaxOperation.CREATE_GAME = "create_game"; cah.$.AjaxOperation.CREATE_GAME = "create_game";
cah.$.AjaxOperation.CHAT = "chat"; cah.$.AjaxOperation.CHAT = "chat";
@ -31,7 +32,9 @@ cah.$.AjaxResponse = function() {
cah.$.AjaxResponse.prototype.dummy = undefined; cah.$.AjaxResponse.prototype.dummy = undefined;
cah.$.AjaxResponse.NEXT = "next"; cah.$.AjaxResponse.NEXT = "next";
cah.$.AjaxResponse.GAME_ID = "game_id"; cah.$.AjaxResponse.GAME_ID = "game_id";
cah.$.AjaxResponse.GAME_INFO = "game_info";
cah.$.AjaxResponse.ERROR = "error"; cah.$.AjaxResponse.ERROR = "error";
cah.$.AjaxResponse.PLAYER_INFO = "player_info";
cah.$.AjaxResponse.ERROR_CODE = "error_code"; cah.$.AjaxResponse.ERROR_CODE = "error_code";
cah.$.AjaxResponse.SERIAL = "serial"; cah.$.AjaxResponse.SERIAL = "serial";
cah.$.AjaxResponse.MAX_GAMES = "max_games"; cah.$.AjaxResponse.MAX_GAMES = "max_games";
@ -95,6 +98,28 @@ cah.$.GameInfo.STATE = "state";
cah.$.GameInfo.PLAYERS = "players"; cah.$.GameInfo.PLAYERS = "players";
cah.$.GameInfo.ID = "id"; cah.$.GameInfo.ID = "id";
cah.$.GamePlayerInfo = function() {
// pass
};
cah.$.GamePlayerInfo.prototype.dummy = undefined;
cah.$.GamePlayerInfo.NAME = "name";
cah.$.GamePlayerInfo.SCORE = "score";
cah.$.GamePlayerInfo.STATUS = "status";
cah.$.GamePlayerStatus = function() {
// pass
};
cah.$.GamePlayerStatus.prototype.dummy = undefined;
cah.$.GamePlayerStatus.IDLE = "idle";
cah.$.GamePlayerStatus.PLAYING = "playing";
cah.$.GamePlayerStatus.JUDGE = "judge";
cah.$.GamePlayerStatus.JUDGING = "judging";
cah.$.GamePlayerStatus_msg = {};
cah.$.GamePlayerStatus_msg['playing'] = "Playing";
cah.$.GamePlayerStatus_msg['idle'] = "";
cah.$.GamePlayerStatus_msg['judging'] = "Judging";
cah.$.GamePlayerStatus_msg['judge'] = "Judge";
cah.$.GameState = function() { cah.$.GameState = function() {
// pass // pass
}; };
@ -129,3 +154,10 @@ cah.$.LongPollResponse.ERROR_CODE = "error_code";
cah.$.LongPollResponse.TIMESTAMP = "timestamp"; cah.$.LongPollResponse.TIMESTAMP = "timestamp";
cah.$.LongPollResponse.NICKNAME = "nickname"; cah.$.LongPollResponse.NICKNAME = "nickname";
cah.$.ReconnectNextAction = function() {
// pass
};
cah.$.ReconnectNextAction.prototype.dummy = undefined;
cah.$.ReconnectNextAction.GAME = "game";
cah.$.ReconnectNextAction.NONE = "none";

View File

@ -28,7 +28,45 @@ cah.Game = function(id) {
* @private * @private
*/ */
this.element_ = $("#game_template").clone()[0]; this.element_ = $("#game_template").clone()[0];
$(this.element_).removeClass("template"); $(this.element_).removeClass("hide");
/**
* The element for the scoreboard for this game.
*
* @type {HTMLDivElement}
* @private
*/
this.scoreboardElement_ = $("#scoreboard_template").clone()[0];
$(this.scoreboardElement_).removeClass("hide");
/**
* User->value mapping of scorecards in the scoreboard.
*
* @type {Object}
* @private
*/
this.scoreCards_ = {};
/**
* The cards in the player's hand.
*
* @type {Array}
* @private
*/
this.hand_ = Array();
};
/**
* Load game data from the server and display the game lobby.
*
* @param {number}
* gameId The game id.
*/
cah.Game.joinGame = function(gameId) {
cah.Ajax.build(cah.$.AjaxOperation.GET_GAME_INFO).withGameId(gameId).run();
cah.GameList.instance.hide();
cah.currentGame = new cah.Game(gameId);
cah.currentGame.insertIntoDocument();
}; };
/** /**
@ -38,22 +76,20 @@ cah.Game.prototype.getElement = function() {
return this.element_; return this.element_;
}; };
$(document).ready(function() { /**
var game = new cah.Game(0); * Add a card to the player's hand.
$("#main").append(game.getElement()); *
* @param {cah.card.WhiteCard}
var cards = Array(); * card Card to add to hand.
for ( var i = 0; i < 10; i++) { */
var card = new cah.card.BlackCard(true); cah.Game.prototype.dealtCard = function(card) {
card.setText("This is card " + i); this.hand_.push(card);
cards.push(card); jQuery(".game_hand_cards", this.element_).append(card.getElement());
jQuery(".game_hand_cards", game.getElement()).append(card.getElement());
var data = { var data = {
card : card.getElement() card : card.getElement()
}; };
var options = { var options = {
duration : 500, duration : 200,
queue : false queue : false
}; };
$(card.getElement()).mouseenter(data, function(e) { $(card.getElement()).mouseenter(data, function(e) {
@ -65,6 +101,127 @@ $(document).ready(function() {
zoom : 1 zoom : 1
}, options); }, options);
}); });
};
cah.Game.prototype.insertIntoDocument = function() {
$("#main_holder").empty().append(this.element_);
$("#info_area").empty().append(this.scoreboardElement_);
$("#leave_game").removeClass("hide");
// TODO display a loading animation
};
/**
* Update game status display.
*
* @param {Object}
* data Game data returned from server.
*/
cah.Game.prototype.updateGameStatus = function(data) {
if (data[cah.$.AjaxResponse.GAME_INFO][cah.$.GameInfo.HOST] == cah.nickname
&& data[cah.$.AjaxResponse.GAME_INFO][cah.$.GameInfo.STATE] == cah.$.GameState.LOBBY) {
$("#start_game").removeClass("hide");
} else {
$("#start_game").addClass("hide");
} }
}); var playerInfos = data[cah.$.AjaxResponse.PLAYER_INFO];
for ( var index in playerInfos) {
var thisInfo = playerInfos[index];
var playerName = thisInfo[cah.$.GamePlayerInfo.NAME];
var panel = this.scoreCards_[playerName];
if (!panel) {
// new score panel
panel = new cah.GameScorePanel(playerName);
$(this.scoreboardElement_).append(panel.getElement());
// TODO remove panels for players that have left the game? or just on the event?
}
panel.update(thisInfo[cah.$.GamePlayerInfo.SCORE], thisInfo[cah.$.GamePlayerInfo.STATUS]);
}
};
// /**
// * Remove a card from the hand.
// *
// * @param {number|cah.card.WhiteCard}
// * card If number, index of card to remove. If cah.card.WhiteCard, card instance to remove.
// */
// cah.Game.prototype.removeCard = function(card) {
//
// };
// ///////////////////////////////////////////////
/**
* Create a scoreboard panel for a player.
*
* @param {String}
* player Player name.
* @constructor
*/
cah.GameScorePanel = function(player) {
/**
* Player name.
*
* @type {String}
* @private
*/
this.player_ = player;
/**
* @type {HTMLDivElement}
* @private
*/
this.element_ = $("#scorecard_template").clone()[0];
$(this.element_).removeClass("hide");
/**
* The score on this scorecard.
*
* @type {number}
* @private
*/
this.score_ = 0;
/**
* The status of the player for this scorecard.
*
* @type {cah.$.GamePlayerStatus}
* @private
*/
this.status_ = cah.$.GamePlayerStatus.IDLE;
jQuery(".scorecard_player", this.element_).text(player);
this.update(this.score_, this.status_);
};
cah.GameScorePanel.prototype.getElement = function() {
return this.element_;
};
/**
* Update the score panel.
*
* TODO add some color for different statuses
*
* @param {number}
* score The player's score
* @param {cah.$.GamePlayerStatus}
* status The player's status.
*/
cah.GameScorePanel.prototype.update = function(score, status) {
this.score_ = score;
this.status_ = status;
jQuery(".scorecard_score", this.element_).text(score);
jQuery(".scorecard_status", this.element_).text(cah.$.GamePlayerStatus_msg[status]);
};
// $(document).ready(function() {
// var game = new cah.Game(0);
// $("#main_holder").append(game.getElement());
//
// for ( var i = 0; i < 10; i++) {
// var card = new cah.card.WhiteCard(true);
// card.setText("This is card " + i);
// game.dealtCard(card);
// }
// });

View File

@ -33,11 +33,23 @@ $(document).ready(function() {
}); });
cah.GameList.prototype.show = function() { cah.GameList.prototype.show = function() {
$(this.element_).removeClass("hide"); $(this.element_).show();
$("#create_game").show();
$("#refresh_games").show();
// $(this.element_).removeClass("hide");
// $("#create_game").removeClass("hide");
// $("#refresh_games").removeClass("hide");
}; };
cah.GameList.prototype.hide = function() { cah.GameList.prototype.hide = function() {
$(this.element_).addClass("hide"); $(this.element_).hide();
$("#create_game").hide();
$("#refresh_games").hide();
// $(this.element_).addClass("hide");
// $("#create_game").addClass("hide");
// $("#refresh_games").addClass("hide");
}; };
cah.GameList.prototype.update = function() { cah.GameList.prototype.update = function() {
@ -126,7 +138,7 @@ cah.GameListLobby = function(parentElem, data) {
this.element_.id = "gamelist_lobby_" + this.id_; this.element_.id = "gamelist_lobby_" + this.id_;
$(parentElem).append(this.element_); $(parentElem).append(this.element_);
$(this.element_).removeClass("template"); $(this.element_).removeClass("hide");
jQuery(".gamelist_lobby_id", this.element_).text(this.id_); jQuery(".gamelist_lobby_id", this.element_).text(this.id_);
jQuery(".gamelist_lobby_host", this.element_).text(data[cah.$.GameInfo.HOST]); jQuery(".gamelist_lobby_host", this.element_).text(data[cah.$.GameInfo.HOST]);
jQuery(".gamelist_lobby_players", this.element_).text(data[cah.$.GameInfo.PLAYERS].join(", ")); jQuery(".gamelist_lobby_players", this.element_).text(data[cah.$.GameInfo.PLAYERS].join(", "));

View File

@ -1,8 +1,22 @@
var cah = {}; var cah = {};
cah.DEBUG = true; cah.DEBUG = true;
/**
* This client's nickname.
*
* @type {string}
*/
cah.nickname = ""; cah.nickname = "";
/**
* The current game this client is playing in. This may be a list later if I expand to multiple
* concurrent game support.
*
* @type {cah.Game}
*/
cah.currentGame = undefined;
/** /**
* Binds a function to a "this object". Result is a new function that will do the right thing across * Binds a function to a "this object". Result is a new function that will do the right thing across
* contexts. * contexts.

View File

@ -35,11 +35,28 @@ public class Constants {
} }
} }
public enum ReconnectNextAction {
GAME("game"),
NONE("none");
private final String action;
ReconnectNextAction(final String action) {
this.action = action;
}
@Override
public String toString() {
return action;
}
}
public enum AjaxOperation { public enum AjaxOperation {
CHAT("chat"), CHAT("chat"),
CREATE_GAME("create_game"), CREATE_GAME("create_game"),
FIRST_LOAD("firstload"), FIRST_LOAD("firstload"),
GAME_LIST("games"), GAME_LIST("games"),
GET_GAME_INFO("get_game_info"),
JOIN_GAME("join_game"), JOIN_GAME("join_game"),
LOG_OUT("logout"), LOG_OUT("logout"),
NAMES("names"), NAMES("names"),
@ -80,12 +97,14 @@ public class Constants {
ERROR("error"), ERROR("error"),
ERROR_CODE("error_code"), ERROR_CODE("error_code"),
GAME_ID("game_id"), GAME_ID("game_id"),
GAME_INFO("game_info"),
GAMES("games"), GAMES("games"),
IN_PROGRESS("in_progress"), IN_PROGRESS("in_progress"),
MAX_GAMES("max_games"), MAX_GAMES("max_games"),
NAMES("names"), NAMES("names"),
NEXT("next"), NEXT("next"),
NICKNAME("nickname"), NICKNAME("nickname"),
PLAYER_INFO("player_info"),
SERIAL(AjaxRequest.SERIAL.toString()); SERIAL(AjaxRequest.SERIAL.toString());
private final String field; private final String field;
@ -232,4 +251,46 @@ public class Constants {
return key; return key;
} }
} }
public enum GamePlayerInfo {
NAME("name"),
SCORE("score"),
STATUS("status");
private final String key;
GamePlayerInfo(final String key) {
this.key = key;
}
@Override
public String toString() {
return key;
}
}
public enum GamePlayerStatus implements Localizable {
IDLE("idle", ""),
JUDGE("judge", "Judge"),
JUDGING("judging", "Judging"),
PLAYING("playing", "Playing");
private final String status;
private final String message;
GamePlayerStatus(final String status, final String message) {
this.status = status;
this.message = message;
}
@Override
public String toString() {
return status;
}
@Override
public String getString() {
return message;
}
}
} }

View File

@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import net.socialgamer.cah.Constants.GameInfo; import net.socialgamer.cah.Constants.GameInfo;
import net.socialgamer.cah.Constants.GamePlayerInfo;
import net.socialgamer.cah.Constants.GamePlayerStatus;
import net.socialgamer.cah.Constants.GameState; import net.socialgamer.cah.Constants.GameState;
import net.socialgamer.cah.Constants.LongPollResponse; import net.socialgamer.cah.Constants.LongPollResponse;
import net.socialgamer.cah.Constants.ReturnableData; import net.socialgamer.cah.Constants.ReturnableData;
@ -148,6 +150,23 @@ public class Game {
return info; return info;
} }
public List<Map<GamePlayerInfo, Object>> getPlayerInfo() {
final List<Map<GamePlayerInfo, Object>> info;
synchronized (players) {
info = new ArrayList<Map<GamePlayerInfo, Object>>(
players.size());
for (final Player player : players) {
final Map<GamePlayerInfo, Object> playerInfo = new HashMap<GamePlayerInfo, Object>();
playerInfo.put(GamePlayerInfo.NAME, player.getUser().getNickname());
playerInfo.put(GamePlayerInfo.SCORE, player.getScore());
// TODO fix this once we actually have gameplay logic
playerInfo.put(GamePlayerInfo.STATUS, GamePlayerStatus.PLAYING.toString());
info.add(playerInfo);
}
}
return info;
}
public void start() { public void start() {
state = GameState.DEALING; state = GameState.DEALING;
// TODO deal // TODO deal

View File

@ -1,9 +1,16 @@
package net.socialgamer.cah.data; package net.socialgamer.cah.data;
import java.util.LinkedList;
import java.util.List;
import net.socialgamer.cah.db.WhiteCard;
public class Player { public class Player {
private final User user; private final User user;
// TODO add their hand, etc. private final List<WhiteCard> hand = new LinkedList<WhiteCard>();
private int score = 0;
public Player(final User user) { public Player(final User user) {
this.user = user; this.user = user;
@ -13,6 +20,18 @@ public class Player {
return user; return user;
} }
public int getScore() {
return score;
}
public void increaseScore() {
score++;
}
public List<WhiteCard> getHand() {
return hand;
}
@Override @Override
public String toString() { public String toString() {
return user.toString(); return user.toString();

View File

@ -7,6 +7,7 @@ import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation; import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxResponse; import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ReconnectNextAction;
import net.socialgamer.cah.Constants.ReturnableData; import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.Constants.SessionAttribute; import net.socialgamer.cah.Constants.SessionAttribute;
import net.socialgamer.cah.RequestWrapper; import net.socialgamer.cah.RequestWrapper;
@ -38,8 +39,15 @@ public class FirstLoadHandler extends Handler {
// and tell the client where to continue from. // and tell the client where to continue from.
// Right now we just tell them what their name is. // Right now we just tell them what their name is.
ret.put(AjaxResponse.IN_PROGRESS, Boolean.TRUE); ret.put(AjaxResponse.IN_PROGRESS, Boolean.TRUE);
ret.put(AjaxResponse.NEXT, ""); // TODO
ret.put(AjaxResponse.NICKNAME, user.getNickname()); ret.put(AjaxResponse.NICKNAME, user.getNickname());
// TODO more
if (user.getGame() != null) {
ret.put(AjaxResponse.NEXT, ReconnectNextAction.GAME.toString());
ret.put(AjaxResponse.GAME_ID, user.getGame().getId());
} else {
ret.put(AjaxResponse.NEXT, ReconnectNextAction.NONE.toString());
}
} }
return ret; return ret;

View File

@ -0,0 +1,64 @@
package net.socialgamer.cah.handlers;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxRequest;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ErrorCode;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.Constants.SessionAttribute;
import net.socialgamer.cah.RequestWrapper;
import net.socialgamer.cah.data.Game;
import net.socialgamer.cah.data.GameManager;
import net.socialgamer.cah.data.User;
import com.google.inject.Inject;
public class GetGameInfoHandler extends Handler {
public static final String OP = AjaxOperation.GET_GAME_INFO.toString();
private final GameManager gameManager;
@Inject
public GetGameInfoHandler(final GameManager gameManager) {
this.gameManager = gameManager;
}
@Override
public Map<ReturnableData, Object> handle(final RequestWrapper request, final HttpSession session) {
final Map<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
final User user = (User) session.getAttribute(SessionAttribute.USER);
assert (user != null);
final int gameId;
if (request.getParameter(AjaxRequest.GAME_ID) == null) {
return error(ErrorCode.NO_GAME_SPECIFIED);
}
try {
gameId = Integer.parseInt(request.getParameter(AjaxRequest.GAME_ID));
} catch (final NumberFormatException nfe) {
return error(ErrorCode.INVALID_GAME);
}
final Game game = gameManager.getGame(gameId);
if (game == null) {
return error(ErrorCode.INVALID_GAME);
}
assert game.getId() == gameId : "Got a game with id not what we asked for.";
data.put(AjaxResponse.GAME_INFO, game.getInfo());
data.put(AjaxResponse.PLAYER_INFO, game.getPlayerInfo());
return data;
}
}

View File

@ -14,6 +14,7 @@ public class Handlers {
LIST.put(CreateGameHandler.OP, CreateGameHandler.class); LIST.put(CreateGameHandler.OP, CreateGameHandler.class);
LIST.put(FirstLoadHandler.OP, FirstLoadHandler.class); LIST.put(FirstLoadHandler.OP, FirstLoadHandler.class);
LIST.put(GameListHandler.OP, GameListHandler.class); LIST.put(GameListHandler.OP, GameListHandler.class);
LIST.put(GetGameInfoHandler.OP, GetGameInfoHandler.class);
LIST.put(JoinGameHandler.OP, JoinGameHandler.class); LIST.put(JoinGameHandler.OP, JoinGameHandler.class);
LIST.put(LogoutHandler.OP, LogoutHandler.class); LIST.put(LogoutHandler.OP, LogoutHandler.class);
LIST.put(NamesHandler.OP, NamesHandler.class); LIST.put(NamesHandler.OP, NamesHandler.class);