Mulligan coding
This commit is contained in:
parent
acf0eb498f
commit
9f9c82474e
@ -63,7 +63,7 @@ public class GameConnection extends Thread {
|
|||||||
this.playerId = (long) handshake.getClientHandle();
|
this.playerId = (long) handshake.getClientHandle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( packet.getType() == 115 ) {
|
if( packet.getType() == PegasusPacketType.SendPing.getValue() ) {
|
||||||
pong();
|
pong();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,15 @@ import com.alterdekim.hearthhack.entity.Deck;
|
|||||||
import com.alterdekim.hearthhack.game.*;
|
import com.alterdekim.hearthhack.game.*;
|
||||||
import com.alterdekim.hearthhack.service.UserService;
|
import com.alterdekim.hearthhack.service.UserService;
|
||||||
import com.alterdekim.hearthhack.util.PegasusPacket;
|
import com.alterdekim.hearthhack.util.PegasusPacket;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -46,10 +46,11 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
private final String password;
|
private final String password;
|
||||||
|
|
||||||
private GameState globalState;
|
private GameState globalState;
|
||||||
|
private RunningState runningState;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private ConcurrentLinkedQueue<IncomeGamePacket> incomeQueue;
|
private final ConcurrentLinkedQueue<IncomeGamePacket> incomeQueue;
|
||||||
private ConcurrentLinkedQueue<OutcomeGamePacket> outcomeQueue;
|
private final ConcurrentLinkedQueue<OutcomeGamePacket> outcomeQueue;
|
||||||
|
|
||||||
// TODO: abolish that later. It's a temporary solution
|
// TODO: abolish that later. It's a temporary solution
|
||||||
private int entity_id = 4;
|
private int entity_id = 4;
|
||||||
@ -63,6 +64,7 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
this.decks = new ConcurrentHashMap<>();
|
this.decks = new ConcurrentHashMap<>();
|
||||||
this.callbacks = new ConcurrentHashMap<>();
|
this.callbacks = new ConcurrentHashMap<>();
|
||||||
this.globalState = GameState.CreateGame;
|
this.globalState = GameState.CreateGame;
|
||||||
|
this.runningState = RunningState.INITIAL_DEAL;
|
||||||
this.objectConfig = objectConfig;
|
this.objectConfig = objectConfig;
|
||||||
log.info("GameRoom players: {}", this.players);
|
log.info("GameRoom players: {}", this.players);
|
||||||
this.start(); // TODO: debug mode should stop that
|
this.start(); // TODO: debug mode should stop that
|
||||||
@ -86,14 +88,137 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processIncomePacket(IncomeGamePacket packet) {
|
private void processIncomePacket(IncomeGamePacket packet) {
|
||||||
log.info("processIncomePacket: {}", packet.getPacket());
|
try {
|
||||||
/* if( packet.getPacket().getType() != 1) return;
|
switch (PegasusPacketType.fromInt(packet.getPacket().getType())) {
|
||||||
List<OutcomeGamePacket> l = this.outcomeQueue.stream()
|
case SendChoices -> processChoices(packet.getPlayerId(), PegasusGame.ChooseEntities.parseFrom((byte[]) packet.getPacket().getBody()));
|
||||||
.filter(p -> p.getPlayerId().longValue() == packet.getPlayerId().longValue())
|
case SendEmoteOrUI -> processEmoteOrUI(packet.getPlayerId(), PegasusGame.UserUI.parseFrom((byte[]) packet.getPacket().getBody()));
|
||||||
|
default -> log.warn("processIncomePacket: {}", packet.getPacket());
|
||||||
|
}
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processChoices(final Long id, PegasusGame.ChooseEntities packet) {
|
||||||
|
if(this.globalState != GameState.Running || this.runningState != RunningState.INITIAL_DEAL || this.findPlayerById(id).isEmpty()) return;
|
||||||
|
// initial_deal state:
|
||||||
|
List<Integer> redeal = this.decks.get(id).getHandCards()
|
||||||
|
.stream()
|
||||||
|
.map(PegasusGame.PowerHistoryEntity.Builder::getEntity)
|
||||||
|
.filter(entity -> !packet.getEntitiesList().contains(entity))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
GamePacketCallback callback = this.callbacks.get(packet.getPlayerId());
|
|
||||||
if (callback == null) return;
|
PegasusGame.PowerHistory.Builder pw = PegasusGame.PowerHistory.newBuilder();
|
||||||
l.forEach(p -> callback.onMessage(p.getPacket()));*/
|
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(this.findPlayerById(id).get().getController()+1)
|
||||||
|
.setTag(GameTag.MULLIGAN_STATE.getValue())
|
||||||
|
.setValue(TagMulligan.DEALING.ordinal())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Queue<Integer> handPoses = new ArrayDeque<>();
|
||||||
|
|
||||||
|
IntStream.range(0, this.decks.get(id).getSize())
|
||||||
|
.boxed()
|
||||||
|
.filter(c -> redeal.contains(this.decks.get(id).getCard(c).getEntity()))
|
||||||
|
.forEach(i -> {
|
||||||
|
PegasusGame.PowerHistoryEntity.Builder b = this.decks.get(id).getCard(i)
|
||||||
|
.addTags(PegasusGame.Tag.newBuilder()
|
||||||
|
.setName(GameTag.ZONE.getValue())
|
||||||
|
.setValue(TagZone.DECK.ordinal())
|
||||||
|
);
|
||||||
|
handPoses.add(
|
||||||
|
b.getTagsList()
|
||||||
|
.stream()
|
||||||
|
.filter(t -> t.getName() == GameTag.ZONE_POSITION.getValue())
|
||||||
|
.map(PegasusGame.Tag::getValue)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(0)
|
||||||
|
);
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(this.decks.get(id).getCard(i).getEntity())
|
||||||
|
.setTag(GameTag.ZONE.getValue())
|
||||||
|
.setValue(TagZone.DECK.ordinal())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this.decks.get(id).updateCard(b, i);
|
||||||
|
});
|
||||||
|
new Random()
|
||||||
|
.ints(handPoses.size(), 0, this.decks.get(id).getSize())
|
||||||
|
.boxed()
|
||||||
|
.forEach(i -> {
|
||||||
|
var l = this.decks.get(id).getCard(i);
|
||||||
|
IntStream.range(0, l.getTagsCount())
|
||||||
|
.boxed()
|
||||||
|
.filter(h -> l.getTags(h).getName() == GameTag.ZONE_POSITION.getValue())
|
||||||
|
.forEach(l::removeTags);
|
||||||
|
PegasusGame.Tag t = PegasusGame.Tag.newBuilder()
|
||||||
|
.setName(GameTag.ZONE_POSITION.getValue())
|
||||||
|
.setValue(handPoses.poll())
|
||||||
|
.build();
|
||||||
|
l.addTags(t);
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(l.getEntity())
|
||||||
|
.setTag(GameTag.ZONE_POSITION.getValue())
|
||||||
|
.setValue(t.getValue())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(l.getEntity())
|
||||||
|
.setTag(GameTag.ZONE.getValue())
|
||||||
|
.setValue(TagZone.HAND.ordinal())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
IntStream.range(0, l.getTagsCount())
|
||||||
|
.boxed()
|
||||||
|
.filter(h -> l.getTags(h).getName() == GameTag.ZONE.getValue())
|
||||||
|
.forEach(h -> l.setTags(h, l.getTags(h).toBuilder().setValue(TagZone.HAND.ordinal())));
|
||||||
|
this.decks.get(id).updateCard(l, i);
|
||||||
|
});
|
||||||
|
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(this.findPlayerById(id).get().getController()+1)
|
||||||
|
.setTag(GameTag.MULLIGAN_STATE.getValue())
|
||||||
|
.setValue(TagMulligan.WAITING.ordinal())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(this.findPlayerById(id).get().getController()+1)
|
||||||
|
.setTag(GameTag.MULLIGAN_STATE.getValue())
|
||||||
|
.setValue(TagMulligan.DONE.ordinal())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
pw.addList(PegasusGame.PowerHistoryData.newBuilder()
|
||||||
|
.setTagChange(PegasusGame.PowerHistoryTagChange.newBuilder()
|
||||||
|
.setEntity(1)
|
||||||
|
.setTag(GameTag.NEXT_STEP.getValue())
|
||||||
|
.setValue(TagStep.MAIN_READY.ordinal())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.broadcast(new PegasusPacket(19, 0, pw.build().toByteArray()));
|
||||||
|
// log.info("Initial_deal choices: player_id={}; packet={}", id, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processEmoteOrUI(final Long id, PegasusGame.UserUI packet) {
|
||||||
|
this.players.stream()
|
||||||
|
.filter(p -> p.getUserId().longValue() != id.longValue())
|
||||||
|
.forEach(p -> this.outcomeQueue.add(
|
||||||
|
new OutcomeGamePacket(
|
||||||
|
p.getUserId(),
|
||||||
|
new PegasusPacket( 15, 0, packet.toBuilder().setPlayerId(id.intValue()).build().toByteArray())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateGameState() {
|
private void updateGameState() {
|
||||||
@ -102,7 +227,6 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
case CreateGame -> createGameEntity();
|
case CreateGame -> createGameEntity();
|
||||||
case CreateDecks -> createDeckEntities();
|
case CreateDecks -> createDeckEntities();
|
||||||
case CreateHeroes -> createPlayerHeroEntity();
|
case CreateHeroes -> createPlayerHeroEntity();
|
||||||
case CreateHeroPowers -> createPlayerHeroPowerEntity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +511,7 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
this.decks.get(player.getUserId()).updateCard(b);
|
this.decks.get(player.getUserId()).updateCard(b, di);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i <= 3; i++, this.entity_id++, di++) {
|
for (int i = 1; i <= 3; i++, this.entity_id++, di++) {
|
||||||
@ -414,7 +538,7 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
this.decks.get(player.getUserId()).updateCard(b);
|
this.decks.get(player.getUserId()).updateCard(b, di);
|
||||||
}
|
}
|
||||||
|
|
||||||
// there was a place for hero & hero_power
|
// there was a place for hero & hero_power
|
||||||
@ -449,11 +573,6 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
this.nextGlobalState();
|
this.nextGlobalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createCardEntity() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createPlayerHeroEntity() {
|
public void createPlayerHeroEntity() {
|
||||||
log.info("Player hero entity");
|
log.info("Player hero entity");
|
||||||
@ -562,12 +681,6 @@ public class GameRoom extends Thread implements IGameRoom {
|
|||||||
this.nextGlobalState();
|
this.nextGlobalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createPlayerHeroPowerEntity() {
|
|
||||||
log.info("hero power entity");
|
|
||||||
this.nextGlobalState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<RoomPlayerDTO> findPlayerById(Long id) {
|
private Optional<RoomPlayerDTO> findPlayerById(Long id) {
|
||||||
return players.stream().filter(p -> p.getUserId().longValue() == id.longValue()).findFirst();
|
return players.stream().filter(p -> p.getUserId().longValue() == id.longValue()).findFirst();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,5 @@ package com.alterdekim.hearthhack.component.interfaces;
|
|||||||
public interface IGameRoom {
|
public interface IGameRoom {
|
||||||
void createGameEntity();
|
void createGameEntity();
|
||||||
void createDeckEntities();
|
void createDeckEntities();
|
||||||
void createCardEntity();
|
|
||||||
void createPlayerHeroEntity();
|
void createPlayerHeroEntity();
|
||||||
void createPlayerHeroPowerEntity();
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ public enum GameState {
|
|||||||
CreateGame,
|
CreateGame,
|
||||||
CreateDecks,
|
CreateDecks,
|
||||||
CreateHeroes,
|
CreateHeroes,
|
||||||
CreateHeroPowers,
|
|
||||||
Running;
|
Running;
|
||||||
|
|
||||||
public static GameState next(GameState state) {
|
public static GameState next(GameState state) {
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.alterdekim.hearthhack.game;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum PegasusPacketType {
|
||||||
|
GetGameState(1),
|
||||||
|
Concede(11),
|
||||||
|
SendPing(115),
|
||||||
|
SendChoices(3),
|
||||||
|
SendOption(2),
|
||||||
|
SendEmoteOrUI(15);
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
|
||||||
|
public static PegasusPacketType fromInt(int i) {
|
||||||
|
for(PegasusPacketType t : values()) {
|
||||||
|
if( t.getValue() == i ) return t;
|
||||||
|
}
|
||||||
|
return SendPing;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.alterdekim.hearthhack.game;
|
||||||
|
|
||||||
|
public enum RunningState {
|
||||||
|
INITIAL_DEAL,
|
||||||
|
DRAW,
|
||||||
|
TURN
|
||||||
|
}
|
@ -7,33 +7,33 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
public class GameDeck {
|
public class GameDeck {
|
||||||
private final Map<String, PegasusGame.PowerHistoryEntity.Builder> deck;
|
private final List<PegasusGame.PowerHistoryEntity.Builder> deck;
|
||||||
|
|
||||||
public GameDeck() {
|
public GameDeck() {
|
||||||
this.deck = new HashMap<>();
|
this.deck = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PegasusGame.PowerHistoryEntity.Builder getCard(Integer i) {
|
public PegasusGame.PowerHistoryEntity.Builder getCard(Integer i) {
|
||||||
return this.deck.get(getKeys().get(i));
|
return this.deck.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<PegasusGame.PowerHistoryEntity.Builder> getByEntityId(Integer i) { return this.deck.stream().filter(c -> c.getEntity() == i).findFirst(); }
|
||||||
|
|
||||||
public Integer getSize() {
|
public Integer getSize() {
|
||||||
return this.deck.values().size();
|
return this.deck.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCard(PegasusGame.PowerHistoryEntity.Builder b) {
|
public void addCard(PegasusGame.PowerHistoryEntity.Builder b) {
|
||||||
this.deck.put(b.getName(), b);
|
this.deck.add(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCard(PegasusGame.PowerHistoryEntity.Builder b) {
|
public void updateCard(PegasusGame.PowerHistoryEntity.Builder b, Integer i) {
|
||||||
deck.put(b.getName(), b);
|
deck.set(i, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PegasusGame.PowerHistoryEntity.Builder> getHandCards() {
|
public List<PegasusGame.PowerHistoryEntity.Builder> getHandCards() {
|
||||||
@ -42,7 +42,6 @@ public class GameDeck {
|
|||||||
|
|
||||||
public List<PegasusGame.PowerHistoryEntity.Builder> getCardsByTag(GameTag tag, Integer val) {
|
public List<PegasusGame.PowerHistoryEntity.Builder> getCardsByTag(GameTag tag, Integer val) {
|
||||||
return deck
|
return deck
|
||||||
.values()
|
|
||||||
.stream()
|
.stream()
|
||||||
.filter(c -> c.getTagsList()
|
.filter(c -> c.getTagsList()
|
||||||
.stream()
|
.stream()
|
||||||
@ -51,10 +50,7 @@ public class GameDeck {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getKeys() {
|
public void shuffleDeck() {
|
||||||
return this.deck.keySet()
|
Collections.shuffle(deck);
|
||||||
.stream()
|
|
||||||
.sorted()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user