-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame.go
114 lines (102 loc) · 3.06 KB
/
game.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
package main
import (
"log"
"os"
"time"
"math/rand"
"github.com/mechmind/ttti-server/message"
"github.com/mechmind/ttti-server/game"
)
type Gamer struct {
game *game.Game
glyph game.Glyph
}
func runGame(c *Client) error {
// init rand
rand.Seed(time.Now().UnixNano())
c.Start()
gamer := &Gamer{nil, game.Glyph(c.glyph[0])}
for msg := range c.connection.Read {
log.Println("game: recieved message: ", msg)
if msg.GetType() == "ping" {
pong := message.MsgPong{"pong"}
c.connection.Write <- pong
} else if msg.GetType() == "pong" {
} else {
err := handleMessage(c, gamer, msg)
if err != nil {
log.Println("error handling message: ", err)
}
}
}
return nil
}
func handleMessage(client *Client, gamer *Gamer, msg message.Message) error {
var err error
switch msg.GetType() {
case "game-state":
// load state
state := msg.(*message.MsgGameState)
field := state.Field
turn := game.Glyph(state.Turn[0])
gamer.game, err = game.LoadGame(turn, state.TurnSquare, field)
if err != nil {
return err
}
//debug
gamer.game.DumpTo(os.Stdout)
// if our turn, make it
if turn == gamer.glyph {
makeTurn(client, gamer)
}
case "turn":
// someone made turn
turn := msg.(*message.MsgTurn)
_, _, _, err := gamer.game.MakeTurn(game.Glyph(turn.Glyph[0]), turn.Coord)
if err != nil {
log.Fatal("turn: server sent invalid turn: ", err, turn)
}
gamer.game.DumpTo(os.Stdout)
// if our turn, make it
if game.Glyph(turn.NextGlyph[0]) == gamer.glyph {
makeTurn(client, gamer)
}
case "game-over":
// game is over
won := msg.(*message.MsgGameOver)
gamer.game.DumpTo(os.Stdout)
if game.Glyph(won.Winner[0]) == gamer.glyph {
log.Fatalf("game is over! I WON!!!")
} else {
log.Fatalf("game is over! I loose...")
}
case "error":
// got error
log.Fatal("got error from server: ", msg)
default:
log.Println("Unknown message: ", msg.GetType(), msg)
}
return nil
}
func makeTurn(client *Client, gamer *Gamer) {
// take random free cell from given square
sq := gamer.game.GetSquare(gamer.game.GetTurnId())
free := make([]int, game.BLOCK_SIZE)
var nextIdx int
for idx, cell := range sq {
if cell == game.EMPTY_GLYPH {
free[nextIdx] = idx
nextIdx++
}
}
free = free[:nextIdx]
if len(free) == 0 {
log.Fatalln("makeTurn: WTF? No free cells")
}
idx := free[rand.Intn(len(free))]
coord := gamer.game.GetTurnId() * game.BLOCK_SIZE + idx
msg := &message.MsgMakeTurn{"make-turn", coord, string(byte(gamer.glyph))}
log.Printf("Making turn: %c at %d [%d,%d]", byte(gamer.glyph), coord, gamer.game.GetTurnId(),
idx)
client.connection.Write <- msg
}