Implement a very crude "game" as a test. Also updates Player.
This commit is contained in:
		| @@ -49,7 +49,8 @@ type CardOption[C StatsCollection] interface { | ||||
| 	// a warning, the game crashes. | ||||
| 	// | ||||
| 	// After an option is enacted, the card is deleted. If a card should be | ||||
| 	// repeatable, Enact must return it to the deck (on every option). | ||||
| 	// repeatable, Enact must return it to the deck (on every option) or | ||||
| 	// the card needs to reinsert itself with its Then function. | ||||
| 	Enact(p *Player[C]) (Message, error) | ||||
|  | ||||
| 	// Enabled returns whether this option can curently be enacted. | ||||
| @@ -63,7 +64,8 @@ type BasicCard[C StatsCollection] struct { | ||||
| 	IsUrgent    bool | ||||
| 	CardText    Message | ||||
| 	CardOptions []CardOption[C] | ||||
| 	AfterOption func(p *Player[C], option CardOption[C]) error | ||||
| 	// AfterOption is given the card itself as its first argument. | ||||
| 	AfterOption func(c Card[C], p *Player[C], option CardOption[C]) error | ||||
| } | ||||
|  | ||||
| // Title implements Card. | ||||
| @@ -91,7 +93,7 @@ func (b *BasicCard[C]) Then(p *Player[C], option CardOption[C]) error { | ||||
| 	if b.AfterOption == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return b.AfterOption(p, option) | ||||
| 	return b.AfterOption(b, p, option) | ||||
| } | ||||
|  | ||||
| // Drawn implements Card. | ||||
|   | ||||
| @@ -260,18 +260,34 @@ func (p *Player[C]) StartNextTurn() error { | ||||
| 	return errs.Emit() | ||||
| } | ||||
|  | ||||
| // Draw draws a card into the hand, informing the card that it has been drawn. | ||||
| // If more than a million cards refuse to enter the hand, this crashes with | ||||
| // ErrUncooperativeCards. If the deck does not have enough cards, this | ||||
| // returns WarningTooFewCards. | ||||
| func (p *Player[C]) Draw() error { | ||||
| 	for attempts := 0; attempts < 1000000; attempts++ { | ||||
| 		if p.Deck.Len() == 0 { | ||||
| 			return WarningTooFewCards | ||||
| 		} | ||||
| 		c := p.Deck.Draw() | ||||
| 		if c.Drawn(p) { | ||||
| 			p.Hand = append(p.Hand, c) | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 	return ErrUncooperativeCards | ||||
| } | ||||
|  | ||||
| // FillHand draws up to the hand limit, informing cards that they have been | ||||
| // drawn. If more than a million cards refuse to enter the hand, this crashes | ||||
| // with ErrUncooperativeCards. If the deck does not have enough cards, this | ||||
| // returns WarningTooFewCards. | ||||
| func (p *Player[C]) FillHand() error { | ||||
| 	failureLimit := 1000000 | ||||
| 	for failureLimit > 0 && p.Deck.Len() > 0 && len(p.Hand) < p.HandLimit { | ||||
| 		c := p.Deck.Draw() | ||||
| 		if c.Drawn(p) { | ||||
| 			p.Hand = append(p.Hand, c) | ||||
| 		} else { | ||||
| 			failureLimit-- | ||||
| 	var lastErr error | ||||
| 	for p.Deck.Len() > 0 && len(p.Hand) < p.HandLimit { | ||||
| 		lastErr = p.Draw() | ||||
| 		if IsSeriousError(lastErr) { | ||||
| 			return lastErr | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -279,10 +295,6 @@ func (p *Player[C]) FillHand() error { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if failureLimit <= 0 { | ||||
| 		return ErrUncooperativeCards | ||||
| 	} | ||||
|  | ||||
| 	return WarningTooFewCards | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user