Skip to content

Commit 3145dea

Browse files
author
Michael Wunderlich
committed
Merge branch 'master' into sql
2 parents c9b8dc8 + 2869aea commit 3145dea

File tree

8 files changed

+82
-6
lines changed

8 files changed

+82
-6
lines changed

bin/test-api.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ do
1414
GAMEID=$(curl --silent -X POST $API/game/$SESSIONID | jq -r .id)
1515
echo "configuring game, "
1616
curl --silent -X POST $API/game/$SESSIONID/$GAMEID/users -H "Content-Type: application/json" --data "[\"$USER1ID\",\"$USER2ID\"]"
17-
curl --silent -X PUT $API/game/$SESSIONID/$GAMEID/rules/TICTACTOE
17+
curl --silent -X PUT $API/game/$SESSIONID/$GAMEID/rules/TicTacToe
1818
curl --silent -X PUT $API/game/$SESSIONID/$GAMEID/name/tic-tac-toe-test
1919
EPOCH=$(date +%s)
2020
curl --silent -X PUT $API/game/$SESSIONID/$GAMEID/starttime/$EPOCH

public/app/gameController.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ function Game($q, $scope, $http, $interval, $routeParams, SessionService, UserSe
66
$scope.gamestate = []; // game state as Array
77
$scope.moving = 0;
88
$scope.user = UserService.get({ id: $routeParams.userid });
9+
$scope.winner = '';
910

1011
$scope.playgame = function(){
1112
return $q(function(resolve, reject) {
@@ -16,6 +17,11 @@ function Game($q, $scope, $http, $interval, $routeParams, SessionService, UserSe
1617
})
1718
SetState = GetState.then(function(result){
1819
$scope.gamestate = $scope.state.state.split('');
20+
if ( $scope.gamestate[0] == 'A' ) {
21+
$scope.winner = "X wins!";
22+
} else if ( $scope.gamestate[0] == 'B') {
23+
$scope.winner = "O wins!";
24+
}
1925
resolve();
2026
});
2127
});
@@ -28,7 +34,7 @@ function Game($q, $scope, $http, $interval, $routeParams, SessionService, UserSe
2834
}, 5000);
2935

