package views import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "slices" "sync" ) func TenChinaGameView() { game := NewTenGame(nil) game.StartShow() } type TenGame struct { lock sync.Mutex playerMax int // 玩家总人数 playerID2Image map[int]fyne.Resource // 各个玩家对应的图标 defaultImage fyne.Resource CurrentRoundPlayer int // 当前行动的玩家 players [][]int // 各个玩家已完成下棋数据 winCallback func(int) // 胜利返回 Items []*canvas.Image // 各个板块对象 w fyne.Window itemSize fyne.Size //单个格子大小 itemX float32 // 格子总数x itemY float32 // 格子总数y } func NewTenGame(winCallback func(int)) *TenGame { game := &TenGame{ playerID2Image: map[int]fyne.Resource{ 0: theme.RadioButtonIcon(), 1: theme.CancelIcon(), }, defaultImage: theme.CheckButtonIcon(), CurrentRoundPlayer: 0, players: make([][]int, 2), winCallback: winCallback, itemSize: fyne.NewSize(100, 100), itemX: 3, itemY: 3, } return game } func (t *TenGame) StartShow() { myApp := fyne.CurrentApp() myWindow := myApp.NewWindow("Game") t.w = myWindow myWindow.SetContent(t.CanvasObject()) myWindow.Resize(fyne.NewSize(t.itemX*t.itemSize.Width+20, t.itemY*t.itemSize.Height+20)) myWindow.CenterOnScreen() myWindow.Show() } func (t *TenGame) CanvasObject() fyne.CanvasObject { gridWrap := container.NewGridWrap(t.itemSize) for i := 0; i < int(t.itemX*t.itemY); i++ { var itemIndex = i image := canvas.NewImageFromResource(t.defaultImage) image.FillMode = canvas.ImageFillOriginal image.Resize(t.itemSize) //fy t.Items = append(t.Items, image) toggle := widget.NewButton("", func() { t.Play(0, itemIndex) }) toggle.Resize(t.itemSize) //toggle.Alignment = 3 gridWrap.Add(container.NewBorder(nil, nil, nil, nil, container.NewWithoutLayout(image, toggle))) } return container.NewScroll(gridWrap) } func (t *TenGame) Play(userIndex int, pos int) error { t.lock.Lock() defer t.lock.Unlock() //if t.CurrentRoundPlayer != userIndex { // return errors.New("not your turn") //} t.play(pos) // 推进 t.CurrentRoundPlayer++ if t.CurrentRoundPlayer+1 > len(t.playerID2Image) { t.CurrentRoundPlayer = 0 } return nil } /* 1, 2, 3 4, 5, 6 7, 8, 9 */ func (t *TenGame) play(pos int) { // 更新玩家数据 playerIntList := t.players[t.CurrentRoundPlayer] playerIntList = append(playerIntList, pos) t.players[t.CurrentRoundPlayer] = playerIntList // 刷新展示 t.Items[pos].Resource = t.playerID2Image[t.CurrentRoundPlayer] t.Items[pos].Refresh() // check 胜利 判断 if t.winCheck(playerIntList) { endView := widget.NewButton("关闭", func() { t.w.Close() }) img := canvas.NewImageFromResource(t.playerID2Image[t.CurrentRoundPlayer]) img.FillMode = canvas.ImageFillOriginal v := container.NewBorder(nil, endView, nil, nil, container.NewBorder(nil, nil, img, nil, widget.NewLabel("胜利"))) dialog.NewCustomWithoutButtons("游戏结束", v, t.w).Show() if t.winCallback != nil { t.winCallback(t.CurrentRoundPlayer) } } } func (t *TenGame) winCheck(playerIntList []int) bool { slices.Sort(playerIntList) if isArithmeticSequence(playerIntList, 1) || isArithmeticSequence(playerIntList, 2) || isArithmeticSequence(playerIntList, 3) || isArithmeticSequence(playerIntList, 4) { return true } return false } func isArithmeticSequence(numbers []int, diff int) bool { if len(numbers) <= 2 { return false } for i := 1; i < len(numbers); i++ { if numbers[i]-numbers[i-1] != diff { return false } } return true }