Skip to content

Commit

Permalink
Merge pull request #20 from feel-easy/len/uno
Browse files Browse the repository at this point in the history
增加uno的房间
  • Loading branch information
ainilili authored Jul 17, 2022
2 parents 33cf160 + efb990e commit c18751c
Show file tree
Hide file tree
Showing 44 changed files with 2,034 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@
# Dependency directories (remove the comment below to include it)
# vendor/
/.idea

.vscode
8 changes: 6 additions & 2 deletions consts/const.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package consts

import (
"github.com/ratel-online/core/consts"
"time"

"github.com/ratel-online/core/consts"
)

type StateID int
Expand All @@ -16,6 +17,7 @@ const (
StateWaiting
StateGame
StateRunFastGame
StateUnoGame
)

type SkillID int
Expand Down Expand Up @@ -49,6 +51,7 @@ const (
GameTypeLaiZi = 2
GameTypeSkill = 3
GameTypeRunFast = 4
GameTypeUno = 5

RobTimeout = 20 * time.Second
PlayTimeout = 40 * time.Second
Expand Down Expand Up @@ -105,8 +108,9 @@ var (
GameTypeLaiZi: "LaiZi",
GameTypeSkill: "Skill",
GameTypeRunFast: "RunFast",
GameTypeUno: "Uno",
}
GameTypesIds = []int{GameTypeClassic, GameTypeLaiZi, GameTypeSkill, GameTypeRunFast} // GameTypeLaiZi, GameTypeRunFast
GameTypesIds = []int{GameTypeClassic, GameTypeLaiZi, GameTypeSkill, GameTypeRunFast, GameTypeUno} // GameTypeLaiZi, GameTypeRunFast
RoomStates = map[int]string{
RoomStateWaiting: "Waiting",
RoomStateRunning: "Running",
Expand Down
12 changes: 6 additions & 6 deletions database/database.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package database

import (
"sort"
"strconv"
stringx "strings"
"sync/atomic"
"time"

"github.com/awesome-cap/hashmap"
"github.com/ratel-online/core/log"
modelx "github.com/ratel-online/core/model"
Expand All @@ -9,11 +15,6 @@ import (
"github.com/ratel-online/core/util/json"
"github.com/ratel-online/core/util/strings"
"github.com/ratel-online/server/consts"
"sort"
"strconv"
stringx "strings"
"sync/atomic"
"time"
)

var roomIds int64 = 0
Expand Down Expand Up @@ -232,7 +233,6 @@ func leaveRoom(room *Room, player *Player) {
if len(playersIds) == 0 {
deleteRoom(room)
}
return
}

func offline(roomId, playerId int64) {
Expand Down
176 changes: 170 additions & 6 deletions database/model.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package database

import (
"bytes"
"fmt"
"strconv"
"strings"
"sync"
"time"

"github.com/ratel-online/core/log"
"github.com/ratel-online/core/model"
"github.com/ratel-online/core/network"
Expand All @@ -10,12 +16,27 @@ import (
"github.com/ratel-online/core/util/json"
"github.com/ratel-online/core/util/poker"
"github.com/ratel-online/server/consts"
"strconv"
"strings"
"sync"
"time"
"github.com/ratel-online/server/uno/card"
"github.com/ratel-online/server/uno/card/color"
"github.com/ratel-online/server/uno/event"
"github.com/ratel-online/server/uno/game"
)

const initialRune = 'A'

type runeSequence struct {
currentRune rune
}

func (s *runeSequence) next() rune {
if s.currentRune == 0 {
s.currentRune = initialRune
}
currentRune := s.currentRune
s.currentRune++
return currentRune
}

type Player struct {
ID int64 `json:"id"`
IP string `json:"ip"`
Expand All @@ -32,6 +53,127 @@ type Player struct {
online bool
}

func (p *Player) GamePlayer() game.Player {
return p
}

func (p *Player) PlayerID() int64 {
return p.ID
}

func (p *Player) NickName() string {
return p.Name
}

func (p *Player) PickColor(gameState game.State) color.Color {
for {
p = getPlayer(p.ID)
p.WriteString(fmt.Sprintf(
"Select a color: '%s', '%s', '%s' or '%s'? \n",
color.Red,
color.Yellow,
color.Green,
color.Blue,
))
colorName, err := p.AskForString(consts.PlayTimeout)
if err != nil {
if err == consts.ErrorsTimeout {
return color.Red
}
p.WriteString(fmt.Sprintf("Unknown color '%s' \n", colorName))
continue
}
chosenColor, err := color.ByName(colorName)
if err != nil {
p.WriteString(fmt.Sprintf("Unknown color '%s' \n", colorName))
continue
}
return chosenColor
}
}

func (p *Player) Play(playableCards []card.Card, gameState game.State) (card.Card, error) {
p = getPlayer(p.ID)
buf := bytes.Buffer{}
buf.WriteString(fmt.Sprintf("It's your turn, %s! \n", p.Name))
buf.WriteString(gameState.String())
p.WriteString(buf.String())
runeSequence := runeSequence{}
cardOptions := make(map[string]card.Card)
for _, card := range playableCards {
label := string(runeSequence.next())
cardOptions[label] = card
}
cardSelectionLines := []string{"Select a card to play:"}
for label, card := range cardOptions {
cardSelectionLines = append(cardSelectionLines, fmt.Sprintf("%s (enter %s)", card, label))
}
cardSelectionMessage := strings.Join(cardSelectionLines, " \n ") + " \n "
for {
p = getPlayer(p.ID)
p.WriteString(cardSelectionMessage)
selectedLabel, err := p.AskForString(consts.PlayTimeout)
if err != nil {
if err == consts.ErrorsTimeout {
selectedLabel = "A"
} else {
return nil, err
}
}
selectedCard, found := cardOptions[selectedLabel]
if !found {
p.WriteString(fmt.Sprintf("No card assigned to '%s' \n", selectedLabel))
continue
}
if !contains(playableCards, selectedCard) {
p.WriteString(fmt.Sprintf("Cheat detected! Card %s is not in %s's hand! \n", selectedCard, p.NickName()))
continue
}
return selectedCard, nil
}
}

func contains(cards []card.Card, searchedCard card.Card) bool {
for _, card := range cards {
if card.Equal(searchedCard) {
return true
}
}
return false
}

func (p *Player) OnFirstCardPlayed(payload event.FirstCardPlayedPayload) {
p = getPlayer(p.ID)
Broadcast(p.RoomID, fmt.Sprintf("First card is %s\n", payload.Card))
}

func (p *Player) OnCardPlayed(payload event.CardPlayedPayload) {
p = getPlayer(p.ID)
Broadcast(p.RoomID, fmt.Sprintf("%s played %s!\n", payload.PlayerName, payload.Card))
}

func (p *Player) OnColorPicked(payload event.ColorPickedPayload) {
p = getPlayer(p.ID)
Broadcast(p.RoomID, fmt.Sprintf("%s picked color %s!\n", payload.PlayerName, payload.Color))
}

func (p *Player) OnPlayerPassed(payload event.PlayerPassedPayload) {
p = getPlayer(p.ID)
Broadcast(p.RoomID, fmt.Sprintf("%s passed!\n", payload.PlayerName))
}

func (p *Player) NotifyCardsDrawn(cards []card.Card) {
p = getPlayer(p.ID)
getPlayer(p.ID).WriteString(fmt.Sprintf("You drew %s!\n", cards))
}

func (p *Player) NotifyNoMatchingCardsInHand(lastPlayedCard card.Card, hand []card.Card) {
buf := bytes.Buffer{}
buf.WriteString(fmt.Sprintf("%s, none of your cards match %s! \n", p.Name, lastPlayedCard))
buf.WriteString(fmt.Sprintf("Your hand is %s \n", hand))
getPlayer(p.ID).WriteString(buf.String())
}

func (p *Player) Write(bytes []byte) error {
return p.conn.Write(protocol.Packet{
Body: bytes,
Expand All @@ -46,7 +188,7 @@ func (p *Player) Offline() {
if room != nil {
room.Lock()
defer room.Unlock()
broadcast(room, fmt.Sprintf("%s lost connection!\n", p.Name))
broadcast(room, fmt.Sprintf("%s lost connection! \n", p.Name))
if room.State == consts.RoomStateWaiting {
leaveRoom(room, p)
}
Expand Down Expand Up @@ -197,6 +339,7 @@ type Room struct {
ID int64 `json:"id"`
Type int `json:"type"`
Game *Game `json:"gameId"`
UnoGame *UnoGame `json:"unoGame"`
State int `json:"state"`
Players int `json:"players"`
Robots int `json:"robots"`
Expand All @@ -211,7 +354,7 @@ type Room struct {
EnableDontShuffle bool `json:"enableDontShuffle"`
}

func (r Room) Model() model.Room {
func (r *Room) Model() model.Room {
return model.Room{
ID: r.ID,
Type: r.Type,
Expand Down Expand Up @@ -278,3 +421,24 @@ func (g Game) Team(playerId int64) string {
}
}
}

type UnoGame struct {
Room *Room `json:"room"`
Players []int64 `json:"players"`
States map[int64]chan int `json:"states"`
Game *game.Game `json:"game"`
PlayerNumber int `json:"playerNumber"`
}

func (ug *UnoGame) HavePlay(player *Player) bool {
for _, id := range ug.Players {
if id == player.ID && player.online {
return true
}
}
return false
}

func (un *UnoGame) NeedExit() bool {
return un.PlayerNumber <= 1
}
18 changes: 13 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@ module github.com/ratel-online/server
go 1.17

require (
github.com/awesome-cap/hashmap v0.0.0-20220308123617-f10e2b637d7d
github.com/gorilla/websocket v1.5.0
github.com/ratel-online/core v0.0.0-20220712045315-c2b04ce849a7
github.com/awesome-cap/hashmap v0.0.0-20211211100532-e3300ac4ae14
github.com/fatih/color v1.8.0
github.com/gorilla/websocket v1.4.2
github.com/ratel-online/core v0.0.0-20220717092113-9fdec75dd055
github.com/stretchr/testify v1.6.1
)

require (
github.com/awesome-cap/im v0.0.0-20211230022156-64f8168049db // indirect
github.com/awesome-cap/im v0.0.0-20210720090440-7556eb92965d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
Loading

0 comments on commit c18751c

Please sign in to comment.