GameID
a universal ID shared between GameProposal, GameBoard and a GameResult
This commit is contained in:
		
							parent
							
								
									a34ea39dfb
								
							
						
					
					
						commit
						e26cfe0d91
					
				@ -35,6 +35,7 @@ import djmil.cordacheckers.cordaclient.dao.flow.arguments.Empty;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameBoardCommandReq;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameBoardResGameResult;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameBoardListRes;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameBoardResGameBoard;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameProposalCommandAcceptRes;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameProposalCommandReq;
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.flow.arguments.GameProposalCommandRes;
 | 
			
		||||
@ -227,6 +228,33 @@ public class CordaClient {
 | 
			
		||||
        return moveResult.successStatus();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
     public GameBoard gameBoardMove(
 | 
			
		||||
        HoldingIdentity myHoldingIdentity,
 | 
			
		||||
        UUID gameBoardUuid,
 | 
			
		||||
        List<Integer> move
 | 
			
		||||
    ) {
 | 
			
		||||
        final RequestBody requestBody = new RequestBody(
 | 
			
		||||
            "gb.move-" +UUID.randomUUID(),
 | 
			
		||||
            "djmil.cordacheckers.gameboard.CommandFlow",
 | 
			
		||||
            new GameBoardCommandReq(
 | 
			
		||||
                gameBoardUuid,
 | 
			
		||||
                new GameBoardCommand(move))
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        final GameBoardResGameBoard moveResult = cordaFlowExecute(
 | 
			
		||||
            myHoldingIdentity,
 | 
			
		||||
            requestBody,
 | 
			
		||||
            GameBoardResGameBoard.class 
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        if (moveResult.failureStatus() != null) {
 | 
			
		||||
            System.out.println("GameBoard.CommandFlow failed: " + moveResult.failureStatus());
 | 
			
		||||
            throw new RuntimeException("GameBoard: CommandFlow execution has failed");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return moveResult.successStatus();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <T> T cordaFlowExecute(HoldingIdentity holdingIdentity, RequestBody requestBody, Class<T> flowResultType) {
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ public record GameBoard(
 | 
			
		||||
    String      opponentName,
 | 
			
		||||
    Piece.Color opponentColor,
 | 
			
		||||
    Boolean     opponentMove,
 | 
			
		||||
    Integer     moveNumber,
 | 
			
		||||
    Map<Integer, Piece> board,
 | 
			
		||||
    GameBoardCommand previousCommand,
 | 
			
		||||
    String message,
 | 
			
		||||
 | 
			
		||||
@ -6,9 +6,7 @@ public class GameBoardCommand {
 | 
			
		||||
    public static enum Type {
 | 
			
		||||
        MOVE,
 | 
			
		||||
        SURRENDER,
 | 
			
		||||
        DRAW,
 | 
			
		||||
        VICTORY,
 | 
			
		||||
        ACCEPT;
 | 
			
		||||
        VICTORY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final Type type;
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
package djmil.cordacheckers.cordaclient.dao.flow.arguments;
 | 
			
		||||
 | 
			
		||||
import djmil.cordacheckers.cordaclient.dao.GameBoard;
 | 
			
		||||
 | 
			
		||||
public record GameBoardResGameBoard(GameBoard successStatus, String failureStatus) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -3,6 +3,7 @@ package djmil.cordacheckers.cordaclient;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@ -215,6 +216,35 @@ public class CordaClientTest {
 | 
			
		||||
        assertThat(gameResult.victoryColor()).isEqualByComparingTo(Piece.Color.BLACK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void testGameBoardMove() throws JsonMappingException, JsonProcessingException, InvalidNameException {
 | 
			
		||||
        final var hiAlice = holdingIdentityResolver.getByUsername("alice");
 | 
			
		||||
        final var hiBob   = holdingIdentityResolver.getByUsername("bob");
 | 
			
		||||
        final var bobColor = Piece.Color.WHITE;
 | 
			
		||||
 | 
			
		||||
        final UUID gpUuid = cordaClient.gameProposalCreate(
 | 
			
		||||
            hiAlice, hiBob,
 | 
			
		||||
            bobColor, "GameBoard MOVE test"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        System.out.println("New GameProposal UUID "+ gpUuid);
 | 
			
		||||
 | 
			
		||||
        final GameBoard gbState = cordaClient.gameProposalAccept(
 | 
			
		||||
            hiBob, gpUuid
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        System.out.println("New GameBoard UUID "+ gbState.id());
 | 
			
		||||
 | 
			
		||||
        assertThatThrownBy(() -> { // Alice can not move, since it is Bob's turn
 | 
			
		||||
            cordaClient.gameBoardMove(
 | 
			
		||||
                hiAlice, gbState.id(),
 | 
			
		||||
                Arrays.asList(1, 2));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        final GameBoard gameBoard = cordaClient.gameBoardMove(
 | 
			
		||||
            hiBob, gbState.id(), Arrays.asList(1, 2));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <T extends CordaState> T findByUuid(List<T> statesList, UUID uuid) {
 | 
			
		||||
        for (T state : statesList) {
 | 
			
		||||
            if (state.id().compareTo(uuid) == 0)
 | 
			
		||||
 | 
			
		||||
@ -21,9 +21,7 @@ public class GameBoardCommand implements Command {
 | 
			
		||||
    public static enum Type {
 | 
			
		||||
        MOVE,
 | 
			
		||||
        SURRENDER,
 | 
			
		||||
        DRAW,
 | 
			
		||||
        VICTORY,
 | 
			
		||||
        ACCEPT; // aka accept opponents DRAW or VICTORY request
 | 
			
		||||
        FINISH;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final Type type;
 | 
			
		||||
@ -81,11 +79,41 @@ public class GameBoardCommand implements Command {
 | 
			
		||||
        requireThat(inGameBoardState.getBlackPlayerName().compareTo(outGameResultState.getBlackPlayerName()) == 0, IN_OUT_PARTICIPANTS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void validateMoveTrx(UtxoLedgerTransaction trx) {
 | 
			
		||||
        requireThat(trx.getInputContractStates().size() == 1, MOVE_INPUT_STATE);
 | 
			
		||||
        final var inGameBoardState = getSingleInputState(trx, GameBoardState.class);
 | 
			
		||||
 | 
			
		||||
        requireThat(trx.getOutputContractStates().size() == 1, MOVE_OUTPUT_STATE);
 | 
			
		||||
        final var outGameBoardState = getSingleOutputState(trx, GameBoardState.class);
 | 
			
		||||
 | 
			
		||||
        requireThat(inGameBoardState.getWhitePlayerName().compareTo(outGameBoardState.getWhitePlayerName()) == 0, IN_OUT_PARTICIPANTS);
 | 
			
		||||
        requireThat(inGameBoardState.getBlackPlayerName().compareTo(outGameBoardState.getBlackPlayerName()) == 0, IN_OUT_PARTICIPANTS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void validateFinishTrx(UtxoLedgerTransaction trx) {
 | 
			
		||||
        requireThat(trx.getInputContractStates().size() == 1, FINAL_MOVE_INPUT_STATE);
 | 
			
		||||
        final var inGameBoardState = getSingleInputState(trx, GameBoardState.class);
 | 
			
		||||
 | 
			
		||||
        requireThat(trx.getOutputContractStates().size() == 1, FINAL_MOVE_OUTPUT_STATE);
 | 
			
		||||
        final var outGameResultState = getSingleOutputState(trx, GameResultState.class);
 | 
			
		||||
 | 
			
		||||
        requireThat(inGameBoardState.getWhitePlayerName().compareTo(outGameResultState.getWhitePlayerName()) == 0, IN_OUT_PARTICIPANTS);
 | 
			
		||||
        requireThat(inGameBoardState.getBlackPlayerName().compareTo(outGameResultState.getBlackPlayerName()) == 0, IN_OUT_PARTICIPANTS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static final String BAD_ACTIONMOVE_CONSTRUCTOR = "Bad constructor for Action.MOVE";
 | 
			
		||||
 | 
			
		||||
    static final String SURRENDER_INPUT_STATE = "SURRENDER command should have exactly one GameBoardState input state";
 | 
			
		||||
    static final String SURRENDER_OUTPUT_STATE = "SURRENDER command should have exactly one GameResultState output state";
 | 
			
		||||
 | 
			
		||||
    static final String MOVE_INPUT_STATE = "MOVE command should have exactly one GameBoardState input state";
 | 
			
		||||
    static final String MOVE_OUTPUT_STATE = "MOVE command should have exactly one GameBoardState output state";
 | 
			
		||||
    static final String MOVE_OUT_BOARD = "MOVE command: move checkers rules violation";
 | 
			
		||||
    static final String MOVE_OUT_COLOR = "MOVE command: moveColor checkers rules violation";
 | 
			
		||||
 | 
			
		||||
    static final String FINAL_MOVE_INPUT_STATE = "FINAL_MOVE command should have exactly one GameBoardState input state";
 | 
			
		||||
    static final String FINAL_MOVE_OUTPUT_STATE = "FINAL_MOVE command should have exactly one GameResultState output state";
 | 
			
		||||
 | 
			
		||||
    static final String IN_OUT_PARTICIPANTS = "InputState and OutputState participants do not match";
 | 
			
		||||
 | 
			
		||||
    public static class CommandTypeException extends RuntimeException {
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,12 @@
 | 
			
		||||
package djmil.cordacheckers.contracts;
 | 
			
		||||
 | 
			
		||||
import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleCommand;
 | 
			
		||||
import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleInputSar;
 | 
			
		||||
import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleReferenceSar;
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import djmil.cordacheckers.states.GameProposalState;
 | 
			
		||||
import net.corda.v5.base.annotations.Suspendable;
 | 
			
		||||
import net.corda.v5.base.exceptions.CordaRuntimeException;
 | 
			
		||||
import net.corda.v5.ledger.utxo.Command;
 | 
			
		||||
import net.corda.v5.ledger.utxo.StateAndRef;
 | 
			
		||||
import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction;
 | 
			
		||||
 | 
			
		||||
public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
 | 
			
		||||
@ -40,18 +35,17 @@ public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
 | 
			
		||||
            log.info("GameBoardContract.verify() as GameBoardCommand "+((GameBoardCommand)command).getType());
 | 
			
		||||
            switch (((GameBoardCommand)command).getType()) {
 | 
			
		||||
                case MOVE:
 | 
			
		||||
                break;
 | 
			
		||||
                    GameBoardCommand.validateMoveTrx(trx);
 | 
			
		||||
                    break;
 | 
			
		||||
                
 | 
			
		||||
                case SURRENDER:
 | 
			
		||||
                    GameBoardCommand.validateSurrenderTrx(trx);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case DRAW:
 | 
			
		||||
                break;
 | 
			
		||||
                case VICTORY:
 | 
			
		||||
                break;
 | 
			
		||||
                case ACCEPT:
 | 
			
		||||
                break;
 | 
			
		||||
                case FINISH:
 | 
			
		||||
                    GameBoardCommand.validateFinishTrx(trx);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new GameBoardCommand.CommandTypeException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -24,10 +24,11 @@ public class GameResultContract implements net.corda.v5.ledger.utxo.Contract {
 | 
			
		||||
        switch (command.getType()) {
 | 
			
		||||
            case SURRENDER: 
 | 
			
		||||
                GameBoardCommand.validateSurrenderTrx(trx);
 | 
			
		||||
            break;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            // case ACCEPT:
 | 
			
		||||
            // break;
 | 
			
		||||
            case FINISH:
 | 
			
		||||
                GameBoardCommand.validateFinishTrx(trx);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                throw new CordaRuntimeException(UNKNOWN_COMMAND);
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ public class GameBoardState implements ContractState, Counterparty {
 | 
			
		||||
    private final MemberX500Name blackPlayerName;
 | 
			
		||||
    
 | 
			
		||||
    private final Piece.Color moveColor;
 | 
			
		||||
    private final Integer moveNumber;
 | 
			
		||||
    private final Map<Integer, Piece> board;
 | 
			
		||||
    private final String message;
 | 
			
		||||
 | 
			
		||||
@ -27,27 +28,45 @@ public class GameBoardState implements ContractState, Counterparty {
 | 
			
		||||
    private final List<PublicKey> participants;
 | 
			
		||||
 | 
			
		||||
    public GameBoardState(
 | 
			
		||||
        GameProposalState gameBoard
 | 
			
		||||
        GameProposalState gameProposalState
 | 
			
		||||
    ) {
 | 
			
		||||
        this.whitePlayerName = gameBoard.getWhitePlayerName();
 | 
			
		||||
        this.blackPlayerName = gameBoard.getBlackPlayerName();
 | 
			
		||||
        this.whitePlayerName = gameProposalState.getWhitePlayerName();
 | 
			
		||||
        this.blackPlayerName = gameProposalState.getBlackPlayerName();
 | 
			
		||||
        
 | 
			
		||||
        // Initial GameBoard state
 | 
			
		||||
        this.moveColor = Piece.Color.WHITE;
 | 
			
		||||
        this.moveNumber = 0;
 | 
			
		||||
        this.board = new LinkedHashMap<Integer, Piece>(initialBoard);
 | 
			
		||||
        this.message = null;
 | 
			
		||||
 | 
			
		||||
        this.id = UUID.randomUUID();
 | 
			
		||||
        this.participants = gameBoard.getParticipants();
 | 
			
		||||
        this.id = gameProposalState.getId();
 | 
			
		||||
        this.participants = gameProposalState.getParticipants();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public GameBoardState(
 | 
			
		||||
        GameBoardState oldGameBoardState, Map<Integer, Piece> newBoard, Piece.Color moveColor
 | 
			
		||||
    ) {
 | 
			
		||||
        this.whitePlayerName = oldGameBoardState.getWhitePlayerName();
 | 
			
		||||
        this.blackPlayerName = oldGameBoardState.getBlackPlayerName();
 | 
			
		||||
        
 | 
			
		||||
        // Initial GameBoard state
 | 
			
		||||
        this.moveColor = moveColor;
 | 
			
		||||
        this.moveNumber = oldGameBoardState.getMoveNumber() +1;
 | 
			
		||||
        this.board = newBoard;
 | 
			
		||||
        this.message = null;
 | 
			
		||||
 | 
			
		||||
        this.id = oldGameBoardState.getId();
 | 
			
		||||
        this.participants = oldGameBoardState.getParticipants();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    @ConstructorForDeserialization
 | 
			
		||||
    public GameBoardState(MemberX500Name whitePlayerName, MemberX500Name blackPlayerName, 
 | 
			
		||||
            Color moveColor, Map<Integer, Piece> board, String message, 
 | 
			
		||||
            Color moveColor, Integer moveNumber, Map<Integer, Piece> board, String message, 
 | 
			
		||||
            UUID id, List<PublicKey> participants) {
 | 
			
		||||
        this.whitePlayerName = whitePlayerName;
 | 
			
		||||
        this.blackPlayerName = blackPlayerName;
 | 
			
		||||
        this.moveColor = moveColor;
 | 
			
		||||
        this.moveNumber = moveNumber;
 | 
			
		||||
        this.board = board;
 | 
			
		||||
        this.message = message;
 | 
			
		||||
        this.id = id;
 | 
			
		||||
@ -66,6 +85,10 @@ public class GameBoardState implements ContractState, Counterparty {
 | 
			
		||||
        return moveColor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Integer getMoveNumber() {
 | 
			
		||||
        return moveNumber;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Map<Integer, Piece> getBoard() {
 | 
			
		||||
        return board;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ public class GameResultState implements ContractState, Counterparty {
 | 
			
		||||
        this.blackPlayerName = stateGameBoard.getBlackPlayerName();
 | 
			
		||||
        this.victoryColor = victoryColor;
 | 
			
		||||
 | 
			
		||||
        this.id = UUID.randomUUID();
 | 
			
		||||
        this.id = stateGameBoard.getId();
 | 
			
		||||
        this.participants = stateGameBoard.getParticipants();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -102,20 +102,29 @@ public class CommandFlow implements ClientStartableFlow {
 | 
			
		||||
        UtxoTransactionBuilder trxBuilder = utxoLedgerService.createTransactionBuilder()
 | 
			
		||||
            .setNotary(utxoSarGameBoard.getState().getNotaryName())
 | 
			
		||||
            .setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis()))
 | 
			
		||||
            .addInputState(utxoSarGameBoard.getRef())
 | 
			
		||||
            .addCommand(command)
 | 
			
		||||
            .addInputState(utxoSarGameBoard.getRef())
 | 
			
		||||
            .addSignatories(stateGameBoard.getParticipants());
 | 
			
		||||
 | 
			
		||||
        switch (command.getType()) {
 | 
			
		||||
            case SURRENDER:
 | 
			
		||||
            case ACCEPT:
 | 
			
		||||
                final Piece.Color winnerColor = winnerColor(command, stateGameBoard, myName);
 | 
			
		||||
                trxBuilder = trxBuilder
 | 
			
		||||
                    .addOutputState( new GameResultState(stateGameBoard, winnerColor) );
 | 
			
		||||
                    .addOutputState( new GameResultState(
 | 
			
		||||
                        stateGameBoard, 
 | 
			
		||||
                        stateGameBoard.getCounterpartyColor(myName)) // winner color
 | 
			
		||||
                        );
 | 
			
		||||
                break;
 | 
			
		||||
            
 | 
			
		||||
            case MOVE:
 | 
			
		||||
                trxBuilder = trxBuilder
 | 
			
		||||
                    .addOutputState( new GameBoardState(stateGameBoard, stateGameBoard.getBoard(), stateGameBoard.getMoveColor())); // TODO: advance color 
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
            case FINISH:
 | 
			
		||||
                throw new CommandTypeException("GameBoard.CommandFlow can not process externaly issued FINISH commnd");
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                throw new CommandTypeException("GameBoard.CommandFlow doTransaction()");
 | 
			
		||||
                throw new CommandTypeException("GameBoard.CommandFlow doTransaction(): Unknown command");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return commit(
 | 
			
		||||
@ -123,22 +132,6 @@ public class CommandFlow implements ClientStartableFlow {
 | 
			
		||||
            opponentName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Suspendable
 | 
			
		||||
    Piece.Color winnerColor(GameBoardCommand command, GameBoardState stateGameBoard, MemberX500Name myName) {
 | 
			
		||||
 | 
			
		||||
        switch (command.getType()) {
 | 
			
		||||
            case SURRENDER:
 | 
			
		||||
                return stateGameBoard.getCounterpartyColor(myName);
 | 
			
		||||
 | 
			
		||||
            case ACCEPT:
 | 
			
		||||
                //stateGameBoard.getMoveColor();
 | 
			
		||||
                throw new RuntimeException("Unimplemented");
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                throw new CommandTypeException("GameBoard.CommandFlow winnerColor()");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Suspendable
 | 
			
		||||
    SecureHash commit(UtxoSignedTransaction candidateTrx, MemberX500Name counterpartyName) {
 | 
			
		||||
        log.info("About to commit " +candidateTrx.getId());
 | 
			
		||||
@ -170,12 +163,17 @@ public class CommandFlow implements ClientStartableFlow {
 | 
			
		||||
 | 
			
		||||
        switch (command.getType()) {
 | 
			
		||||
            case SURRENDER:
 | 
			
		||||
            case ACCEPT:
 | 
			
		||||
                return viewGameResult(utxoTrx);
 | 
			
		||||
 | 
			
		||||
            case MOVE:
 | 
			
		||||
            case VICTORY: // request, shall be accepted by opponent
 | 
			
		||||
            case DRAW:    // request, shall be accepted by opponent
 | 
			
		||||
                // 1. create initial GameBoardView
 | 
			
		||||
                // 2. check for winning conditions
 | 
			
		||||
                //    - run subcommnd FINISH that will consume current gbUtxo and will produce GameResult state
 | 
			
		||||
                //    - update GameBoardView to have FINISH command
 | 
			
		||||
                // 3. return GameBoardView
 | 
			
		||||
                return viewGameBoard(utxoTrx);
 | 
			
		||||
 | 
			
		||||
            case FINISH:
 | 
			
		||||
                return viewGameBoard(utxoTrx);
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
 | 
			
		||||
@ -65,12 +65,10 @@ public class CommandResponderFlow implements ResponderFlow {
 | 
			
		||||
    GameBoardState getGameBoardState(UtxoLedgerTransaction utxoGameBoard, GameBoardCommand command) {
 | 
			
		||||
        switch (command.getType()) {
 | 
			
		||||
            case SURRENDER:
 | 
			
		||||
            case ACCEPT:
 | 
			
		||||
            case FINISH:
 | 
			
		||||
                return getSingleInputState(utxoGameBoard, GameBoardState.class);
 | 
			
		||||
 | 
			
		||||
            case MOVE:
 | 
			
		||||
            case VICTORY:
 | 
			
		||||
            case DRAW:
 | 
			
		||||
                return getSingleOutputState(utxoGameBoard, GameBoardState.class); 
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
 | 
			
		||||
@ -17,16 +17,26 @@ public class GameBoardView {
 | 
			
		||||
    public final String opponentName;
 | 
			
		||||
    public final Piece.Color opponentColor;
 | 
			
		||||
    public final Boolean opponentMove;
 | 
			
		||||
    public final Integer moveNumber;
 | 
			
		||||
    public final Map<Integer, Piece> board;
 | 
			
		||||
    public final GameBoardCommand previousCommand;
 | 
			
		||||
    public final String message;
 | 
			
		||||
    public final UUID id;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * GameStatus enum:
 | 
			
		||||
     * - YOUR_TURN
 | 
			
		||||
     * - WAIT_FOR_OPPONENT
 | 
			
		||||
     * - VICTORY
 | 
			
		||||
     * - YOU_LOOSE
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    // Serialisation service requires a default constructor
 | 
			
		||||
    public GameBoardView() {
 | 
			
		||||
        this.opponentName = null;
 | 
			
		||||
        this.opponentColor = null;
 | 
			
		||||
        this.opponentMove = null;
 | 
			
		||||
        this.moveNumber = null;
 | 
			
		||||
        this.board = null;
 | 
			
		||||
        this.previousCommand = null;
 | 
			
		||||
        this.message = null;
 | 
			
		||||
@ -36,6 +46,11 @@ public class GameBoardView {
 | 
			
		||||
    // A view from a perspective of a concrete player, on a ledger transaction that has 
 | 
			
		||||
    // produced new GameBoardState
 | 
			
		||||
    public GameBoardView(UtxoLedgerTransaction utxoGameBoard, MemberX500Name myName) throws NotInvolved {
 | 
			
		||||
        // TODO check command type: MOVE vs FINNISH | SURRENDER
 | 
			
		||||
        //                  SingleOutPut vs SingleInput
 | 
			
		||||
        this.previousCommand = UtxoLedgerTransactionUtil
 | 
			
		||||
            .getOptionalCommand(utxoGameBoard, GameBoardCommand.class)
 | 
			
		||||
            .orElseGet(() -> null); // there is no previous command for GameProposal.Accept case
 | 
			
		||||
 | 
			
		||||
        final GameBoardState stateGameBoard = UtxoLedgerTransactionUtil
 | 
			
		||||
            .getSingleOutputState(utxoGameBoard, GameBoardState.class);
 | 
			
		||||
@ -44,13 +59,10 @@ public class GameBoardView {
 | 
			
		||||
        this.opponentColor = stateGameBoard.getCounterpartyColor(myName);
 | 
			
		||||
 | 
			
		||||
        this.opponentMove  = this.opponentColor == stateGameBoard.getMoveColor();
 | 
			
		||||
        this.moveNumber    = stateGameBoard.getMoveNumber();
 | 
			
		||||
        this.board   = stateGameBoard.getBoard();
 | 
			
		||||
        this.message = stateGameBoard.getMessage();
 | 
			
		||||
        this.id      = stateGameBoard.getId();
 | 
			
		||||
 | 
			
		||||
        this.previousCommand = UtxoLedgerTransactionUtil
 | 
			
		||||
            .getOptionalCommand(utxoGameBoard, GameBoardCommand.class)
 | 
			
		||||
            .orElseGet(() -> null); // there is no previous command for GameProposal.Accept case
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ public class CommitResponderFlow implements ResponderFlow {
 | 
			
		||||
    @Suspendable
 | 
			
		||||
    @Override
 | 
			
		||||
    public void call(FlowSession session) {
 | 
			
		||||
        log.info("GameProposal: Commit responder flow");
 | 
			
		||||
        try {
 | 
			
		||||
            UtxoTransactionValidator txValidator = ledgerTransaction -> {
 | 
			
		||||
                final GameProposalCommand command = ledgerTransaction.getCommands(GameProposalCommand.class).get(0);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user