diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-07-24 12:17:26 -0400 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-07-28 18:03:10 +0200 |
| commit | 749dc58ced17662d9f6dd40bb44d315d12d3d48b (patch) | |
| tree | 170a957d296dc82467310b7b22f66d2ad440dff7 | |
| parent | ce875a8454265ac4a17be25eeaa6e0b136936a56 (diff) | |
| download | muhqs-game-749dc58ced17662d9f6dd40bb44d315d12d3d48b.tar.gz muhqs-game-749dc58ced17662d9f6dd40bb44d315d12d3d48b.zip | |
add random challange aupport to the client
| -rw-r--r-- | go/client/game.go | 8 | ||||
| -rw-r--r-- | go/client/startMenu.go | 22 | ||||
| -rw-r--r-- | go/game/challenge.go | 100 | ||||
| -rw-r--r-- | go/game/map.go | 6 |
4 files changed, 134 insertions, 2 deletions
diff --git a/go/client/game.go b/go/client/game.go index 71fa6b4c..fdb72683 100644 --- a/go/client/game.go +++ b/go/client/game.go @@ -117,12 +117,16 @@ func (g *Game) loadMap(mapName string) *Game { log.Fatal(err) } g.gameState.SetMap(m) + g.initMapUi() + return g +} + +func (g *Game) initMapUi() { g.mapView = ui.NewMapView(g.gameState) g.AddWidget(g.mapView) - storeTiles := m.FilterTiles(func(t *game.Tile) bool { return t.Type == game.TileTypes.Store }) + storeTiles := g.gameState.Map().FilterTiles(func(t *game.Tile) bool { return t.Type == game.TileTypes.Store }) g.storesOnMap = len(storeTiles) > 0 - return g } func (g *Game) addActivePlayer(name string, deckList string) *Game { diff --git a/go/client/startMenu.go b/go/client/startMenu.go index a9ee5c48..2c3225b9 100644 --- a/go/client/startMenu.go +++ b/go/client/startMenu.go @@ -132,6 +132,17 @@ func (m *startMenu) build() { m.startDeck = deckInput.Text() m.startGame() })) + m.AddWidget(ui.NewSimpleButton( + (m.Width-START_BUTTON_WIDTH)/2, + deckInput.Y+deckInput.Height+4*START_BUTTON_HEIGHT, + START_BUTTON_WIDTH, + START_BUTTON_HEIGHT, + "Challenge", + func(*ui.SimpleButton) { + m.playerName = playerInput.Text() + s := game.NewRandomChallenge(m.playerName) + m.startChallenge(s) + })) } func (m *startMenu) Update() error { @@ -178,3 +189,14 @@ func (m *startMenu) startGame() { activities.PushActivity(g.Start()) } + +func (m *startMenu) startChallenge(state game.State) { + g := newGame(m.app, state) + + g.initMapUi() + p := state.PlayerByName(m.playerName) + g.activePlayerId = p.Id + g.initPlayerUi(p) + + activities.PushActivity(g.Start()) +} diff --git a/go/game/challenge.go b/go/game/challenge.go new file mode 100644 index 00000000..9ce4515e --- /dev/null +++ b/go/game/challenge.go @@ -0,0 +1,100 @@ +package game + +import ( + "log" + "math/rand" +) + +func NewRandomChallenge(name string) *LocalState { + s := NewLocalState() + maps := []string{"2P-ring-street", "2P-river-king"} + if m, err := GetMap(maps[rand.Intn(len(maps))]); err != nil { + log.Panic(err) + } else { + s.SetMap(m) + } + + // Prepare the players + s.AddNewPlayer(name, NewDeck()) + // Add Opponent + ai := s.AddNewPlayer("opponent", NewDeck()) + ai.Ctrl = NewSimpleAiControl(ai) + + switch rand.Intn(2) { + // Cavalry Archer Challenge + case 0: + return prepCavArcherChallenge(s) + // Random Base Challenge + default: + return prepBaseChallenge(s) + } +} + +func prepCavArcherChallenge(s *LocalState) *LocalState { + // Override old Prepare to prevent Kings from beeing spawned + s._map.Prepare = func(*LocalState) { + u := NewCard("base/cavalry_archer") + tiles := s._map.AvailableTilesFor(u) + tile := tiles[rand.Intn(len(tiles))] + p := s.PlayerById(1) + p.Deck = NewDeck() + s.addNewUnit(u, tile.Position, p) + + // Prepare the opponent's units + nUnits := rand.Intn(2) + 4 + units := make([]*Card, 0, nUnits) + // Only use Melee Units + candidates := NewDeckFromCardPaths(Sets.Base.CardPaths()).FilterCards(func(c *Card) bool { + if c.Type != CardTypes.Unit { + return false + } + + // Disallow armor since the cavalry archer can not penetrate it. + if _, err := c.getXEffect("armor"); err == nil { + return false + } + + var attack Attack + if attackDesc, found := c.Values["attack"]; found { + attack = parseAttack(attackDesc) + return attack.MaxRange() == 1 + } + return false + }) + + for range nUnits { + units = append(units, NewCard(candidates[rand.Intn(len(candidates))].Path())) + } + + for _, u := range units { + tiles := s._map.AvailableTilesFor(u) + tile := tiles[rand.Intn(len(tiles))] + ai := s.PlayerById(2) + s.addNewUnit(u, tile.Position, ai) + } + + s._map.WinCondition = func(*LocalState) []*Player { + winners := []*Player{} + for _, p := range s.players { + if len(s.EnemyUnits(p)) == 0 { + winners = append(winners, p) + } + } + return winners + } + } + + return s +} + +func prepBaseChallenge(s *LocalState) *LocalState { + p := s.PlayerById(1) + nCards := rand.Intn(6) + nCards = nCards + 3 + NewRandomDeck(nCards, []SetIdentifier{Sets.Base, Sets.Magic, Sets.Equipments}).MoveInto(p.Store) + + ai := s.PlayerById(2) + ai.Deck = NewRandomDeck(nCards, []SetIdentifier{Sets.Base}) + + return s +} diff --git a/go/game/map.go b/go/game/map.go index 2b0bebd7..be541cdd 100644 --- a/go/game/map.go +++ b/go/game/map.go @@ -285,6 +285,12 @@ func (m *Map) FreeTiles() []*Tile { return m.FilterTiles(func(t *Tile) bool { return t.IsFree() }) } +func (m *Map) AvailableTilesFor(c *Card) []*Tile { + return m.FilterTiles(func(t *Tile) bool { + return t.IsAvailableForCard(c) + }) +} + func (m *Map) distributeStoreCards(cards PileOfCards, rand *rand.Rand) { nStores := len(m.Stores) stores := make([]*Store, 0, nStores) |