3036
$scope.move = function(cellid){
31-
if ( $scope.moving == 1 ) {
37+
if ( $scope.moving == 1 || $scope.winner != '' ) {
3238
return;
3339
}
3440
$scope.moving = 1;

public/game.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<div id="game">
22
<div id="user"><h6>{{ user.name}}</h6></div>
33
<div class="sub-header">{{game.name}}</div>
4+
<div id="win message">{{ winner }}</div>
45
<div class="gameboard">
56
<div class="row">
67
<div class="square" ng-click="move(1)">&nbsp;{{gamestate[1]}}</div>

src/main/java/scorekeep/MoveController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public List<Move> getMoves(@PathVariable String sessionId, @PathVariable String
3131
}
3232
/* POST /move/SESSION/GAME/USER ; move string */
3333
@RequestMapping(value="/{userId}", method=RequestMethod.POST)
34-
public Move newMove(@PathVariable String sessionId, @PathVariable String gameId, @PathVariable String userId, @RequestBody String move) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException {
34+
public Move newMove(@PathVariable String sessionId, @PathVariable String gameId, @PathVariable String userId, @RequestBody String move) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException, RulesException {
3535
return moveFactory.newMove(sessionId, gameId, userId, move);
3636
}
3737
/** GET /move/SESSION/GAME/MOVE **/

src/main/java/scorekeep/MoveFactory.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55
import java.util.HashMap;
66
import java.util.List;
77
import java.util.Set;
8+
import java.lang.Class;
9+
import java.lang.reflect.Method;
10+
import java.lang.reflect.InvocationTargetException;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
813

914
public class MoveFactory {
15+
private static final Logger logger = LoggerFactory.getLogger("scorekeep.MoveFactory");
1016
private SecureRandom random = new SecureRandom();
1117
private final HashMap<String, Move> allMoves = new HashMap<String, Move>(1);
1218
private MoveModel moveModel = new MoveModel();
@@ -18,10 +24,11 @@ public class MoveFactory {
1824
public MoveFactory(){
1925
}
2026

21-
public Move newMove(String sessionId, String gameId, String userId, String moveText) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException {
27+
public Move newMove(String sessionId, String gameId, String userId, String moveText) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException, RulesException {
2228
String moveId = new BigInteger(40, random).toString(32).toUpperCase();
2329
String stateId = new BigInteger(40, random).toString(32).toUpperCase();
2430
Move move = new Move(moveId, sessionId, gameId, userId, moveText);
31+
String newStateText = "";
2532
// load game state
2633
Game game = gameController.getGame(sessionId, gameId);
2734
List<String> states = game.getStates();
@@ -37,7 +44,15 @@ public Move newMove(String sessionId, String gameId, String userId, String moveT
3744
if (newTurn.size() != 1) {
3845
newTurn.remove(userId);
3946
}
40-
String newStateText = TicTacToe.move(oldState.getState(), moveText);
47+
String rulesName = game.getRules();
48+
if ( !rulesName.matches("[a-zA-Z]{1,16}") ) {
49+
throw new RulesException(rulesName);
50+
}
51+
try {
52+
Class<?> rules = Class.forName("scorekeep." + rulesName);
53+
Method moveMethod = rules.getMethod("move", String.class, String.class);
54+
newStateText = (String) moveMethod.invoke(null, oldState.getState(), moveText);
55+
} catch ( ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { throw new RulesException(rulesName); }
4156
// save new game state
4257
State newState = new State(stateId, sessionId, gameId, newStateText, newTurn);
4358
// register state and move id to game
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package scorekeep;
2+
import org.springframework.web.bind.annotation.ResponseStatus;
3+
import org.springframework.http.HttpStatus;
4+
5+
@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Rules move invocation failed.")
6+
public class RulesException extends Exception{
7+
private String rulesId;
8+
public RulesException(String rulesId)
9+
{
10+
this.rulesId = rulesId;
11+
}
12+
public String getRulesId()
13+
{
14+
return rulesId;
15+
}
16+
}

src/main/java/scorekeep/RulesFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class RulesFactory {
88
private final HashMap<String, Rules> allRules = new HashMap<String, Rules>(1);
99

1010
public RulesFactory(){
11-
String id = "TICTACTOE";
11+
String id = "TicTacToe";
1212
String name = "Tic Tac Toe";
1313
String[] categories = { "head to head", "quick" };
1414
Integer[] users = { 2 };

src/main/java/scorekeep/TicTacToe.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package scorekeep;
22

33
import java.lang.Character;
4+
import java.lang.Math;
45
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
67

@@ -25,7 +26,44 @@ public static String move(String oldState, String moveText) {
2526
logger.error("Not your turn");
2627
}
2728
// new = "ONNXNNNNNN"
29+
// check for victory
30+
// - convert state to integer
31+
int stateInt = toInt(oldchar, movchar[0]);
32+
logger.info("state int: " + stateInt);
33+
// - compare
34+
boolean win = checkWin(stateInt);
35+
if ( win ) {
36+
if ( movchar[0] == 'X') {
37+
oldchar[0] = 'A';
38+
} else {
39+
oldchar[0] = 'B';
40+
}
41+
}
2842
String newState = new String(oldchar);
2943
return newState;
3044
}
45+
46+
public static int toInt(char[] state, char turn) {
47+
int out = 0;
48+
int len = state.length;
49+
for ( int i = 1; i <= len; i++ ){
50+
if ( state[len-i] == turn) {
51+
out += java.lang.Math.pow( 2, i-1 );
52+
}
53+
}
54+
return out;
55+
}
56+
57+
public static boolean checkWin(int state) {
58+
int[] winningStates = {7,56,73,84,146,273,292,448};
59+
for ( int i = 0; i < 8; i++ ){
60+
int combinedState = winningStates[i] & state;
61+
if ( combinedState == winningStates[i]) {
62+
logger.info("winning state: " + state);
63+
logger.info("matches: " + winningStates[i]);
64+
return true;
65+
}
66+
}
67+
return false;
68+
}
3169
}

0 commit comments

Comments
 (0)