完善小游戏逻辑
This commit is contained in:
+2
-4
@@ -3,11 +3,9 @@ package global
|
|||||||
import "work_cation/models"
|
import "work_cation/models"
|
||||||
|
|
||||||
type SendGlobal struct {
|
type SendGlobal struct {
|
||||||
SendChan chan *models.Message
|
SendChan chan *models.Message
|
||||||
Game1Chan chan *models.GameMessage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Send = &SendGlobal{
|
var Send = &SendGlobal{
|
||||||
SendChan: make(chan *models.Message, 1000),
|
SendChan: make(chan *models.Message, 1000),
|
||||||
Game1Chan: make(chan *models.GameMessage, 1000),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ func main() {
|
|||||||
func mainView(w fyne.Window) fyne.CanvasObject {
|
func mainView(w fyne.Window) fyne.CanvasObject {
|
||||||
service.Zeroconf.StartFindService()
|
service.Zeroconf.StartFindService()
|
||||||
views.ListenChat()
|
views.ListenChat()
|
||||||
views.StartGameListen()
|
|
||||||
// 启动服务
|
// 启动服务
|
||||||
if err := service.Server.StartListenServer(); err != nil {
|
if err := service.Server.StartListenServer(); err != nil {
|
||||||
return widget.NewLabel(err.Error())
|
return widget.NewLabel(err.Error())
|
||||||
}
|
}
|
||||||
|
views.StartGameListen()
|
||||||
var (
|
var (
|
||||||
content = container.NewMax()
|
content = container.NewMax()
|
||||||
a = fyne.CurrentApp()
|
a = fyne.CurrentApp()
|
||||||
|
|||||||
+9
-51
@@ -16,9 +16,10 @@ import (
|
|||||||
"work_cation/repo"
|
"work_cation/repo"
|
||||||
)
|
)
|
||||||
|
|
||||||
type serverService struct {
|
type ServerService struct {
|
||||||
Status string
|
Status string
|
||||||
server *http.Server
|
server *http.Server
|
||||||
|
Router *gin.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -26,9 +27,9 @@ const (
|
|||||||
StatusOffline = "offline"
|
StatusOffline = "offline"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Server = &serverService{Status: StatusOffline}
|
var Server = &ServerService{Status: StatusOffline}
|
||||||
|
|
||||||
func (s *serverService) Online() error {
|
func (s *ServerService) Online() error {
|
||||||
if s.Status == StatusOnline {
|
if s.Status == StatusOnline {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -42,7 +43,7 @@ func (s *serverService) Online() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverService) StatusOffline() error {
|
func (s *ServerService) StatusOffline() error {
|
||||||
//if err := s.server.Close(); err != nil {
|
//if err := s.server.Close(); err != nil {
|
||||||
// return err
|
// return err
|
||||||
//}
|
//}
|
||||||
@@ -53,8 +54,9 @@ func (s *serverService) StatusOffline() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverService) StartListenServer() error {
|
func (s *ServerService) StartListenServer() error {
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
|
s.Router = router
|
||||||
router.GET("/user", func(c *gin.Context) {
|
router.GET("/user", func(c *gin.Context) {
|
||||||
user := repo.User.GetUserInfo(global.DB)
|
user := repo.User.GetUserInfo(global.DB)
|
||||||
c.JSON(200, user)
|
c.JSON(200, user)
|
||||||
@@ -82,7 +84,7 @@ func (s *serverService) StartListenServer() error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/chat", func(c *gin.Context) {
|
router.POST("/chat", func(c *gin.Context) {
|
||||||
user, msg, is := publicPostCheck(c)
|
user, msg, is := PublicPostCheck(c)
|
||||||
if !is {
|
if !is {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -98,50 +100,6 @@ func (s *serverService) StartListenServer() error {
|
|||||||
c.JSON(200, gin.H{"message": "ok"})
|
c.JSON(200, gin.H{"message": "ok"})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 开始游戏
|
|
||||||
router.POST("/start_game", func(c *gin.Context) {
|
|
||||||
user, msg, is := publicPostCheck(c)
|
|
||||||
if !is {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
message := &models.GameMessage{
|
|
||||||
Router: "/start_game",
|
|
||||||
User: &user.Users,
|
|
||||||
GameType: int(msg["type"].(float64)),
|
|
||||||
GameUuid: msg["game_uuid"].(string),
|
|
||||||
}
|
|
||||||
global.Send.Game1Chan <- message
|
|
||||||
c.JSON(200, gin.H{"message": "ok"})
|
|
||||||
})
|
|
||||||
router.POST("/play_game", func(c *gin.Context) {
|
|
||||||
user, msg, is := publicPostCheck(c)
|
|
||||||
if !is {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
message := &models.GameMessage{
|
|
||||||
Router: "/play_game",
|
|
||||||
User: &user.Users,
|
|
||||||
Pos: int(msg["pos"].(float64)),
|
|
||||||
GameUuid: msg["game_uuid"].(string),
|
|
||||||
}
|
|
||||||
global.Send.Game1Chan <- message
|
|
||||||
c.JSON(200, gin.H{"message": "ok"})
|
|
||||||
})
|
|
||||||
|
|
||||||
router.POST("/close_game", func(c *gin.Context) {
|
|
||||||
user, msg, is := publicPostCheck(c)
|
|
||||||
if !is {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
message := &models.GameMessage{
|
|
||||||
Router: "/close_game",
|
|
||||||
User: &user.Users,
|
|
||||||
GameUuid: msg["game_uuid"].(string),
|
|
||||||
}
|
|
||||||
global.Send.Game1Chan <- message
|
|
||||||
c.JSON(200, gin.H{"message": "ok"})
|
|
||||||
})
|
|
||||||
|
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: cfg.T.ServerAddr,
|
Addr: cfg.T.ServerAddr,
|
||||||
Handler: router,
|
Handler: router,
|
||||||
@@ -206,7 +164,7 @@ func zipFolder(folderPath string, zipFile io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func publicPostCheck(c *gin.Context) (*models.UserFollows, map[string]interface{}, bool) {
|
func PublicPostCheck(c *gin.Context) (*models.UserFollows, map[string]interface{}, bool) {
|
||||||
uuid := c.GetHeader("User-User")
|
uuid := c.GetHeader("User-User")
|
||||||
user := repo.UserFollow.GetUser(global.DB, uuid)
|
user := repo.UserFollow.GetUser(global.DB, uuid)
|
||||||
if user.Ip != c.ClientIP() {
|
if user.Ip != c.ClientIP() {
|
||||||
|
|||||||
+23
-9
@@ -7,10 +7,10 @@ import (
|
|||||||
"fyne.io/fyne/v2/dialog"
|
"fyne.io/fyne/v2/dialog"
|
||||||
"fyne.io/fyne/v2/theme"
|
"fyne.io/fyne/v2/theme"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"time"
|
"time"
|
||||||
"work_cation/global"
|
"work_cation/global"
|
||||||
"work_cation/models"
|
"work_cation/models"
|
||||||
"work_cation/pkg/utils"
|
|
||||||
"work_cation/repo"
|
"work_cation/repo"
|
||||||
"work_cation/service"
|
"work_cation/service"
|
||||||
)
|
)
|
||||||
@@ -95,21 +95,35 @@ func OpenChat(user models.Users) {
|
|||||||
scroll.ScrollToBottom()
|
scroll.ScrollToBottom()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port}
|
||||||
// 分享
|
// 分享
|
||||||
toolBar := widget.NewToolbar(
|
toolBar := widget.NewToolbar(
|
||||||
widget.NewToolbarAction(theme.ContentAddIcon(), func() {
|
widget.NewToolbarAction(theme.ContentAddIcon(), func() {
|
||||||
dialog.ShowInformation("未开发", "分享脚本功能 尽请期待", w)
|
dialog.ShowInformation("未开发", "分享脚本功能 尽请期待", w)
|
||||||
}),
|
}),
|
||||||
widget.NewToolbarAction(theme.CancelIcon(), func() { w.Close() }),
|
widget.NewToolbarAction(theme.CancelIcon(), func() { w.Close() }),
|
||||||
widget.NewToolbarAction(theme.MailForwardIcon(), func() {
|
widget.NewToolbarAction(theme.WarningIcon(), func() {
|
||||||
game := NewTenGame(nil)
|
var ilo *dialog.CustomDialog
|
||||||
online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port}
|
box := container.NewVBox()
|
||||||
err := game.AddNet(utils.Uuid.CreateUUID(), 0, online, &user)
|
for _, item := range GameConfigList {
|
||||||
if err != nil {
|
var itemCopy = item
|
||||||
dialog.ShowInformation("错误", err.Error(), w)
|
box.Add(widget.NewButton(itemCopy.Name, func() {
|
||||||
return
|
req := gin.H{
|
||||||
|
"name": itemCopy.Name,
|
||||||
|
"x": itemCopy.X,
|
||||||
|
"y": itemCopy.Y,
|
||||||
|
"win": itemCopy.Win}
|
||||||
|
_, err := service.PostSend("/send_game", online, req)
|
||||||
|
if err != nil {
|
||||||
|
dialog.ShowError(err, w)
|
||||||
|
}
|
||||||
|
ilo.Hide()
|
||||||
|
}))
|
||||||
|
|
||||||
}
|
}
|
||||||
game.StartShow()
|
ilo = dialog.NewCustomWithoutButtons("选择", box, w)
|
||||||
|
ilo.Show()
|
||||||
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
button := widget.NewButton("", submit)
|
button := widget.NewButton("", submit)
|
||||||
|
|||||||
+127
-58
@@ -12,66 +12,115 @@ import (
|
|||||||
"fyne.io/fyne/v2/layout"
|
"fyne.io/fyne/v2/layout"
|
||||||
"fyne.io/fyne/v2/theme"
|
"fyne.io/fyne/v2/theme"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"image/png"
|
"image/png"
|
||||||
|
"net/http"
|
||||||
"slices"
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"work_cation/global"
|
"work_cation/global"
|
||||||
"work_cation/models"
|
"work_cation/models"
|
||||||
|
"work_cation/pkg/utils"
|
||||||
"work_cation/service"
|
"work_cation/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GameConfig struct {
|
||||||
|
Name string
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
Win int
|
||||||
|
}
|
||||||
|
|
||||||
|
var GameConfigList = []GameConfig{
|
||||||
|
{"3*3 井字棋", 3, 3, 3},
|
||||||
|
{"10*10 五子棋", 10, 10, 5},
|
||||||
|
{"19*19 五子棋", 19, 19, 5},
|
||||||
|
}
|
||||||
|
|
||||||
func TenChinaGameView() {
|
func TenChinaGameView() {
|
||||||
game := NewTenGame(nil)
|
game := NewTenGame(nil)
|
||||||
//go func() {
|
game.Show()
|
||||||
// for {
|
|
||||||
// select {
|
|
||||||
// case <-game.Ctx.Done():
|
|
||||||
// return
|
|
||||||
// case msg := <-global.Send.Game1Chan:
|
|
||||||
// game.play()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}()
|
|
||||||
game.StartShow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartGameListen() {
|
func StartGameListen() {
|
||||||
go func() {
|
router := service.Server.Router
|
||||||
for {
|
|
||||||
select {
|
// 推送游戏邀请
|
||||||
case msg := <-global.Send.Game1Chan:
|
service.Server.Router.POST("/send_game", func(c *gin.Context) {
|
||||||
switch msg.Router {
|
user, msg, is := service.PublicPostCheck(c)
|
||||||
case "/play_game":
|
if !is {
|
||||||
g := global.GetGameInfo(msg.GameUuid)
|
return
|
||||||
if g != nil {
|
|
||||||
game := g.Obj.(*TenGame)
|
|
||||||
game.Play(game.userIndex, msg.Pos)
|
|
||||||
}
|
|
||||||
case "/close_game":
|
|
||||||
g := global.GetGameInfo(msg.GameUuid)
|
|
||||||
if g != nil {
|
|
||||||
dialog.NewConfirm("提示", "对方已退出", func(b bool) {
|
|
||||||
g.Obj.(*TenGame).w.Close()
|
|
||||||
}, g.Obj.(*TenGame).w).Show()
|
|
||||||
//dialog.ShowInformation("提示", "对方已退出", g.Obj.(*TenGame).w)
|
|
||||||
}
|
|
||||||
case "/start_game":
|
|
||||||
g := global.GetGameInfo(msg.GameUuid)
|
|
||||||
if g != nil {
|
|
||||||
fmt.Println("start_game")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
game := NewTenGame(nil)
|
|
||||||
online := &models.Online{ID: msg.User.ID, Ip: msg.User.Ip, Port: msg.User.Port}
|
|
||||||
game.AddNet(msg.GameUuid, 1, online, msg.User)
|
|
||||||
game.StartShow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
w := fyne.CurrentApp().NewWindow("游戏邀请")
|
||||||
|
w.SetContent(container.NewVBox(
|
||||||
|
widget.NewLabel(fmt.Sprintf("%s向你发起了 %s 游戏邀请 ", user.Name, msg["name"])),
|
||||||
|
container.NewHBox(
|
||||||
|
widget.NewButton("同意", func() {
|
||||||
|
game := NewTenGame(nil)
|
||||||
|
game.itemX = float32(msg["x"].(float64))
|
||||||
|
game.itemY = float32(msg["y"].(float64))
|
||||||
|
game.winSum = int(msg["win"].(float64))
|
||||||
|
online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port}
|
||||||
|
err := game.AddNet(utils.Uuid.CreateUUID(), 0, online, &user.Users)
|
||||||
|
if err != nil {
|
||||||
|
dialog.ShowInformation("错误", err.Error(), w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
game.Show()
|
||||||
|
w.Close()
|
||||||
|
}),
|
||||||
|
widget.NewButton("婉拒", w.Close),
|
||||||
|
)))
|
||||||
|
w.CenterOnScreen()
|
||||||
|
w.RequestFocus()
|
||||||
|
w.Show()
|
||||||
|
c.JSON(http.StatusOK, gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 开始游戏
|
||||||
|
router.POST("/start_game", func(c *gin.Context) {
|
||||||
|
user, msg, is := service.PublicPostCheck(c)
|
||||||
|
if !is {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
game := NewTenGame(nil)
|
||||||
|
game.itemX = float32(msg["x"].(float64))
|
||||||
|
game.itemY = float32(msg["y"].(float64))
|
||||||
|
game.winSum = int(msg["win"].(float64))
|
||||||
|
online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port}
|
||||||
|
game.AddNet(utils.Uuid.CreateUUID(), 1, online, &user.Users)
|
||||||
|
game.Show()
|
||||||
|
c.JSON(200, gin.H{"message": "ok"})
|
||||||
|
})
|
||||||
|
router.POST("/play_game", func(c *gin.Context) {
|
||||||
|
_, msg, is := service.PublicPostCheck(c)
|
||||||
|
if !is {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g := global.GetGameInfo(msg["game_uuid"].(string))
|
||||||
|
if g != nil {
|
||||||
|
game := g.Obj.(*TenGame)
|
||||||
|
game.Play(game.userIndex, int(msg["pos"].(float64)))
|
||||||
|
}
|
||||||
|
c.JSON(200, gin.H{"message": "ok"})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.POST("/close_game", func(c *gin.Context) {
|
||||||
|
_, msg, is := service.PublicPostCheck(c)
|
||||||
|
if !is {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g := global.GetGameInfo(msg["game_uuid"].(string))
|
||||||
|
if g != nil {
|
||||||
|
dialog.NewConfirm("提示", "对方已退出", func(b bool) {
|
||||||
|
g.Obj.(*TenGame).w.Close()
|
||||||
|
}, g.Obj.(*TenGame).w).Show()
|
||||||
|
//dialog.ShowInformation("提示", "对方已退出", g.Obj.(*TenGame).w)
|
||||||
|
}
|
||||||
|
c.JSON(200, gin.H{"message": "ok"})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格子棋 Checkered-Chess
|
// 格子棋 Checkered-Chess
|
||||||
@@ -123,9 +172,9 @@ func NewTenGame(winCallback func(int)) *TenGame {
|
|||||||
currentRoundPlayer: 0,
|
currentRoundPlayer: 0,
|
||||||
players: make([][]int, len(playerImageMap)),
|
players: make([][]int, len(playerImageMap)),
|
||||||
winCallback: winCallback,
|
winCallback: winCallback,
|
||||||
itemSize: fyne.NewSize(50, 50),
|
itemSize: fyne.NewSize(45, 45),
|
||||||
itemX: 10,
|
itemX: 19,
|
||||||
itemY: 10,
|
itemY: 19,
|
||||||
winSum: 5,
|
winSum: 5,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
Cancel: cancel,
|
Cancel: cancel,
|
||||||
@@ -150,7 +199,14 @@ func (t *TenGame) AddNet(uuid string, myIndex int, online *models.Online, user *
|
|||||||
// 发起人
|
// 发起人
|
||||||
if myIndex == 0 {
|
if myIndex == 0 {
|
||||||
t.userIndex = 1
|
t.userIndex = 1
|
||||||
_, err := service.Client.StartGame(t.online, t.uuid, global.GameType1)
|
req := gin.H{
|
||||||
|
"type": global.GameType1,
|
||||||
|
"game_uuid": t.uuid,
|
||||||
|
"x": t.itemX,
|
||||||
|
"y": t.itemY,
|
||||||
|
"win": t.winSum,
|
||||||
|
}
|
||||||
|
_, err := service.PostSend("/start_game", online, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.isNet = false
|
t.isNet = false
|
||||||
return err
|
return err
|
||||||
@@ -159,18 +215,12 @@ func (t *TenGame) AddNet(uuid string, myIndex int, online *models.Online, user *
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TenGame) StartShow() {
|
func (t *TenGame) Show() {
|
||||||
myApp := fyne.CurrentApp()
|
myApp := fyne.CurrentApp()
|
||||||
|
|
||||||
myWindow := myApp.NewWindow("")
|
myWindow := myApp.NewWindow("")
|
||||||
t.w = myWindow
|
t.w = myWindow
|
||||||
t.setTitle()
|
t.setTitle()
|
||||||
wSize := fyne.NewSize(t.itemX*(t.itemSize.Width), t.itemY*(t.itemSize.Height))
|
myWindow.SetContent(t.mainCanvasObject())
|
||||||
myWindow.Resize(wSize)
|
|
||||||
myWindow.SetContent(container.New(layout.NewMaxLayout(),
|
|
||||||
canvas.NewImageFromResource(drawABackgroundImage(wSize, int(t.itemX), int(t.itemY))),
|
|
||||||
t.CanvasObject()))
|
|
||||||
|
|
||||||
myWindow.SetOnClosed(func() {
|
myWindow.SetOnClosed(func() {
|
||||||
if t.isNet {
|
if t.isNet {
|
||||||
global.DeleteGame(t.uuid)
|
global.DeleteGame(t.uuid)
|
||||||
@@ -182,7 +232,16 @@ func (t *TenGame) StartShow() {
|
|||||||
myWindow.Show()
|
myWindow.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TenGame) CanvasObject() fyne.CanvasObject {
|
// 主界面
|
||||||
|
func (t *TenGame) mainCanvasObject() fyne.CanvasObject {
|
||||||
|
return container.NewBorder(nil, nil, nil, nil, t.chessCanvasObject())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 棋盘界面
|
||||||
|
func (t *TenGame) chessCanvasObject() fyne.CanvasObject {
|
||||||
|
// 计算大小
|
||||||
|
wSize := fyne.NewSize(t.itemX*(t.itemSize.Width), t.itemY*(t.itemSize.Height))
|
||||||
|
|
||||||
var items []fyne.CanvasObject
|
var items []fyne.CanvasObject
|
||||||
|
|
||||||
for i := 0; i < int(t.itemX*t.itemY); i++ {
|
for i := 0; i < int(t.itemX*t.itemY); i++ {
|
||||||
@@ -202,14 +261,24 @@ func (t *TenGame) CanvasObject() fyne.CanvasObject {
|
|||||||
})
|
})
|
||||||
toggle.Resize(t.itemSize)
|
toggle.Resize(t.itemSize)
|
||||||
|
|
||||||
iViews := container.NewBorder(nil, nil, nil, nil, container.NewWithoutLayout(image, toggle))
|
iViews := container.NewWithoutLayout(image, toggle)
|
||||||
iViews.Resize(t.itemSize)
|
iViews.Resize(t.itemSize)
|
||||||
//gridWrap.Add()
|
//gridWrap.Add()
|
||||||
items = append(items, iViews)
|
items = append(items, iViews)
|
||||||
}
|
}
|
||||||
gridWrap := container.NewGridWithRows(int(t.itemX), items...)
|
gridWrap := container.NewGridWithRows(int(t.itemX), items...)
|
||||||
|
|
||||||
return container.NewScroll(gridWrap)
|
scroll := container.NewScroll(gridWrap)
|
||||||
|
scroll.SetMinSize(wSize)
|
||||||
|
|
||||||
|
// 绘制背景
|
||||||
|
background := canvas.NewImageFromResource(drawABackgroundImage(wSize, int(t.itemX), int(t.itemY)))
|
||||||
|
background.SetMinSize(wSize)
|
||||||
|
|
||||||
|
return container.New(layout.NewCenterLayout(),
|
||||||
|
background,
|
||||||
|
scroll,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TenGame) Play(userIndex int, pos int) error {
|
func (t *TenGame) Play(userIndex int, pos int) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user