Feature: RoomController.go

This commit is contained in:
2020-03-27 12:46:19 +08:00
parent 3ffb7bc64b
commit c6258df867
11 changed files with 192 additions and 80 deletions
-45
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
package main
package container
import (
"encoding/json"
+71
View File
@@ -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)
}
+4 -1
View File
@@ -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 {
+66 -8
View File
@@ -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
View File
@@ -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
+10 -5
View File
@@ -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)
}
-2
View File
@@ -1,7 +1,5 @@
package message
type CommonMsg struct {
MsgType int `json:"msg_type"`
Content interface{}
-2
View File
@@ -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
View File
@@ -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)
}
+10 -8
View File
@@ -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()