package main import ( "fmt" "strconv" "strings" ) type GameStatus int const ( StatusLobby = iota StatusReady StatusPlaying StatusStop ) func (g GameStatus) String() string { return []string{"Lobby", "Ready", "Playing", "Stopped"}[g] } type Game struct { GameBoard *Board SentinalPlayer *Player ScourgePlayer *Player SentinalDeck *Deck ScourgeDeck *Deck CurrentTurn int CardBuffer []Card CanDraw bool Status GameStatus } func NewGame() *Game { deckA := NewDeck() deckB := NewDeck() deckA.Shuffle() deckB.Shuffle() return &Game{ GameBoard: NewBoard(), SentinalPlayer: NewPlayer("Sentinal", 1), ScourgePlayer: NewPlayer("Scourge", 2), SentinalDeck: deckA, ScourgeDeck: deckB, CurrentTurn: 0, //start with no turn CardBuffer: []Card{}, CanDraw: false, Status: StatusLobby, } } func (g *Game) String() string { return fmt.Sprintf("Sen(%v): %v\n\n%v\n\nSco(%v): %v\nStatus:%v Draw:%v Turn:%v\n%v\n", g.SentinalPlayer.Life, g.SentinalPlayer.Hand, g.GameBoard, g.ScourgePlayer.Life, g.ScourgePlayer.Hand, g.Status, g.CanDraw, g.CurrentTurn, g.CardBuffer) } func (g *Game) PlayerStateAct(id int, cmd string) *Game { switch cmd { case "d": //debug game state return g case "g": //game state if id == 1 { return &Game{ GameBoard: g.GameBoard, SentinalPlayer: g.SentinalPlayer, ScourgePlayer: nil, SentinalDeck: g.SentinalDeck, ScourgeDeck: nil, CurrentTurn: g.CurrentTurn, CardBuffer: nil, CanDraw: g.CanDraw, Status: g.Status, } } else { return &Game{ GameBoard: g.GameBoard, SentinalPlayer: nil, ScourgePlayer: g.ScourgePlayer, SentinalDeck: nil, ScourgeDeck: g.ScourgeDeck, CurrentTurn: g.CurrentTurn, CardBuffer: nil, CanDraw: g.CanDraw, Status: g.Status, } } case "b": //begin game g.Status = StatusReady //TODO check for ready on both accounts first g.SentinalPlayer.Hand = g.SentinalDeck.Cards[len(g.SentinalDeck.Cards)-5 : len(g.SentinalDeck.Cards)] g.SentinalDeck.Cards = g.SentinalDeck.Cards[0 : len(g.SentinalDeck.Cards)-5] g.ScourgePlayer.Hand = g.ScourgeDeck.Cards[len(g.ScourgeDeck.Cards)-5 : len(g.ScourgeDeck.Cards)] g.SentinalDeck.Cards = g.ScourgeDeck.Cards[0 : len(g.ScourgeDeck.Cards)-5] return g case "s": //start turn if g.Status == StatusReady { g.Status = StatusPlaying g.CurrentTurn = id g.CanDraw = false } else { g.CanDraw = true } if id != g.CurrentTurn { return nil } if id == 1 { for _, v := range g.GameBoard.Sentinal { v.Upkeep(g) } } else { for _, v := range g.GameBoard.Scourge { v.Upkeep(g) } } return g case "e": //end turn and clean up if id != g.CurrentTurn { return nil } g.CardBuffer = []Card{} if id == 1 { for _, v := range g.GameBoard.Sentinal { v.Endstep(g) } } else { for _, v := range g.GameBoard.Scourge { v.Endstep(g) } } if g.CurrentTurn == 1 { g.CurrentTurn = 2 } else { g.CurrentTurn = 1 } return g } fmt.Println("invalid state command") return nil } func (g *Game) PlayerAct(id int, cmd string) []Card { if id != g.CurrentTurn { return nil } var curr *Player var opp *Player var currD *Deck if id == g.SentinalPlayer.Id { curr = g.SentinalPlayer opp = g.ScourgePlayer currD = g.SentinalDeck } else { curr = g.ScourgePlayer opp = g.SentinalPlayer currD = g.ScourgeDeck } cmd_s := strings.Split(cmd, " ") if len(cmd_s) < 1 { return nil } switch cmd_s[0] { case "s": //scry: return scry options off top of deck if !g.CanDraw || len(g.CardBuffer) > 0 { return nil } g.CardBuffer = currD.Scry(curr.Life) return g.CardBuffer case "d": //draw: return player hand if !g.CanDraw { return nil } if len(cmd_s) != 2 || !g.CanDraw { return nil } x_i, err := strconv.Atoi(cmd_s[1]) if err != nil { panic(err) } x := g.CardBuffer[x_i] buf := g.CardBuffer for i, v := range buf { if v == x { buf = append(buf[:i], buf[i+1:]...) } } currD.Bottom(buf) curr.Hand = append(curr.Hand, x) g.CanDraw = false return curr.Hand case "m": //move: return player board or [] if invalid if len(cmd_s) != 3 { return nil } x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) res := g.GameBoard.Move(g.CurrentTurn, x_i, y_i) if res { return g.GameBoard.GetRow(g.CurrentTurn) } else { return []Card{} } case "a": //attack if len(cmd_s) != 3 { return nil } x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) res := g.GameBoard.Attack(g.CurrentTurn, x_i, y_i) if res == 1 { opp.Life = opp.Life - 1 return g.GameBoard.GetRow(g.CurrentTurn) } else if res == 0 { return g.GameBoard.GetRow(g.CurrentTurn) } else { fmt.Println("can't attack") return []Card{} } case "p": //play: return player boad or [] if invalid if len(cmd_s) != 3 { fmt.Println("not enough arguments") return nil } fmt.Println("playing") x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) card := curr.Hand[x_i] if g.GameBoard.CanPlay(g.CurrentTurn, &card, y_i) { curr.Hand[x_i].Cast(g) } res := g.GameBoard.Play(g.CurrentTurn, &card, y_i) if res { curr.Hand[x_i].Enters(g) curr.Hand = append(curr.Hand[:x_i], curr.Hand[x_i+1:]...) return g.GameBoard.GetRow(g.CurrentTurn) } else { fmt.Println("couldn't play") return []Card{} } default: fmt.Println("Invalid act command") return nil } return nil }