GameState
a base state class for GameProposal, GameBoard and GameResult also will be used as a base building block for GameBoardView
This commit is contained in:
parent
bd6612f3e6
commit
dc702f7584
@ -75,8 +75,8 @@ public class GameBoardCommand implements Command {
|
||||
requireThat(trx.getOutputContractStates().size() == 1, SURRENDER_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);
|
||||
requireThat(inGameBoardState.getWhitePlayerName().compareTo(outGameResultState.getWinnerName()) == 0, IN_OUT_PARTICIPANTS);
|
||||
requireThat(inGameBoardState.getBlackPlayerName().compareTo(outGameResultState.getOpponentName()) == 0, IN_OUT_PARTICIPANTS);
|
||||
}
|
||||
|
||||
public static void validateMoveTrx(UtxoLedgerTransaction trx) {
|
||||
@ -97,8 +97,8 @@ public class GameBoardCommand implements Command {
|
||||
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);
|
||||
requireThat(inGameBoardState.getWhitePlayerName().compareTo(outGameResultState.getWinnerName()) == 0, IN_OUT_PARTICIPANTS);
|
||||
requireThat(inGameBoardState.getBlackPlayerName().compareTo(outGameResultState.getOpponentName()) == 0, IN_OUT_PARTICIPANTS);
|
||||
}
|
||||
|
||||
static final String BAD_ACTIONMOVE_CONSTRUCTOR = "Bad constructor for Action.MOVE";
|
||||
|
@ -1,24 +0,0 @@
|
||||
package djmil.cordacheckers.states;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.corda.v5.base.annotations.CordaSerializable;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
|
||||
@CordaSerializable
|
||||
public interface Game {
|
||||
|
||||
@NotNull
|
||||
MemberX500Name getCounterpartyName(MemberX500Name myName) throws NotInvolved;
|
||||
|
||||
@NotNull
|
||||
UUID getGameUuid();
|
||||
|
||||
public static class NotInvolved extends RuntimeException {
|
||||
public <T> NotInvolved(MemberX500Name myName, Class<T> clazz, UUID uuid) {
|
||||
super(myName +" not involved in " +clazz.getSimpleName() +" UUID " +uuid);
|
||||
}
|
||||
}
|
||||
}
|
@ -11,10 +11,9 @@ import djmil.cordacheckers.states.Piece.Color;
|
||||
import net.corda.v5.base.annotations.ConstructorForDeserialization;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
import net.corda.v5.ledger.utxo.BelongsToContract;
|
||||
import net.corda.v5.ledger.utxo.ContractState;
|
||||
|
||||
@BelongsToContract(GameBoardContract.class)
|
||||
public class GameBoardState implements ContractState, Game {
|
||||
public class GameBoardState extends GameState {
|
||||
|
||||
private final MemberX500Name whitePlayerName;
|
||||
private final MemberX500Name blackPlayerName;
|
||||
@ -22,14 +21,10 @@ public class GameBoardState implements ContractState, Game {
|
||||
private final Piece.Color moveColor;
|
||||
private final Integer moveNumber;
|
||||
private final Map<Integer, Piece> board;
|
||||
private final String message;
|
||||
|
||||
private final UUID gameUuid;
|
||||
private final List<PublicKey> participants;
|
||||
public GameBoardState(GameProposalState gameProposalState) {
|
||||
super(gameProposalState.gameUuid, gameProposalState.message, gameProposalState.participants);
|
||||
|
||||
public GameBoardState(
|
||||
GameProposalState gameProposalState
|
||||
) {
|
||||
this.whitePlayerName = gameProposalState.getWhitePlayerName();
|
||||
this.blackPlayerName = gameProposalState.getBlackPlayerName();
|
||||
|
||||
@ -37,15 +32,12 @@ public class GameBoardState implements ContractState, Game {
|
||||
this.moveColor = Piece.Color.WHITE;
|
||||
this.moveNumber = 0;
|
||||
this.board = new LinkedHashMap<Integer, Piece>(initialBoard);
|
||||
this.message = null;
|
||||
|
||||
this.gameUuid = gameProposalState.getGameUuid();
|
||||
this.participants = gameProposalState.getParticipants();
|
||||
}
|
||||
|
||||
public GameBoardState(
|
||||
GameBoardState oldGameBoardState, Map<Integer, Piece> newBoard, Piece.Color moveColor
|
||||
) {
|
||||
GameBoardState oldGameBoardState, Map<Integer, Piece> newBoard, Piece.Color moveColor) {
|
||||
super(oldGameBoardState.gameUuid, oldGameBoardState.message, oldGameBoardState.participants);
|
||||
|
||||
this.whitePlayerName = oldGameBoardState.getWhitePlayerName();
|
||||
this.blackPlayerName = oldGameBoardState.getBlackPlayerName();
|
||||
|
||||
@ -53,32 +45,30 @@ public class GameBoardState implements ContractState, Game {
|
||||
this.moveColor = moveColor;
|
||||
this.moveNumber = oldGameBoardState.getMoveNumber() +1;
|
||||
this.board = newBoard;
|
||||
this.message = null;
|
||||
|
||||
this.gameUuid = oldGameBoardState.getGameUuid();
|
||||
this.participants = oldGameBoardState.getParticipants();
|
||||
}
|
||||
|
||||
@ConstructorForDeserialization
|
||||
public GameBoardState(MemberX500Name whitePlayerName, MemberX500Name blackPlayerName,
|
||||
Color moveColor, Integer moveNumber, Map<Integer, Piece> board, String message,
|
||||
UUID gameUuid, List<PublicKey> participants) {
|
||||
super(gameUuid, message, participants);
|
||||
|
||||
this.whitePlayerName = whitePlayerName;
|
||||
this.blackPlayerName = blackPlayerName;
|
||||
this.moveColor = moveColor;
|
||||
this.moveNumber = moveNumber;
|
||||
this.board = board;
|
||||
this.message = message;
|
||||
this.gameUuid = gameUuid;
|
||||
this.participants = participants;
|
||||
}
|
||||
|
||||
public MemberX500Name getWhitePlayerName() {
|
||||
return whitePlayerName;
|
||||
}
|
||||
|
||||
public MemberX500Name getBlackPlayerName() {
|
||||
return blackPlayerName;
|
||||
public MemberX500Name getMovePlayerName() {
|
||||
switch (moveColor) {
|
||||
case WHITE:
|
||||
return whitePlayerName;
|
||||
case BLACK:
|
||||
return blackPlayerName;
|
||||
default:
|
||||
throw new Piece.Color.UnknownException();
|
||||
}
|
||||
}
|
||||
|
||||
public Piece.Color getMoveColor() {
|
||||
@ -93,16 +83,9 @@ public class GameBoardState implements ContractState, Game {
|
||||
return board;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public UUID getGameUuid() {
|
||||
return gameUuid;
|
||||
}
|
||||
|
||||
public List<PublicKey> getParticipants() {
|
||||
return participants;
|
||||
@Override
|
||||
public MemberX500Name getWhitePlayerName() {
|
||||
return whitePlayerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -113,26 +96,10 @@ public class GameBoardState implements ContractState, Game {
|
||||
if (blackPlayerName.compareTo(myName) == 0)
|
||||
return whitePlayerName;
|
||||
|
||||
throw new Game.NotInvolved(myName, GameBoardState.class, this.gameUuid);
|
||||
}
|
||||
|
||||
public Piece.Color getCounterpartyColor(MemberX500Name myName) throws NotInvolved {
|
||||
final MemberX500Name opponentName = getCounterpartyName(myName);
|
||||
|
||||
return getWhitePlayerName().compareTo(opponentName) == 0 ? Piece.Color.WHITE : Piece.Color.BLACK;
|
||||
}
|
||||
|
||||
public MemberX500Name getMovePlayerName() {
|
||||
switch (moveColor) {
|
||||
case WHITE:
|
||||
return whitePlayerName;
|
||||
case BLACK:
|
||||
return blackPlayerName;
|
||||
default:
|
||||
throw new Piece.Color.UnknownException();
|
||||
}
|
||||
throw new GameState.NotInvolved(myName, GameBoardState.class, this.gameUuid);
|
||||
}
|
||||
|
||||
// TODO: move to contract
|
||||
public final static Map<Integer, Piece> initialBoard = Map.ofEntries(
|
||||
// Inspired by Checkers notation rules: https://www.bobnewell.net/nucleus/checkers.php
|
||||
Map.entry( 1, new Piece(Piece.Color.BLACK, Piece.Type.MAN)),
|
||||
|
@ -8,17 +8,13 @@ import djmil.cordacheckers.contracts.GameProposalContract;
|
||||
import net.corda.v5.base.annotations.ConstructorForDeserialization;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
import net.corda.v5.ledger.utxo.BelongsToContract;
|
||||
import net.corda.v5.ledger.utxo.ContractState;
|
||||
|
||||
@BelongsToContract(GameProposalContract.class)
|
||||
public class GameProposalState implements ContractState, Game {
|
||||
public class GameProposalState extends GameState {
|
||||
|
||||
private final MemberX500Name issuer;
|
||||
private final MemberX500Name acquier;
|
||||
private final Piece.Color acquierColor;
|
||||
private final String message;
|
||||
private final UUID gameUuid;
|
||||
private final List<PublicKey> participants;
|
||||
|
||||
@ConstructorForDeserialization
|
||||
public GameProposalState(
|
||||
@ -29,12 +25,10 @@ public class GameProposalState implements ContractState, Game {
|
||||
UUID gameUuid,
|
||||
List<PublicKey> participants
|
||||
) {
|
||||
super(gameUuid, message, participants);
|
||||
this.issuer = issuer;
|
||||
this.acquier = acquier;
|
||||
this.acquierColor = acquierColor;
|
||||
this.message = message;
|
||||
this.gameUuid = gameUuid;
|
||||
this.participants = participants;
|
||||
}
|
||||
|
||||
public MemberX500Name getIssuer() {
|
||||
@ -49,26 +43,10 @@ public class GameProposalState implements ContractState, Game {
|
||||
return acquierColor;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public UUID getGameUuid() {
|
||||
return gameUuid;
|
||||
}
|
||||
|
||||
public List<PublicKey> getParticipants() {
|
||||
return participants;
|
||||
}
|
||||
|
||||
public MemberX500Name getWhitePlayerName() {
|
||||
return acquierColor == Piece.Color.WHITE ? getAcquier() : getIssuer();
|
||||
}
|
||||
|
||||
public MemberX500Name getBlackPlayerName() {
|
||||
return acquierColor == Piece.Color.BLACK ? getAcquier() : getIssuer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberX500Name getCounterpartyName(MemberX500Name myName) throws NotInvolved {
|
||||
if (issuer.compareTo(myName) == 0)
|
||||
@ -77,7 +55,7 @@ public class GameProposalState implements ContractState, Game {
|
||||
if (acquier.compareTo(myName) == 0)
|
||||
return issuer;
|
||||
|
||||
throw new Game.NotInvolved(myName, GameProposalState.class, this.gameUuid);
|
||||
throw new GameState.NotInvolved(myName, GameProposalState.class, this.gameUuid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,68 +8,57 @@ import djmil.cordacheckers.contracts.GameResultContract;
|
||||
import net.corda.v5.base.annotations.ConstructorForDeserialization;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
import net.corda.v5.ledger.utxo.BelongsToContract;
|
||||
import net.corda.v5.ledger.utxo.ContractState;
|
||||
|
||||
@BelongsToContract(GameResultContract.class)
|
||||
public class GameResultState implements ContractState, Game {
|
||||
public class GameResultState extends GameState {
|
||||
|
||||
private final MemberX500Name whitePlayerName;
|
||||
private final MemberX500Name blackPlayerName;
|
||||
private final MemberX500Name winnerName;
|
||||
private final MemberX500Name opponentName;
|
||||
|
||||
private final Piece.Color victoryColor;
|
||||
|
||||
private final UUID gameUuid;
|
||||
private final List<PublicKey> participants;
|
||||
private final Piece.Color winnerColor;
|
||||
|
||||
@ConstructorForDeserialization
|
||||
public GameResultState(MemberX500Name whitePlayerName, MemberX500Name blackPlayerName, Piece.Color victoryColor,
|
||||
UUID gameUuid, List<PublicKey> participants) {
|
||||
this.whitePlayerName = whitePlayerName;
|
||||
this.blackPlayerName = blackPlayerName;
|
||||
this.victoryColor = victoryColor;
|
||||
this.gameUuid = gameUuid;
|
||||
this.participants = participants;
|
||||
public GameResultState(MemberX500Name winnerName, MemberX500Name opponentName, Piece.Color winnerColor,
|
||||
UUID gameUuid, String message, List<PublicKey> participants) {
|
||||
super(gameUuid, message, participants);
|
||||
this.winnerName = winnerName;
|
||||
this.opponentName = opponentName;
|
||||
this.winnerColor = winnerColor;
|
||||
}
|
||||
|
||||
public GameResultState(GameBoardState stateGameBoard, Piece.Color victoryColor) {
|
||||
this.whitePlayerName = stateGameBoard.getWhitePlayerName();
|
||||
this.blackPlayerName = stateGameBoard.getBlackPlayerName();
|
||||
this.victoryColor = victoryColor;
|
||||
|
||||
this.gameUuid = stateGameBoard.getGameUuid();
|
||||
this.participants = stateGameBoard.getParticipants();
|
||||
public GameResultState(GameBoardState gameBoardState, Piece.Color victoryColor) {
|
||||
super(gameBoardState.gameUuid, null, gameBoardState.participants);
|
||||
this.winnerName = gameBoardState.getWhitePlayerName();
|
||||
this.opponentName = gameBoardState.getBlackPlayerName();
|
||||
this.winnerColor = victoryColor;
|
||||
}
|
||||
|
||||
public MemberX500Name getWhitePlayerName() {
|
||||
return whitePlayerName;
|
||||
public MemberX500Name getWinnerName() {
|
||||
return winnerName;
|
||||
}
|
||||
|
||||
public MemberX500Name getBlackPlayerName() {
|
||||
return blackPlayerName;
|
||||
public MemberX500Name getOpponentName() {
|
||||
return opponentName;
|
||||
}
|
||||
|
||||
public Piece.Color getVictoryColor() {
|
||||
return victoryColor;
|
||||
}
|
||||
|
||||
public UUID getGameUuid() {
|
||||
return gameUuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PublicKey> getParticipants() {
|
||||
return participants;
|
||||
public Piece.Color getWinnerColor() {
|
||||
return winnerColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberX500Name getCounterpartyName(MemberX500Name myName) throws NotInvolved {
|
||||
if (whitePlayerName.compareTo(myName) == 0)
|
||||
return blackPlayerName;
|
||||
if (winnerName.compareTo(myName) == 0)
|
||||
return opponentName;
|
||||
|
||||
if (blackPlayerName.compareTo(myName) == 0)
|
||||
return whitePlayerName;
|
||||
if (opponentName.compareTo(myName) == 0)
|
||||
return winnerName;
|
||||
|
||||
throw new Game.NotInvolved(myName, GameResultState.class, this.gameUuid);
|
||||
throw new GameState.NotInvolved(myName, GameResultState.class, this.gameUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
MemberX500Name getWhitePlayerName() {
|
||||
return winnerColor == Piece.Color.WHITE ? winnerName : opponentName;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package djmil.cordacheckers.states;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.corda.v5.base.annotations.CordaSerializable;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
import net.corda.v5.ledger.utxo.ContractState;
|
||||
|
||||
@CordaSerializable
|
||||
public abstract class GameState implements ContractState {
|
||||
final UUID gameUuid;
|
||||
final String message;
|
||||
final List<PublicKey> participants;
|
||||
|
||||
@NotNull
|
||||
abstract MemberX500Name getWhitePlayerName();
|
||||
|
||||
@NotNull
|
||||
abstract MemberX500Name getCounterpartyName(MemberX500Name myName) throws NotInvolved;
|
||||
|
||||
GameState(UUID gameUuid, String message, List<PublicKey> participants) {
|
||||
this.gameUuid = gameUuid;
|
||||
this.message = message;
|
||||
this.participants = participants;
|
||||
}
|
||||
|
||||
public UUID getGameUuid() {
|
||||
return gameUuid;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public List<PublicKey> getParticipants() {
|
||||
return participants;
|
||||
}
|
||||
|
||||
public MemberX500Name getBlackPlayerName() {
|
||||
return getCounterpartyName(getWhitePlayerName());
|
||||
}
|
||||
|
||||
public Piece.Color getCounterpartyColor(MemberX500Name myName) throws NotInvolved {
|
||||
final MemberX500Name opponentName = getCounterpartyName(myName);
|
||||
|
||||
return getWhitePlayerName().compareTo(opponentName) == 0 ? Piece.Color.WHITE : Piece.Color.BLACK;
|
||||
}
|
||||
|
||||
public static class NotInvolved extends RuntimeException {
|
||||
public <T> NotInvolved(MemberX500Name name, Class<T> clazz, UUID uuid) {
|
||||
super(name +" is not involved in " +clazz.getSimpleName() +" UUID " +uuid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
||||
|
||||
import djmil.cordacheckers.contracts.GameBoardCommand;
|
||||
import djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil;
|
||||
import djmil.cordacheckers.states.Game.NotInvolved;
|
||||
import djmil.cordacheckers.states.GameState.NotInvolved;
|
||||
import djmil.cordacheckers.states.GameBoardState;
|
||||
import djmil.cordacheckers.states.Piece;
|
||||
import net.corda.v5.base.types.MemberX500Name;
|
||||
|
@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import djmil.cordacheckers.FlowResult;
|
||||
import djmil.cordacheckers.states.GameBoardState;
|
||||
import djmil.cordacheckers.states.Game.NotInvolved;
|
||||
import djmil.cordacheckers.states.GameState.NotInvolved;
|
||||
import net.corda.v5.application.flows.ClientRequestBody;
|
||||
import net.corda.v5.application.flows.ClientStartableFlow;
|
||||
import net.corda.v5.application.flows.CordaInject;
|
||||
|
@ -10,7 +10,7 @@ import djmil.cordacheckers.contracts.GameProposalCommand;
|
||||
import djmil.cordacheckers.gameboard.GameBoardView;
|
||||
import djmil.cordacheckers.states.GameBoardState;
|
||||
import djmil.cordacheckers.states.GameProposalState;
|
||||
import djmil.cordacheckers.states.Game.NotInvolved;
|
||||
import djmil.cordacheckers.states.GameState.NotInvolved;
|
||||
import net.corda.v5.application.flows.ClientRequestBody;
|
||||
import net.corda.v5.application.flows.ClientStartableFlow;
|
||||
import net.corda.v5.application.flows.CordaInject;
|
||||
|
@ -20,9 +20,9 @@ public class GameResultView {
|
||||
}
|
||||
|
||||
public GameResultView(GameResultState gameResultState) {
|
||||
this.whitePlayerName = gameResultState.getWhitePlayerName().getCommonName();
|
||||
this.blackPlayerName = gameResultState.getBlackPlayerName().getCommonName();
|
||||
this.victoryColor = gameResultState.getVictoryColor();
|
||||
this.whitePlayerName = gameResultState.getWinnerName().getCommonName();
|
||||
this.blackPlayerName = gameResultState.getOpponentName().getCommonName();
|
||||
this.victoryColor = gameResultState.getWinnerColor();
|
||||
this.id = gameResultState.getGameUuid();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user