Feature: RoomController.go
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
package main
|
||||
|
||||
import "github.com/c-my/MahjongServer/rule"
|
||||
|
||||
type Hall struct {
|
||||
rooms map[int]*Room
|
||||
players map[int]int
|
||||
|
||||
maxRoomSize int
|
||||
}
|
||||
|
||||
var hall *Hall = nil
|
||||
|
||||
func GetHall() *Hall {
|
||||
if hall != nil {
|
||||
return hall
|
||||
} else {
|
||||
hall = NewHall(100)
|
||||
return hall
|
||||
}
|
||||
}
|
||||
|
||||
func NewHall(maxRoomSize int) *Hall {
|
||||
return &Hall{maxRoomSize: maxRoomSize}
|
||||
}
|
||||
|
||||
func (h *Hall) CreateRoom(userID int, roomName string, passwd string) int {
|
||||
for i := 0; i < h.maxRoomSize; i++ {
|
||||
if !h.hasRoom(i) {
|
||||
h.rooms[i] = NewRoom(rule.NewJinzhouRule())
|
||||
h.players[userID] = i
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (h *Hall) hasRoom(roomID int) bool {
|
||||
_, ok := h.rooms[roomID]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (h *Hall) destroyRoom(roomID int) {
|
||||
delete(h.rooms, roomID)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package container
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -0,0 +1,71 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"github.com/c-my/MahjongServer/rule"
|
||||
)
|
||||
|
||||
type Hall struct {
|
||||
rooms map[int]*Room
|
||||
players map[int]int
|
||||
|
||||
maxRoomSize int
|
||||
}
|
||||
|
||||
var hall *Hall = nil
|
||||
|
||||
func GetHall() *Hall {
|
||||
if hall != nil {
|
||||
return hall
|
||||
} else {
|
||||
hall = NewHall(100)
|
||||
return hall
|
||||
}
|
||||
}
|
||||
|
||||
func NewHall(maxRoomSize int) *Hall {
|
||||
return &Hall{maxRoomSize: maxRoomSize, rooms: map[int]*Room{}, players: map[int]int{}}
|
||||
}
|
||||
|
||||
func (h *Hall) CreateRoom(userID int, roomName string, passwd string) int {
|
||||
for i := 0; i < h.maxRoomSize; i++ {
|
||||
if !h.hasRoom(i) {
|
||||
room := NewRoom(rule.NewJinzhouRule())
|
||||
room.playerCount = 1
|
||||
h.rooms[i] = room
|
||||
h.players[userID] = i
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (h *Hall) JoinRoom(userID int, roomID int) bool {
|
||||
if !h.hasRoom(roomID) {
|
||||
return false
|
||||
}
|
||||
room := h.rooms[roomID]
|
||||
if room.playerCount >= 4 {
|
||||
return false
|
||||
}
|
||||
h.players[userID] = roomID
|
||||
room.playerCount = room.playerCount + 1
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *Hall) GetRoomID(userID int) int {
|
||||
roomID, ok := h.players[userID]
|
||||
if !ok {
|
||||
return -1
|
||||
} else {
|
||||
return roomID
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hall) hasRoom(roomID int) bool {
|
||||
_, ok := h.rooms[roomID]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (h *Hall) destroyRoom(roomID int) {
|
||||
delete(h.rooms, roomID)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package container
|
||||
|
||||
import (
|
||||
"github.com/c-my/MahjongServer/game"
|
||||
@@ -13,6 +13,9 @@ type Room struct {
|
||||
|
||||
gameRecvCh chan message.GameMsgRecv
|
||||
gameSendCh chan message.GameMsgSend
|
||||
|
||||
password string
|
||||
playerCount int
|
||||
}
|
||||
|
||||
func NewRoom(rule rule.MahjongRule) *Room {
|
||||
@@ -1,17 +1,75 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/c-my/MahjongServer/container"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func RoomPostHandler(writer http.ResponseWriter, request *http.Request) {
|
||||
err := request.ParseForm()
|
||||
type createRoomMsg struct {
|
||||
UserID int `json:"user_id"`
|
||||
RoomName string `json:"room_name"`
|
||||
Passwd string `json:"passwd"`
|
||||
}
|
||||
|
||||
type joinRoomMsg struct {
|
||||
UserID int `json:"user_id"`
|
||||
RoomID int `json:"room_id"`
|
||||
}
|
||||
|
||||
type result struct {
|
||||
Success bool `json:"Success"`
|
||||
RoomID int `json:"room_id"`
|
||||
}
|
||||
|
||||
func RoomCreateHandler(writer http.ResponseWriter, request *http.Request) {
|
||||
var msg createRoomMsg
|
||||
err := json.NewDecoder(request.Body).Decode(&msg)
|
||||
if err != nil {
|
||||
return
|
||||
j, _ := json.Marshal(failMsg())
|
||||
log.Print("failed to create room: unknown request")
|
||||
writer.Write(j)
|
||||
}
|
||||
form := request.Form
|
||||
userID:=form["UserID"]
|
||||
roomName :=form["RoomName"]
|
||||
PassWord := form["Password"]
|
||||
GetHall().CreateRoom(userID, roomName, PassWord)
|
||||
userID := msg.UserID
|
||||
roomName := msg.RoomName
|
||||
PassWord := msg.RoomName
|
||||
roomID := container.GetHall().CreateRoom(userID, roomName, PassWord)
|
||||
if roomID == -1 {
|
||||
log.Print("failed to create room: max room size reached")
|
||||
j, _ := json.Marshal(failMsg())
|
||||
writer.Write(j)
|
||||
}
|
||||
log.Print("created room:", roomID)
|
||||
j, _ := json.Marshal(successMsg(roomID))
|
||||
writer.Write(j)
|
||||
}
|
||||
|
||||
func RoomJoinHandler(writer http.ResponseWriter, request *http.Request) {
|
||||
var msg joinRoomMsg
|
||||
err := json.NewDecoder(request.Body).Decode(&msg)
|
||||
if err != nil {
|
||||
j, _ := json.Marshal(failMsg())
|
||||
log.Print("failed to join room: unknown request")
|
||||
writer.Write(j)
|
||||
}
|
||||
userID := msg.UserID
|
||||
roomID := msg.RoomID
|
||||
|
||||
success := container.GetHall().JoinRoom(userID, roomID)
|
||||
if !success {
|
||||
j, _ := json.Marshal(failMsg())
|
||||
writer.Write(j)
|
||||
} else {
|
||||
j, _ := json.Marshal(successMsg(roomID))
|
||||
writer.Write(j)
|
||||
}
|
||||
}
|
||||
|
||||
func successMsg(roomID int) result {
|
||||
return result{Success: true, RoomID: roomID}
|
||||
}
|
||||
|
||||
func failMsg() result {
|
||||
return result{Success: false}
|
||||
}
|
||||
|
||||
+27
-5
@@ -75,8 +75,8 @@ func (m *MahjongManager) gameLoop(gameRecvCh chan message.GameMsgRecv, gameSendC
|
||||
}
|
||||
|
||||
func (m *MahjongManager) handleStart(msg message.GameMsgRecv) {
|
||||
//m.dealTile()
|
||||
m.dealTileTest()
|
||||
m.dealTile()
|
||||
//m.dealTileTest()
|
||||
newTile := m.wall.FrontDraw()
|
||||
//TODO:判断第一张牌能否碰、杠、胡
|
||||
availableActions := m.getAvailableActions(m.playerTile[msg.TableOrder].HandTiles, m.playerTile[msg.TableOrder].ShownTiles, newTile)
|
||||
@@ -134,14 +134,25 @@ func (m *MahjongManager) handleDiscard(msg message.GameMsgRecv) {
|
||||
for i := 1; i <= 3; i++ {
|
||||
hand := m.playerTile[(currentOrder+i)%4].HandTiles
|
||||
if m.rules.CanExposedKong(hand, msg.Tile) {
|
||||
availableAction := make([]int, 0)
|
||||
chowTypes := make([]int, 0)
|
||||
availableAction = append(availableAction, config.Pong, config.ExposedKong)
|
||||
if i == 1 {
|
||||
canChow, types := m.rules.CanChow(hand, msg.Tile)
|
||||
if canChow {
|
||||
availableAction = append(availableAction, config.Chow)
|
||||
chowTypes = types
|
||||
}
|
||||
}
|
||||
msgSend := message.GameMsgSend{
|
||||
MsgType: config.GameMsgType,
|
||||
TableOrder: -1,
|
||||
CurrentTurn: (currentOrder + i) % 4,
|
||||
CurrentTile: msg.Tile,
|
||||
AvailableActions: []int{config.Pong, config.ExposedKong},
|
||||
AvailableActions: availableAction,
|
||||
LastTurn: msg.TableOrder,
|
||||
LastAction: config.Discard,
|
||||
ChowTypes: chowTypes,
|
||||
PlayerTile: m.playerTile,
|
||||
WallCount: m.wall.Length(),
|
||||
}
|
||||
@@ -149,14 +160,25 @@ func (m *MahjongManager) handleDiscard(msg message.GameMsgRecv) {
|
||||
return
|
||||
}
|
||||
if m.rules.CanPong(hand, msg.Tile) {
|
||||
availableAction := make([]int, 0)
|
||||
chowTypes := make([]int, 0)
|
||||
availableAction = append(availableAction, config.Pong)
|
||||
if i == 1 {
|
||||
canChow, types := m.rules.CanChow(hand, msg.Tile)
|
||||
if canChow {
|
||||
availableAction = append(availableAction, config.Chow)
|
||||
chowTypes = types
|
||||
}
|
||||
}
|
||||
msgSend := message.GameMsgSend{
|
||||
MsgType: config.GameMsgType,
|
||||
TableOrder: -1,
|
||||
CurrentTurn: (currentOrder + i) % 4,
|
||||
CurrentTile: msg.Tile,
|
||||
AvailableActions: []int{config.Pong},
|
||||
AvailableActions: availableAction,
|
||||
LastTurn: msg.TableOrder,
|
||||
LastAction: config.Discard,
|
||||
ChowTypes: chowTypes,
|
||||
PlayerTile: m.playerTile,
|
||||
WallCount: m.wall.Length(),
|
||||
}
|
||||
@@ -358,7 +380,7 @@ func (m *MahjongManager) handleAddedKong(msg message.GameMsgRecv) {
|
||||
shown := m.playerTile[msg.TableOrder].ShownTiles
|
||||
|
||||
m.playerTile[msg.TableOrder].HandTiles = model.RemoveTile(hand, msg.Tile, 1)
|
||||
pos:=0
|
||||
pos := 0
|
||||
for i, v := range shown {
|
||||
if v.ShownType == config.Pong && v.Tiles[0].Equals(msg.Tile) {
|
||||
pos = i
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/c-my/MahjongServer/container"
|
||||
"github.com/c-my/MahjongServer/controller"
|
||||
"github.com/c-my/MahjongServer/rule"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -15,7 +18,7 @@ var upgrader = websocket.Upgrader{
|
||||
},
|
||||
}
|
||||
|
||||
var room *Room
|
||||
var room *container.Room
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("connection received")
|
||||
@@ -24,9 +27,11 @@ func handler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
room = NewRoom(rule.NewJinzhouRule())
|
||||
room = container.NewRoom(rule.NewJinzhouRule())
|
||||
room.Start()
|
||||
|
||||
http.HandleFunc("/", handler)
|
||||
http.ListenAndServe("127.0.0.1:1114", nil)
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/room/", controller.RoomCreateHandler).Methods("POST")
|
||||
router.HandleFunc("/room/", controller.RoomJoinHandler).Methods("PUT")
|
||||
router.HandleFunc("/", handler)
|
||||
http.ListenAndServe("127.0.0.1:1114", router)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package message
|
||||
|
||||
|
||||
|
||||
type CommonMsg struct {
|
||||
MsgType int `json:"msg_type"`
|
||||
Content interface{}
|
||||
|
||||
@@ -6,8 +6,6 @@ import "github.com/c-my/MahjongServer/model"
|
||||
// Action string `json:"action"`
|
||||
//}
|
||||
|
||||
|
||||
|
||||
type GameMsgRecv struct {
|
||||
MsgType int `json:"msg_type"`
|
||||
|
||||
|
||||
+3
-3
@@ -32,15 +32,15 @@ func (r *JinzhouRule) CanChow(tiles []model.Tile, newTile model.Tile) (bool, []i
|
||||
if !newTile.IsSuit() {
|
||||
return false, append(chowTypes, config.NAC)
|
||||
}
|
||||
if r.canLeftChow(tiles, newTile){
|
||||
if r.canLeftChow(tiles, newTile) {
|
||||
canChow = true
|
||||
chowTypes = append(chowTypes, config.LeftChow)
|
||||
}
|
||||
if r.canMidChow(tiles, newTile){
|
||||
if r.canMidChow(tiles, newTile) {
|
||||
canChow = true
|
||||
chowTypes = append(chowTypes, config.MidChow)
|
||||
}
|
||||
if(r.canRightChow(tiles, newTile)){
|
||||
if r.canRightChow(tiles, newTile) {
|
||||
canChow = true
|
||||
chowTypes = append(chowTypes, config.RightChow)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"github.com/c-my/MahjongServer/config"
|
||||
"github.com/c-my/MahjongServer/model"
|
||||
"testing"
|
||||
)
|
||||
@@ -20,7 +21,8 @@ func TestJinzhouRule_CanChow(t *testing.T) {
|
||||
{[]model.Tile{{1, 7}, {1, 8}, {2, 4}}, model.Tile{4, 1}, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if j.CanChow(test.hand, test.newTile) != test.want {
|
||||
canChow, _ := j.CanChow(test.hand, test.newTile)
|
||||
if canChow != test.want {
|
||||
t.Errorf("wrong chow")
|
||||
}
|
||||
}
|
||||
@@ -74,7 +76,7 @@ func TestJinzhouRule_CanWin(t *testing.T) {
|
||||
}{
|
||||
{[]model.Tile{{0, 7}, {0, 8}, {0, 9},
|
||||
{2, 1}, {2, 2}, {2, 3}, {2, 7}, {2, 8}, {2, 9}, {2, 9}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
model.Tile{2, 6},
|
||||
true},
|
||||
{[]model.Tile{{0, 7}, {0, 7}, {0, 9}, {0, 9},
|
||||
@@ -85,12 +87,12 @@ func TestJinzhouRule_CanWin(t *testing.T) {
|
||||
true}, //7对
|
||||
{[]model.Tile{{0, 2}, {0, 3}, {0, 4}, {0, 6}, {0, 7}, {0, 8},
|
||||
{2, 5}, {2, 7}, {2, 8}, {2, 8}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
model.Tile{2, 6},
|
||||
false}, //缺幺九
|
||||
{[]model.Tile{{0, 2}, {0, 3}, {0, 4}, {0, 6}, {0, 7}, {0, 8},
|
||||
{2, 5}, {2, 7}, {2, 8}, {2, 8}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{1, 9}, {1, 9}, {1, 9}, {1, 9}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{1, 9}, {1, 9}, {1, 9}, {1, 9}}}},
|
||||
model.Tile{2, 6},
|
||||
true},
|
||||
{[]model.Tile{{0, 7}, {0, 8}, {0, 9},
|
||||
@@ -101,12 +103,12 @@ func TestJinzhouRule_CanWin(t *testing.T) {
|
||||
false},
|
||||
{[]model.Tile{{0, 9}, {0, 9}, {0, 9},
|
||||
{2, 1}, {2, 2}, {2, 3}, {2, 7}, {2, 8}, {2, 9}, {2, 9}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
model.Tile{2, 6},
|
||||
true},
|
||||
{[]model.Tile{{0, 7}, {0, 8}, {0, 9},
|
||||
{2, 1}, {2, 2}, {2, 3}, {2, 7}, {2, 8}, {2, 9}, {2, 9}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{0, 3}, {0, 3}, {0, 3}, {0, 3}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{0, 3}, {0, 3}, {0, 3}, {0, 3}}}},
|
||||
model.Tile{2, 6},
|
||||
false}, //缺门
|
||||
}
|
||||
@@ -126,7 +128,7 @@ func BenchmarkJinzhouRule_CanWin_Normal(b *testing.B) {
|
||||
want bool
|
||||
}{[]model.Tile{{0, 7}, {0, 8}, {0, 9},
|
||||
{2, 1}, {2, 2}, {2, 3}, {2, 7}, {2, 8}, {2, 9}, {2, 9}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{1, 3}, {1, 3}, {1, 3}, {1, 3}}}},
|
||||
model.Tile{2, 6}, true}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
@@ -162,7 +164,7 @@ func BenchmarkJinzhouRule_CanWin_LackDoor(b *testing.B) {
|
||||
want bool
|
||||
}{[]model.Tile{{0, 7}, {0, 8}, {0, 9},
|
||||
{2, 1}, {2, 2}, {2, 3}, {2, 7}, {2, 8}, {2, 9}, {2, 9}},
|
||||
[]model.ShownTile{{model.ConcealedKong, []model.Tile{{0, 3}, {0, 3}, {0, 3}, {0, 3}}}},
|
||||
[]model.ShownTile{{config.ConcealedKong, []model.Tile{{0, 3}, {0, 3}, {0, 3}, {0, 3}}}},
|
||||
model.Tile{2, 6},
|
||||
false} //缺门
|
||||
b.ResetTimer()
|
||||
|
||||
Reference in New Issue
Block a user