aboutsummaryrefslogtreecommitdiff
path: root/go/game/challenge.go
blob: b27ef1625c03c7467b10cf5729d8ee26e9b5982e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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) + 2

		// add support equipment
		if nUnits > 3 {
			candidates := NewDeckFromCardPaths(Sets.Base.CardPaths()).FilterCards(func(c *Card) bool {
				return c.Type == CardTypes.Equipment
			})
			e := NewCard(candidates[rand.Intn(len(candidates))].Path())
			tiles := s._map.AvailableTilesFor(e)
			tile := tiles[rand.Intn(len(tiles))]
			s.addNewEquipment(e, tile.Position, p)
		}

		units := make([]*Card, 0, nUnits)
		ai := s.PlayerById(2)
		// 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))]
			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
	d := NewRandomDeck(nCards, []SetIdentifier{Sets.Base, Sets.Magic, Sets.Equipments})
	p.Store.AddCards(d.FilterCards(func(c *Card) bool { return c.IsBuyable() }))

	ai := s.PlayerById(2)
	ai.Deck = NewRandomDeck(nCards, []SetIdentifier{Sets.Base})

	return s
}