forked from ricktimmis/gobandit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tiles.go
146 lines (131 loc) · 3.57 KB
/
tiles.go
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"github.com/spf13/viper"
"io/ioutil"
"math/rand"
"strconv"
"strings"
)
//Tile provides a data structure to hold image sets and values, and meets the requirements
//for the tileset interface. Tile loads a data model meta information from the configuration, and expects
//image assets to be provided as png files.
type Tile struct {
imgpath string //path to png image assets
face map[int]string // png image files
value map[int]int // value of each face
currface int
lastface int
nextface int
settotal int
index map[int]int // map pointer to keep faces and values in sync
}
/*
Tileset
A Tileset provides the faces and values that will be displayed in the rows and columns of a Board.
This abstraction enables tilesets to be created as pluggable components to the GoBandit game. Thus
a Fruit machine game might hold a tileset of 6 fruits, or a playing card game would hold a
tileset of 52 playing cards.
*/
type TileSet interface {
//Init() bool // True for success
//Load() bool // True for success
Count() int // Number of tiles in the set
Shuffle()
Next()
GetFace() string // Returns the face name of the current tile
GetValue() int // Returns the value of the current tile
GetImage() string // Returns a filename for the tile image
GetTile() *Tile // Returns a pointer to the tile instance
}
// Constructor / Initialiser
func (t *Tile) init() {
t.imgpath = ""
t.face = make(map[int]string)
t.value = make(map[int]int)
t.currface = 1 // Keeping initial values simple
t.lastface = 0 // so we can use a simple inc to
t.nextface = 2 // to move indexes
t.settotal = 0
t.index = make(map[int]int, 10)
return
}
// Loads data into the tile struct from passed config key value map
func (t *Tile) load() error {
t.imgpath = viper.GetString("FilePath")
files, err := ioutil.ReadDir(t.imgpath)
if err != nil {
return err
}
//Load all PNG image files from the directory
count := 0
for _, f := range files {
if strings.Contains(f.Name(), ".png") {
t.face[count] = f.Name()
count++
//filenames should be name_value.png
s := strings.Split(f.Name(), "_")
v := strings.Split(s[1], ".")
t.value[count], err = strconv.Atoi(v[0])
if err != nil {
return err
}
}
}
t.settotal = count
return nil
}
// Returns a count of tiles in the set
func (t *Tile) Count() int {
return t.settotal
}
// Randomly reorders the set
func (t *Tile) Shuffle() {
rand.Shuffle(len(t.face), func(i, j int) {
t.face[i], t.face[j] = t.face[j], t.face[i]
t.value[i], t.value[j] = t.value[j], t.value[i]
})
return
}
// Pop next tile from the set, e,g like dealing a card
func (t *Tile) Next() {
if t.lastface != t.settotal {
t.lastface++
} else {
t.lastface = 0
}
t.currface++
if t.nextface == 0 {
t.currface = 0
}
t.nextface++
if t.currface == t.settotal {
t.nextface = 0
}
return
}
// Returns the name of the current tile image
func (t *Tile) GetFace() string {
//filenames should be name_value.png
n := strings.Split(t.face[t.currface], "_")
return n[0]
}
// Returns the value of the current tileface
func (t *Tile) GetValue() int {
return t.value[t.currface]
}
// GetImage returns path to the image on disc
func (t *Tile) GetImage() string {
// FIXME Return pointer to the image as a []byte in memory for the current tileface
// Doing the above will remove the need for disk I/O
return t.imgpath + t.face[t.currface]
}
// GetTile Creates & Returns a pointer to a new tile instance, Factory style
func (t *Tile) GetTile() *Tile {
var i = new(Tile)
i.init()
err := i.load()
if err != nil {
panic(err)
}
return i
}