save
This commit is contained in:
parent
a5f78f4d9d
commit
95e6383f94
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"git.tuxpa.in/a/card_id/common/game"
|
||||
"git.tuxpa.in/a/card_id/common/game/card"
|
||||
"git.tuxpa.in/a/card_id/common/game/score"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -16,15 +17,27 @@ func main() {
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
g := game.Game{Dealer: deal, Lives: 3}
|
||||
|
||||
trial := g.CreateTrial(3, 1)
|
||||
g.CurrentTrial = 1
|
||||
fmt.Println("type c[n] to select a card, e.g. c1")
|
||||
fmt.Println("exit to exit")
|
||||
for {
|
||||
if trial != nil {
|
||||
if trial.CheckSelection() {
|
||||
fmt.Print("\n match found!!!")
|
||||
sc, lives := trial.CheckSelection()
|
||||
if sc != 0 {
|
||||
fmt.Println(" match found!!!")
|
||||
g.Combo = g.Combo + 1
|
||||
g.Score = g.Score + sc*score.DefaultTable.Ratio(g.Combo)*g.CurrentTrial
|
||||
} else {
|
||||
g.Combo = 0
|
||||
}
|
||||
g.Lives = g.Lives + lives
|
||||
msg := fmt.Sprintf(`
|
||||
lives: %0.4v | score: %d | combo: %d
|
||||
`, g.Lives, g.Score, g.Combo)
|
||||
fmt.Printf(msg)
|
||||
}
|
||||
fmt.Printf("\ncardid > ")
|
||||
var args [4]string
|
||||
@ -45,20 +58,15 @@ func main() {
|
||||
case "select", "sel", "c":
|
||||
if alen > 1 {
|
||||
num, _ := strconv.Atoi(args[1])
|
||||
cd, err := trial.SelectCard(num)
|
||||
_, err := trial.SelectCard(num)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if cd.Id > 0 {
|
||||
msg := fmt.Sprintf(`
|
||||
card %d was %s | lives: %d
|
||||
current hand:
|
||||
%s`, num, cd.Name, trial.Lives, trial.ShowString())
|
||||
fmt.Printf(msg)
|
||||
}
|
||||
|
||||
} else {
|
||||
trial.SelectCard(0)
|
||||
}
|
||||
fmt.Printf("hand: %s\n", trial.ShowString())
|
||||
case "debug":
|
||||
fmt.Println(trial)
|
||||
case "exit", "quit", "q":
|
||||
|
1
common/data/combo.go
Normal file
1
common/data/combo.go
Normal file
@ -0,0 +1 @@
|
||||
package data
|
@ -1,16 +1,47 @@
|
||||
package card
|
||||
|
||||
import "git.tuxpa.in/a/card_id/common/data"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.tuxpa.in/a/card_id/common/data"
|
||||
"lukechampine.com/frand"
|
||||
)
|
||||
|
||||
type Card struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CleanName string `json:"clean_name"`
|
||||
|
||||
Rate float64 `json:"rate"`
|
||||
|
||||
BonusLife bool `json:"bonus_life"`
|
||||
}
|
||||
|
||||
func (c *Card) FromResult(d data.Result) Card {
|
||||
c.Id = d.Id
|
||||
c.Name = d.Name
|
||||
c.Rate = d.Rate
|
||||
c.CleanName = strings.ReplaceAll(strings.TrimSpace(stripNum(c.Name)), " ", " ")
|
||||
return *c
|
||||
}
|
||||
|
||||
func (c *Card) CopyWithBonus(chance float64) Card {
|
||||
return Card{
|
||||
Id: c.Id,
|
||||
Rate: c.Rate,
|
||||
Name: c.Name,
|
||||
CleanName: c.CleanName,
|
||||
BonusLife: (frand.Float64() <= chance),
|
||||
}
|
||||
}
|
||||
|
||||
func stripNum(s string) string {
|
||||
var result strings.Builder
|
||||
for i := 0; i < len(s); i++ {
|
||||
b := s[i]
|
||||
if !('0' <= b && b <= '9') {
|
||||
result.WriteByte(b)
|
||||
}
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
@ -21,6 +21,25 @@ func NewDealer() *Dealer {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Dealer) CardNames() []string {
|
||||
out := map[string]struct{}{}
|
||||
for _, br := range g.Brands {
|
||||
for _, c := range br.RewardDeck.Cards {
|
||||
out[c.CleanName] = struct{}{}
|
||||
}
|
||||
if br.SpecialDeck != nil {
|
||||
for _, c := range br.SpecialDeck.Cards {
|
||||
out[c.CleanName] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
keys := make([]string, 0, len(out))
|
||||
for k := range out {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (g *Dealer) ReadFromRoot(datadir string) (*Dealer, error) {
|
||||
if datadir == "" {
|
||||
datadir = "./data"
|
||||
|
@ -13,10 +13,13 @@ type Deck struct {
|
||||
Cards []Card
|
||||
|
||||
TotalProbability float64
|
||||
|
||||
BonusLifeProbability float64
|
||||
}
|
||||
|
||||
func NewDeck(r data.Results) *Deck {
|
||||
out := &Deck{}
|
||||
out.BonusLifeProbability = 0.005
|
||||
out.Cards = make([]Card, 0, len(r))
|
||||
for _, v := range r {
|
||||
out.Cards = append(out.Cards, new(Card).FromResult(v))
|
||||
@ -31,7 +34,7 @@ func (t *Deck) Draw() Card {
|
||||
for _, v := range t.Cards {
|
||||
sofar = sofar + v.Rate
|
||||
if sofar >= selector-0.000000001 {
|
||||
return v
|
||||
return v.CopyWithBonus(t.BonusLifeProbability)
|
||||
}
|
||||
}
|
||||
return Card{
|
||||
|
@ -6,8 +6,31 @@ import (
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
Lives int
|
||||
Dealer *card.Dealer
|
||||
Lives float64
|
||||
Score int
|
||||
|
||||
Combo int
|
||||
BestCombo int
|
||||
CurrentTrial int
|
||||
|
||||
Trial *Trial
|
||||
Trials []Trial
|
||||
|
||||
Player string
|
||||
PlayerId string
|
||||
|
||||
Dealer *card.Dealer `json:"-"`
|
||||
}
|
||||
|
||||
func (g *Game) New(user string, dealer *card.Dealer) *Game {
|
||||
return &Game{
|
||||
Dealer: dealer,
|
||||
Player: user,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) Resolve(action string, args []string) {
|
||||
|
||||
}
|
||||
|
||||
func (g *Game) CreateTrial(pairs int, extra int) *Trial {
|
||||
@ -37,7 +60,7 @@ func (g *Game) CreateTrial(pairs int, extra int) *Trial {
|
||||
}
|
||||
|
||||
frand.Shuffle(len(cards), func(i, j int) { cards[i], cards[j] = cards[j], cards[i] })
|
||||
trial := NewTrial(g.Lives)
|
||||
trial := NewTrial()
|
||||
for k, v := range cards {
|
||||
trial.Cards[k+1] = v
|
||||
}
|
||||
|
71
common/game/score/score.go
Normal file
71
common/game/score/score.go
Normal file
@ -0,0 +1,71 @@
|
||||
package score
|
||||
|
||||
type ComboTable interface {
|
||||
Ratio(int) int
|
||||
}
|
||||
|
||||
type MapTable struct {
|
||||
m map[int]int
|
||||
}
|
||||
|
||||
func (t *MapTable) Ratio(i int) int {
|
||||
if v, ok := t.m[i]; ok {
|
||||
return v
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
var DefaultTable ComboTable = &MapTable{
|
||||
m: map[int]int{
|
||||
0: 1,
|
||||
1: 2,
|
||||
2: 4,
|
||||
3: 7,
|
||||
4: 12,
|
||||
5: 19,
|
||||
6: 28,
|
||||
7: 39,
|
||||
8: 52,
|
||||
9: 67,
|
||||
10: 84,
|
||||
11: 103,
|
||||
12: 124,
|
||||
13: 147,
|
||||
14: 172,
|
||||
15: 199,
|
||||
16: 228,
|
||||
17: 259,
|
||||
18: 292,
|
||||
19: 327,
|
||||
20: 364,
|
||||
21: 364,
|
||||
22: 364,
|
||||
23: 364,
|
||||
24: 364,
|
||||
25: 364,
|
||||
26: 364,
|
||||
27: 364,
|
||||
28: 364,
|
||||
29: 364,
|
||||
30: 364,
|
||||
31: 364,
|
||||
32: 364,
|
||||
33: 364,
|
||||
34: 364,
|
||||
35: 364,
|
||||
36: 364,
|
||||
37: 364,
|
||||
38: 364,
|
||||
39: 364,
|
||||
40: 364,
|
||||
41: 364,
|
||||
42: 364,
|
||||
43: 364,
|
||||
44: 364,
|
||||
45: 364,
|
||||
46: 364,
|
||||
47: 364,
|
||||
48: 364,
|
||||
49: 364,
|
||||
50: 364,
|
||||
}}
|
@ -12,7 +12,6 @@ import (
|
||||
|
||||
type Trial struct {
|
||||
Cards map[int]card.Card
|
||||
Lives int
|
||||
|
||||
SelectionState int
|
||||
PendingSelection [2]int
|
||||
@ -21,9 +20,8 @@ type Trial struct {
|
||||
History [][2]int
|
||||
}
|
||||
|
||||
func NewTrial(lives int) *Trial {
|
||||
func NewTrial() *Trial {
|
||||
return &Trial{
|
||||
Lives: lives,
|
||||
Cards: make(map[int]card.Card, 7),
|
||||
Shown: make(map[int]card.Card, 7),
|
||||
PendingSelection: [2]int{-1, -1},
|
||||
@ -34,9 +32,6 @@ func (t *Trial) SelectCard(id int) (card.Card, error) {
|
||||
if id > len(t.Cards) {
|
||||
return card.Card{}, errs.Invalid("index out of bounds")
|
||||
}
|
||||
if t.Lives == 0 {
|
||||
return card.Card{}, errs.Logic("game over")
|
||||
}
|
||||
switch t.SelectionState {
|
||||
case 0: // start selection
|
||||
t.SelectionState = 1
|
||||
@ -51,36 +46,37 @@ func (t *Trial) SelectCard(id int) (card.Card, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Trial) CheckSelection() bool {
|
||||
func (t *Trial) CheckSelection() (points int, lifechange float64) {
|
||||
switch t.SelectionState {
|
||||
case 0, 1:
|
||||
return false
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
defer func() {
|
||||
t.SelectionState = 0
|
||||
}()
|
||||
|
||||
lifechange = -1
|
||||
c1, ok := t.Cards[t.PendingSelection[0]]
|
||||
if !ok {
|
||||
return false
|
||||
return
|
||||
}
|
||||
c2, ok := t.Cards[t.PendingSelection[1]]
|
||||
if !ok {
|
||||
return false
|
||||
return
|
||||
}
|
||||
if c1.Id == c2.Id {
|
||||
if c1.Name == c2.Name {
|
||||
t.Shown[t.PendingSelection[0]] = c1
|
||||
t.Shown[t.PendingSelection[1]] = c2
|
||||
return true
|
||||
if c1.BonusLife || c2.BonusLife {
|
||||
return 10, 1
|
||||
}
|
||||
return 10, 0.35
|
||||
}
|
||||
}
|
||||
t.History = append(t.History, t.PendingSelection)
|
||||
t.PendingSelection = [2]int{-1, -1}
|
||||
t.Lives = t.Lives - 1
|
||||
return false
|
||||
return 0, -1
|
||||
}
|
||||
|
||||
func (t *Trial) Show() map[int]card.Card {
|
||||
@ -102,8 +98,8 @@ func (t *Trial) ShowString() string {
|
||||
}
|
||||
|
||||
outs := ""
|
||||
for _, k := range t.CardKeys() {
|
||||
piece := "[???]"
|
||||
for n, k := range t.CardKeys() {
|
||||
piece := fmt.Sprintf("[??%d??]", n+1)
|
||||
if v, ok := out[k]; ok {
|
||||
piece = fmt.Sprintf("[%s]", v.Name)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user