forked from geetarista/vindinium-starter-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.go
140 lines (117 loc) · 2.68 KB
/
client.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
package vindinium
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"time"
)
const (
MoveTimeout = 15
StartTimeout = 10 * 60
)
type Client struct {
Server string
Key string
Mode string
BotName string
Turns string
RandomMap bool
Debug bool
Bot Bot
State *State
Url string
}
func NewClient(server, key, mode, botName, turns string, randomMap bool, debug bool) (client *Client) {
client = &Client{
Server: server,
Key: key,
Mode: mode,
BotName: botName,
Turns: turns,
RandomMap: randomMap,
Debug: debug,
}
client.Setup()
return
}
func (c *Client) Setup() {
c.Url = c.Server + "/api/" + c.Mode
switch c.BotName {
case "fighter":
c.Bot = &FighterBot{}
default:
c.Bot = &RandomBot{}
}
}
func (c *Client) finished() bool {
return c.State.Game.Finished
}
func (c *Client) move(dir Direction) error {
values := make(url.Values)
values.Set("dir", string(dir))
return c.post(c.State.PlayUrl, values, MoveTimeout)
}
func (c *Client) post(uri string, values url.Values, seconds int) error {
if c.Debug {
fmt.Printf("Making request to to: %s\n", uri)
}
timeout := time.Duration(seconds) * time.Second
dial := func(network, addr string) (net.Conn, error) {
return net.DialTimeout(network, addr, timeout)
}
transport := http.Transport{Dial: dial}
client := http.Client{Transport: &transport}
response, err := client.PostForm(uri, values)
if err != nil {
return err
}
defer response.Body.Close()
data, _ := ioutil.ReadAll(response.Body)
if response.StatusCode >= 500 {
return errors.New(fmt.Sprintf("Server responded with %s", response.Status))
} else if response.StatusCode >= 400 {
return errors.New(fmt.Sprintf("Request error: %s", string(data[:])))
}
if err := json.Unmarshal(data, &c.State); err != nil {
return err
}
if c.Debug {
fmt.Printf("Setting data to:\n%s\n", string(data))
}
return nil
}
func (c *Client) Start() error {
values := make(url.Values)
values.Set("key", c.Key)
if c.Mode == "training" {
values.Set("turns", c.Turns)
if !c.RandomMap {
values.Set("map", "m1")
}
}
fmt.Println("Connecting and waiting for other players to join...")
return c.post(c.Url, values, StartTimeout)
}
func (c *Client) Play() error {
fmt.Printf("Playing at: %s\n", c.State.ViewUrl)
move := 1
for c.State.Game.Finished == false {
fmt.Printf("\rMaking move: %d", move)
if c.Debug {
fmt.Printf("\nclient: %+v\n", c)
fmt.Printf("bot: %+v\n", c.Bot)
fmt.Printf("state: %+v\n", c.State)
}
dir := c.Bot.Move(c.State)
if err := c.move(dir); err != nil {
return err
}
move++
}
fmt.Println("\nFinished game.")
return nil
}