Intial board config for GameProposalCreate
- victory tests without hardcode - better server logs - unmodifiable getters for game board - totalMoves counter for GameResult
This commit is contained in:
parent
07ce05bf01
commit
f9f6920512
@ -3,6 +3,7 @@ package djmil.cordacheckers.cordaclient;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -101,14 +102,20 @@ public class CordaClient {
|
||||
}
|
||||
|
||||
public GameState gameProposalCreate(HoldingIdentity issuer, HoldingIdentity acquier, Stone.Color acquierColor,
|
||||
String message
|
||||
) {
|
||||
String message) {
|
||||
|
||||
return gameProposalCreate(issuer, acquier, acquierColor, GameState.defaultGameBoard, message);
|
||||
}
|
||||
|
||||
public GameState gameProposalCreate(HoldingIdentity issuer, HoldingIdentity acquier, Stone.Color acquierColor,
|
||||
Map<Integer, Stone> board, String message) {
|
||||
final RequestBody requestBody = new RequestBody(
|
||||
"gp.create-" + UUID.randomUUID(),
|
||||
"djmil.cordacheckers.gameproposal.CreateFlow",
|
||||
new ReqGameProposalCreate(
|
||||
acquier.x500Name(),
|
||||
acquierColor,
|
||||
board,
|
||||
message));
|
||||
|
||||
return cordaFlowExecute(issuer, requestBody,RspGameState.class)
|
||||
|
@ -27,4 +27,32 @@ public record GameState(
|
||||
GAME_RESULT_YOU_LOOSE;
|
||||
}
|
||||
|
||||
public final static Map<Integer, Stone> defaultGameBoard = Map.ofEntries(
|
||||
// Inspired by Checkers notation rules: https://www.bobnewell.net/nucleus/checkers.php
|
||||
Map.entry( 1, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 2, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 3, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 4, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 5, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 6, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 7, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 8, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry( 9, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry(10, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry(11, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry(12, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
|
||||
Map.entry(21, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(22, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(23, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(24, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(25, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(26, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(27, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(28, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(29, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(30, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(31, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(32, new Stone(Stone.Color.WHITE, Stone.Type.MAN))
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package djmil.cordacheckers.cordaclient.dao.flow.arguments;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import djmil.cordacheckers.cordaclient.dao.Stone;
|
||||
|
||||
public record ReqGameProposalCreate(
|
||||
String opponentName,
|
||||
Stone.Color opponentColor,
|
||||
Map<Integer, Stone> board,
|
||||
String message
|
||||
) {
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package djmil.cordacheckers.cordaclient.dao.flow.arguments;
|
||||
|
||||
import djmil.cordacheckers.cordaclient.dao.GameState;
|
||||
import djmil.cordacheckers.cordaclient.dao.flow.RequestBody;
|
||||
|
||||
public interface Rsp <T> {
|
||||
@ -8,8 +9,14 @@ public interface Rsp <T> {
|
||||
|
||||
public default T getResponce(RequestBody requestBody) {
|
||||
if (failureStatus() == null) {
|
||||
System.out.println(requestBody.clientRequestId() +" [OK]");
|
||||
return successStatus();
|
||||
final var responce = successStatus();
|
||||
final String gameUuid = (responce instanceof GameState)
|
||||
? "GameUUID " +((GameState)responce).uuid().toString()
|
||||
: "";
|
||||
|
||||
System.out.println(requestBody.clientRequestId() +" [OK] " +gameUuid);
|
||||
|
||||
return responce;
|
||||
}
|
||||
|
||||
System.err.println(requestBody.clientRequestId() +" has failed: " +failureStatus());
|
||||
|
@ -5,6 +5,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -31,6 +32,17 @@ public class GameBoardTests {
|
||||
final static Stone BLACK_MAN = new Stone(Stone.Color.BLACK, Stone.Type.MAN);
|
||||
final static Stone BLACK_KING = new Stone(Stone.Color.BLACK, Stone.Type.KING);
|
||||
|
||||
final static Map<Integer, Stone> victoryTestBoard1 = Map.ofEntries(
|
||||
Map.entry(15, BLACK_MAN),
|
||||
Map.entry(23, WHITE_MAN)
|
||||
);
|
||||
|
||||
final static Map<Integer, Stone> victoryTestBoard2 = Map.ofEntries(
|
||||
Map.entry(21, BLACK_MAN),
|
||||
Map.entry(29, WHITE_MAN),
|
||||
Map.entry(30, WHITE_MAN)
|
||||
);
|
||||
|
||||
@Test
|
||||
void testSurrender() {
|
||||
final var hiWhite = holdingIdentityResolver.getByUsername(whitePlayerName);
|
||||
@ -39,8 +51,6 @@ public class GameBoardTests {
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiWhite, hiBlack, Stone.Color.BLACK, "GameBoard SURRENDER test");
|
||||
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
|
||||
final GameState acceptedGameBlackView = cordaClient.gameProposalAccept(
|
||||
hiBlack, game.uuid());
|
||||
|
||||
@ -54,6 +64,7 @@ public class GameBoardTests {
|
||||
assertThat(surrendererGameView.opponentName()).isEqualToIgnoringCase(whitePlayerName);
|
||||
assertThat(surrendererGameView.opponentColor()).isEqualByComparingTo(Stone.Color.WHITE);
|
||||
assertThat(surrendererGameView.status()).isEqualByComparingTo(Status.GAME_RESULT_YOU_LOOSE);
|
||||
assertThat(surrendererGameView.moveNumber() == 0);
|
||||
|
||||
assertThatThrownBy(() -> { // White can not surrender, since Black already did
|
||||
cordaClient.gameBoardSurrender(
|
||||
@ -66,6 +77,7 @@ public class GameBoardTests {
|
||||
assertThat(winnerGameView.opponentName()).isEqualToIgnoringCase(blackPlayerName);
|
||||
assertThat(winnerGameView.opponentColor()).isEqualByComparingTo(Stone.Color.BLACK);
|
||||
assertThat(winnerGameView.status()).isEqualByComparingTo(Status.GAME_RESULT_YOU_WON);
|
||||
assertThat(winnerGameView.moveNumber() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -75,7 +87,6 @@ public class GameBoardTests {
|
||||
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiWhite, hiBlack, Stone.Color.BLACK, "GameBoard MOVE test");
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
|
||||
final var m0 = cordaClient.gameProposalAccept(hiBlack, game.uuid());
|
||||
assertThat(m0.previousMove()).isNull();
|
||||
@ -186,27 +197,23 @@ public class GameBoardTests {
|
||||
final var hiWhite = holdingIdentityResolver.getByUsername(whitePlayerName);
|
||||
final var hiBlack = holdingIdentityResolver.getByUsername(blackPlayerName);
|
||||
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiWhite, hiBlack, Stone.Color.BLACK, "GameBoard Vitcory test 1");
|
||||
final GameState game = cordaClient.gameProposalCreate(hiBlack, hiWhite, Stone.Color.WHITE,
|
||||
victoryTestBoard1, "GameBoard Vitcory test 1");
|
||||
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
|
||||
final GameState m0 = cordaClient.gameProposalAccept(hiBlack, game.uuid());
|
||||
|
||||
// For this test to work, uncoment proper initialBoard state configuration in
|
||||
// cordacheckers/contracts/GameBoardContract.java
|
||||
// i'm too lazy to implement this test properly =^.^=
|
||||
assertThat(m0.board().size() == 2);
|
||||
assertThat(m0.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_OPPONENT);
|
||||
final GameState m0 = cordaClient.gameProposalAccept(hiWhite, game.uuid());
|
||||
assertThat(m0.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_YOU);
|
||||
assertThat(m0.board()).containsAllEntriesOf(victoryTestBoard1);
|
||||
|
||||
final var m1 = cordaClient.gameBoardMove(hiWhite, game.uuid(), move(23, 18), null);
|
||||
assertThat(m1.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_OPPONENT);
|
||||
|
||||
final var m2 = cordaClient.gameBoardMove(hiBlack, game.uuid(), move(15, 22), null);
|
||||
assertThat(m2.status()).isEqualByComparingTo(Status.GAME_RESULT_YOU_WON);
|
||||
assertThat(m2.moveNumber() == 2);
|
||||
|
||||
final var m2WhiteView = cordaClient.gameStateGet(hiWhite, game.uuid());
|
||||
assertThat(m2WhiteView.status()).isEqualByComparingTo(Status.GAME_RESULT_YOU_LOOSE);
|
||||
assertThat(m2WhiteView.moveNumber() == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -214,27 +221,23 @@ public class GameBoardTests {
|
||||
final var hiWhite = holdingIdentityResolver.getByUsername(whitePlayerName);
|
||||
final var hiBlack = holdingIdentityResolver.getByUsername(blackPlayerName);
|
||||
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiWhite, hiBlack, Stone.Color.BLACK, "GameBoard Vitcory test 2");
|
||||
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
final GameState game = cordaClient.gameProposalCreate(hiWhite, hiBlack, Stone.Color.BLACK,
|
||||
victoryTestBoard2, "GameBoard Vitcory test 2");
|
||||
|
||||
final GameState m0 = cordaClient.gameProposalAccept(hiBlack, game.uuid());
|
||||
|
||||
// For this test to work, uncoment proper initialBoard state configuration in
|
||||
// cordacheckers/contracts/GameBoardContract.java
|
||||
// i'm too lazy to implement this test properly =^.^=
|
||||
assertThat(m0.board().size() == 3);
|
||||
assertThat(m0.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_OPPONENT);
|
||||
assertThat(m0.board()).containsAllEntriesOf(victoryTestBoard2);
|
||||
|
||||
final var m0WhiteView = cordaClient.gameStateGet(hiWhite, game.uuid());
|
||||
assertThat(m0WhiteView.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_YOU);
|
||||
|
||||
final var m1 = cordaClient.gameBoardMove(hiWhite, game.uuid(), move(29, 25), null);
|
||||
assertThat(m1.status()).isEqualByComparingTo(Status.GAME_RESULT_YOU_WON);
|
||||
assertThat(m1.moveNumber() == 1);
|
||||
|
||||
final var m1BlackView = cordaClient.gameStateGet(hiBlack, game.uuid());
|
||||
assertThat(m1BlackView.status()).isEqualByComparingTo(Status.GAME_RESULT_YOU_LOOSE);
|
||||
assertThat(m1BlackView.moveNumber() == 1);
|
||||
}
|
||||
|
||||
ArrayList<Integer> move(int from, int to) {
|
||||
|
@ -32,12 +32,7 @@ public class GameProposalTests {
|
||||
final String message = "GameProposal CREATE test";
|
||||
|
||||
final GameState issuerGameView = cordaClient.gameProposalCreate(
|
||||
hiIssuer,
|
||||
hiAcquier,
|
||||
acquierColor,
|
||||
message);
|
||||
|
||||
System.out.println("Game UUID " +issuerGameView.uuid());
|
||||
hiIssuer, hiAcquier, acquierColor, message);
|
||||
|
||||
/*
|
||||
* Issuers perspective on a newly created GameProposal
|
||||
@ -45,6 +40,9 @@ public class GameProposalTests {
|
||||
assertThat(issuerGameView.status()).isEqualByComparingTo(Status.GAME_PROPOSAL_WAIT_FOR_OPPONENT);
|
||||
assertThat(issuerGameView.opponentName()).isEqualToIgnoringCase(acquier);
|
||||
assertThat(issuerGameView.opponentColor()).isEqualByComparingTo(acquierColor);
|
||||
assertThat(issuerGameView.board()).containsAllEntriesOf(GameState.defaultGameBoard);
|
||||
assertThat(issuerGameView.previousMove()).isEmpty();
|
||||
assertThat(issuerGameView.moveNumber() == 0);
|
||||
assertThat(issuerGameView.message()).isEqualToIgnoringCase(message);
|
||||
assertThat(issuerGameView.uuid()).isNotNull();
|
||||
|
||||
@ -62,6 +60,9 @@ public class GameProposalTests {
|
||||
assertThat(acquierGameView.status()).isEqualByComparingTo(Status.GAME_PROPOSAL_WAIT_FOR_YOU);
|
||||
assertThat(acquierGameView.opponentName()).isEqualToIgnoringCase(issuer);
|
||||
assertThat(acquierGameView.opponentColor()).isEqualByComparingTo(acquierColor.opposite());
|
||||
assertThat(acquierGameView.board()).containsAllEntriesOf(GameState.defaultGameBoard);
|
||||
assertThat(acquierGameView.previousMove()).isEmpty();
|
||||
assertThat(acquierGameView.moveNumber() == 0);
|
||||
assertThat(acquierGameView.message()).isEqualToIgnoringCase(message);
|
||||
assertThat(acquierGameView.uuid()).isEqualByComparingTo(issuerGameView.uuid());
|
||||
}
|
||||
@ -70,12 +71,9 @@ public class GameProposalTests {
|
||||
void testReject() {
|
||||
final var hiIssuer = holdingIdentityResolver.getByUsername(issuer);
|
||||
final var hiAcquier = holdingIdentityResolver.getByUsername(acquier);
|
||||
final String message = "GameProposal REJECT test";
|
||||
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiIssuer, hiAcquier, acquierColor, message);
|
||||
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
hiIssuer, hiAcquier, acquierColor, "GameProposal REJECT test");
|
||||
|
||||
assertThatThrownBy(() -> { // Issuer can not reject
|
||||
cordaClient.gameProposalReject(
|
||||
@ -102,12 +100,9 @@ public class GameProposalTests {
|
||||
void testCancel() {
|
||||
final var hiIssuer = holdingIdentityResolver.getByUsername(issuer);
|
||||
final var hiAcquier = holdingIdentityResolver.getByUsername(acquier);
|
||||
final String message = "GameProposal CANCEL test";
|
||||
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiIssuer, hiAcquier, acquierColor, message);
|
||||
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
hiIssuer, hiAcquier, acquierColor, "GameProposal CANCEL test");
|
||||
|
||||
assertThatThrownBy(() -> { // Acquier can not cancel
|
||||
cordaClient.gameProposalCancel(
|
||||
@ -134,12 +129,9 @@ public class GameProposalTests {
|
||||
void testAccept() {
|
||||
final var hiIssuer = holdingIdentityResolver.getByUsername(issuer);
|
||||
final var hiAcquier = holdingIdentityResolver.getByUsername(acquier);
|
||||
final String message = "GameProposal ACCEPT test";
|
||||
|
||||
final GameState game = cordaClient.gameProposalCreate(
|
||||
hiIssuer, hiAcquier, acquierColor, message);
|
||||
|
||||
System.out.println("Game UUID " +game.uuid());
|
||||
hiIssuer, hiAcquier, acquierColor, "GameProposal ACCEPT test");
|
||||
|
||||
assertThatThrownBy(() -> { // Issuer can not accept
|
||||
cordaClient.gameProposalAccept(
|
||||
@ -151,6 +143,9 @@ public class GameProposalTests {
|
||||
|
||||
assertThat(acceptedGameAcquierView.opponentName()).isEqualToIgnoringCase(issuer);
|
||||
assertThat(acceptedGameAcquierView.opponentColor()).isEqualByComparingTo(acquierColor.opposite());
|
||||
assertThat(acceptedGameAcquierView.board()).containsAllEntriesOf(GameState.defaultGameBoard);
|
||||
assertThat(acceptedGameAcquierView.previousMove()).isEmpty();
|
||||
assertThat(acceptedGameAcquierView.moveNumber() == 0);
|
||||
assertThat(acceptedGameAcquierView.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_YOU);
|
||||
assertThat(acceptedGameAcquierView.uuid()).isEqualByComparingTo(game.uuid());
|
||||
|
||||
@ -164,6 +159,9 @@ public class GameProposalTests {
|
||||
|
||||
assertThat(acceptedGameIssuerView.opponentName()).isEqualToIgnoringCase(acquier);
|
||||
assertThat(acceptedGameIssuerView.opponentColor()).isEqualByComparingTo(acquierColor);
|
||||
assertThat(acceptedGameIssuerView.board()).containsAllEntriesOf(GameState.defaultGameBoard);
|
||||
assertThat(acceptedGameIssuerView.previousMove()).isEmpty();
|
||||
assertThat(acceptedGameIssuerView.moveNumber() == 0);
|
||||
assertThat(acceptedGameIssuerView.status()).isEqualByComparingTo(Status.GAME_BOARD_WAIT_FOR_OPPONENT);
|
||||
assertThat(acceptedGameIssuerView.uuid()).isEqualByComparingTo(game.uuid());
|
||||
}
|
||||
|
@ -34,6 +34,12 @@ public class Stone {
|
||||
private final Color color;
|
||||
private final Type type;
|
||||
|
||||
// Serialisation service requires a default constructor
|
||||
public Stone() {
|
||||
this.color = null;
|
||||
this.type = null;
|
||||
}
|
||||
|
||||
@ConstructorForDeserialization
|
||||
public Stone(Color color, Type type) {
|
||||
this.color = color;
|
||||
|
@ -3,12 +3,9 @@ package djmil.cordacheckers.contracts;
|
||||
import static djmil.cordacheckers.contracts.GameCommand.requireThat;
|
||||
import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleCommand;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import djmil.cordacheckers.checkers.Stone;
|
||||
import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction;
|
||||
|
||||
public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
|
||||
@ -17,7 +14,7 @@ public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
|
||||
|
||||
@Override
|
||||
public void verify(UtxoLedgerTransaction trx) {
|
||||
log.info("GameBoardContract.verify() called");
|
||||
log.info("GameBoardContract verify");
|
||||
|
||||
requireThat(trx.getCommands().size() == 1, GameCommand.REQUIRE_SINGLE_COMMAND);
|
||||
final GameCommand command = getSingleCommand(trx, GameCommand.class);
|
||||
@ -44,44 +41,4 @@ public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
|
||||
}
|
||||
}
|
||||
|
||||
public final static Map<Integer, Stone> initialBoard = Map.ofEntries(
|
||||
// Inspired by Checkers notation rules: https://www.bobnewell.net/nucleus/checkers.php
|
||||
// Map.entry( 1, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 2, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 3, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 4, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 5, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 6, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 7, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 8, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry( 9, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry(10, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry(11, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry(12, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
|
||||
// Map.entry(21, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(22, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(23, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(24, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(25, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(26, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(27, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(28, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(29, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(30, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(31, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
// Map.entry(32, new Stone(Stone.Color.WHITE, Stone.Type.MAN))
|
||||
|
||||
|
||||
/* VICTORY TEST 1 */
|
||||
// Map.entry(15, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
// Map.entry(23, new Stone(Stone.Color.WHITE, Stone.Type.MAN))
|
||||
|
||||
|
||||
/* VICTORY TEST 2 */
|
||||
Map.entry(21, new Stone(Stone.Color.BLACK, Stone.Type.MAN)),
|
||||
Map.entry(29, new Stone(Stone.Color.WHITE, Stone.Type.MAN)),
|
||||
Map.entry(30, new Stone(Stone.Color.WHITE, Stone.Type.MAN))
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ public class GameCommand implements Command {
|
||||
/*
|
||||
* Major command logick check
|
||||
*/
|
||||
requireThat(outGameBoard.getBoard().equals(GameBoardContract.initialBoard), "Bad GameBoard initial state");
|
||||
requireThat(outGameBoard.getBoard().size() > 0, "GameBoard initial state was not found");
|
||||
}
|
||||
|
||||
public void validateGameProposalReject(UtxoLedgerTransaction trx) {
|
||||
@ -192,6 +192,8 @@ public class GameCommand implements Command {
|
||||
requireThat(outGameResult.getLooserName().compareTo(outGameResult.getBlackPlayer()) == 0 ||
|
||||
outGameResult.getLooserName().compareTo(outGameResult.getWhitePlayer()) == 0,
|
||||
"Surenderer must be either Black or White player");
|
||||
|
||||
requireThat(outGameResult.getTotalMoves() == inGameBoard.getMoveNumber(), GAME_RESULT_MOVES);
|
||||
}
|
||||
|
||||
public void validateGameBoardVictory(UtxoLedgerTransaction trx) {
|
||||
@ -212,6 +214,7 @@ public class GameCommand implements Command {
|
||||
requireThat(possibleMoves.isEmpty(), "Victory condition violation");
|
||||
|
||||
requireThat(outGameResult.getWinnerName().compareTo(inGameBoard.getIdelPlayerName()) == 0, "Bad winner name");
|
||||
requireThat(outGameResult.getTotalMoves() == inGameBoard.getMoveNumber(), GAME_RESULT_MOVES);
|
||||
}
|
||||
|
||||
public static void requireThat(boolean asserted, String errorMessage) {
|
||||
@ -245,4 +248,6 @@ public class GameCommand implements Command {
|
||||
|
||||
static final String VICTORY_INPUT_STATE = "VICTORY command should have exactly one GameBoardState input state";
|
||||
static final String VICTORY_OUTPUT_STATE = "VICTORY command should have exactly one GameResultState output state";
|
||||
|
||||
static final String GAME_RESULT_MOVES = "Wrong number of total moves";
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package djmil.cordacheckers.states;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -23,7 +24,7 @@ public class GameBoardState extends GameState {
|
||||
super(gameProposalState.whitePlayer, gameProposalState.blackPlayer,
|
||||
gameProposalState.gameUuid, gameProposalState.message, gameProposalState.participants);
|
||||
|
||||
this.board = new LinkedHashMap<Integer, Stone>(GameBoardContract.initialBoard);
|
||||
this.board = gameProposalState.getBoard();
|
||||
this.activeColor = Stone.Color.WHITE;
|
||||
this.moveNumber = 0;
|
||||
}
|
||||
@ -68,7 +69,7 @@ public class GameBoardState extends GameState {
|
||||
}
|
||||
|
||||
public Map<Integer, Stone> getBoard() {
|
||||
return board;
|
||||
return Collections.unmodifiableMap(board);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,12 @@
|
||||
package djmil.cordacheckers.states;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import djmil.cordacheckers.checkers.Stone;
|
||||
import djmil.cordacheckers.contracts.GameProposalContract;
|
||||
import net.corda.v5.base.annotations.ConstructorForDeserialization;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
@ -13,12 +16,15 @@ import net.corda.v5.ledger.utxo.BelongsToContract;
|
||||
public class GameProposalState extends GameState {
|
||||
|
||||
private final MemberX500Name issuerName;
|
||||
private final Map<Integer, Stone> board;
|
||||
|
||||
@ConstructorForDeserialization
|
||||
public GameProposalState(MemberX500Name whitePlayer, MemberX500Name blackPlayer, MemberX500Name issuerName,
|
||||
UUID gameUuid, String message, List<PublicKey> participants) {
|
||||
UUID gameUuid, Map<Integer, Stone> board, String message, List<PublicKey> participants) {
|
||||
super(whitePlayer, blackPlayer, gameUuid, message, participants);
|
||||
|
||||
this.issuerName = issuerName;
|
||||
this.board = board;
|
||||
}
|
||||
|
||||
public MemberX500Name getIssuerName() {
|
||||
@ -29,4 +35,8 @@ public class GameProposalState extends GameState {
|
||||
return getOpponentName(issuerName);
|
||||
}
|
||||
|
||||
public Map<Integer, Stone> getBoard() {
|
||||
return Collections.unmodifiableMap(board);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,17 +13,20 @@ import net.corda.v5.ledger.utxo.BelongsToContract;
|
||||
public class GameResultState extends GameState {
|
||||
|
||||
private final MemberX500Name winnerName;
|
||||
private final Integer totalMoves;
|
||||
|
||||
@ConstructorForDeserialization
|
||||
public GameResultState(MemberX500Name whitePlayer, MemberX500Name blackPlayer, MemberX500Name winnerName,
|
||||
UUID gameUuid, String message, List<PublicKey> participants) {
|
||||
Integer totalMoves, UUID gameUuid, String message, List<PublicKey> participants) {
|
||||
super(whitePlayer, blackPlayer, gameUuid, message, participants);
|
||||
this.winnerName = winnerName;
|
||||
this.totalMoves = totalMoves;
|
||||
}
|
||||
|
||||
public GameResultState(MemberX500Name winnerName, GameBoardState gameBoardState, PublicKey custodianPubicKey) {
|
||||
super(gameBoardState.whitePlayer, gameBoardState.blackPlayer, gameBoardState.gameUuid, null, gameBoardState.participants, custodianPubicKey);
|
||||
this.winnerName = winnerName;
|
||||
this.totalMoves = gameBoardState.getMoveNumber();
|
||||
}
|
||||
|
||||
public MemberX500Name getWinnerName() {
|
||||
@ -34,4 +37,8 @@ public class GameResultState extends GameState {
|
||||
return getOpponentName(getWinnerName());
|
||||
}
|
||||
|
||||
public Integer getTotalMoves() {
|
||||
return totalMoves;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -90,29 +90,25 @@ public class CreateFlow implements ClientStartableFlow{
|
||||
GameProposalState buildGameProposalStateFrom(ClientRequestBody requestBody) {
|
||||
final CreateFlowArgs args = requestBody.getRequestBodyAs(jsonMarshallingService, CreateFlowArgs.class);
|
||||
|
||||
final Stone.Color opponentColor = Stone.Color.valueOf(args.opponentColor);
|
||||
if (opponentColor == null) {
|
||||
throw new RuntimeException("Allowed values for opponentColor are: "
|
||||
+ Stone.Color.WHITE.name() +", " + Stone.Color.BLACK.name()
|
||||
+ ". Actual value was: " + args.opponentColor);
|
||||
}
|
||||
|
||||
final MemberInfo myInfo = memberLookup.myInfo();
|
||||
final MemberInfo opponentInfo = requireNonNull(
|
||||
memberLookup.lookup(MemberX500Name.parse(args.opponentName)),
|
||||
"MemberLookup can't find opponentName specified in flow arguments: " + args.opponentName
|
||||
);
|
||||
|
||||
final MemberInfo whitePlayerInfo = opponentColor == Stone.Color.WHITE ? opponentInfo : myInfo;
|
||||
final MemberInfo blackPlayerInfo = opponentColor == Stone.Color.BLACK ? opponentInfo : myInfo;
|
||||
final MemberInfo whitePlayerInfo = args.opponentColor == Stone.Color.WHITE ? opponentInfo : myInfo;
|
||||
final MemberInfo blackPlayerInfo = args.opponentColor == Stone.Color.BLACK ? opponentInfo : myInfo;
|
||||
|
||||
return new GameProposalState(
|
||||
whitePlayerInfo.getName(),
|
||||
blackPlayerInfo.getName(),
|
||||
myInfo.getName(), // <<--- GameProposal issuer
|
||||
UUID.randomUUID(),
|
||||
args.board,
|
||||
args.message,
|
||||
Arrays.asList(myInfo.getLedgerKeys().get(0), opponentInfo.getLedgerKeys().get(0))
|
||||
Arrays.asList(
|
||||
myInfo.getLedgerKeys().get(0),
|
||||
opponentInfo.getLedgerKeys().get(0))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,20 @@
|
||||
package djmil.cordacheckers.gameproposal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import djmil.cordacheckers.checkers.Stone;
|
||||
|
||||
public class CreateFlowArgs {
|
||||
public final String opponentName;
|
||||
public final String opponentColor;
|
||||
public final Stone.Color opponentColor;
|
||||
public final Map<Integer, Stone> board;
|
||||
public final String message;
|
||||
|
||||
// Serialisation service requires a default constructor
|
||||
public CreateFlowArgs() {
|
||||
opponentName = null;
|
||||
opponentColor = null;
|
||||
board = null;
|
||||
message = null;
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ public class View {
|
||||
this.status = status;
|
||||
this.opponentName = gameProposal.getOpponentName(myName).getCommonName();
|
||||
this.opponentColor = gameProposal.getOpponentColor(myName);
|
||||
this.board = null;
|
||||
this.moveNumber = null;
|
||||
this.board = gameProposal.getBoard();
|
||||
this.previousMove = null;
|
||||
this.moveNumber = 0;
|
||||
this.message = gameProposal.getMessage();
|
||||
this.uuid = gameProposal.getGameUuid();
|
||||
}
|
||||
@ -64,8 +64,8 @@ public class View {
|
||||
this.opponentName = gameBoard.getOpponentName(myName).getCommonName();
|
||||
this.opponentColor = gameBoard.getOpponentColor(myName);
|
||||
this.board = gameBoard.getBoard();
|
||||
this.moveNumber = gameBoard.getMoveNumber();
|
||||
this.previousMove = previousMove;
|
||||
this.moveNumber = gameBoard.getMoveNumber();
|
||||
this.message = gameBoard.getMessage();
|
||||
this.uuid = gameBoard.getGameUuid();
|
||||
}
|
||||
@ -75,8 +75,8 @@ public class View {
|
||||
this.opponentName = gameResult.getOpponentName(myName).getCommonName();
|
||||
this.opponentColor = gameResult.getOpponentColor(myName);
|
||||
this.board = null;
|
||||
this.moveNumber = null;
|
||||
this.previousMove = null;
|
||||
this.moveNumber = gameResult.getTotalMoves();
|
||||
this.message = gameResult.getMessage();
|
||||
this.uuid = gameResult.getGameUuid();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user