Code for sequential phases to match up with Croupier Flutter
Change-Id: I2f0631862a484bc49b277415ffb576eb99531605
diff --git a/go/src/hearts/assets/StartBlue.png b/go/src/hearts/assets/StartBlue.png
new file mode 100644
index 0000000..036938f
--- /dev/null
+++ b/go/src/hearts/assets/StartBlue.png
Binary files differ
diff --git a/go/src/hearts/assets/StartGray.png b/go/src/hearts/assets/StartGray.png
new file mode 100644
index 0000000..555592c
--- /dev/null
+++ b/go/src/hearts/assets/StartGray.png
Binary files differ
diff --git a/go/src/hearts/img/reposition/reposition.go b/go/src/hearts/img/reposition/reposition.go
index 8bc1aef..a86da1f 100644
--- a/go/src/hearts/img/reposition/reposition.go
+++ b/go/src/hearts/img/reposition/reposition.go
@@ -168,6 +168,7 @@
// Animation for the 'play' action, when app is in the table view
func AnimateTableCardPlay(animCard *card.Card, playerInt int, quit chan bool, u *uistate.UIState) {
+ BringNodeToFront(animCard.GetNode(), u)
destination := u.DropTargets[playerInt]
destinationPos := destination.GetCurrent()
destinationDim := destination.GetDimensions()
diff --git a/go/src/hearts/img/texture/texture.go b/go/src/hearts/img/texture/texture.go
index 5a4c71c..12d65cd 100644
--- a/go/src/hearts/img/texture/texture.go
+++ b/go/src/hearts/img/texture/texture.go
@@ -272,7 +272,7 @@
"U-Lower-Gray.png", "V-Lower-Gray.png", "W-Lower-Gray.png", "X-Lower-Gray.png", "Y-Lower-Gray.png", "Z-Lower-Gray.png",
"Space-Gray.png", "RoundedRectangle-DBlue.png", "RoundedRectangle-LBlue.png", "RoundedRectangle-Gray.png", "Rectangle-LBlue.png",
"Rectangle-DBlue.png", "HorizontalPullTab.png", "VerticalPullTab.png", "NewGame.png", "NewRound.png", "JoinGame.png", "Period.png",
- "SitSpot.png", "WatchSpot.png",
+ "SitSpot.png", "WatchSpot.png", "StartBlue.png", "StartGray.png",
}
for _, f := range boundedImgs {
a, err := asset.Open(f)
diff --git a/go/src/hearts/img/uistate/uistate.go b/go/src/hearts/img/uistate/uistate.go
index b6d90c0..10497df 100644
--- a/go/src/hearts/img/uistate/uistate.go
+++ b/go/src/hearts/img/uistate/uistate.go
@@ -72,65 +72,67 @@
NumPlayers int
NumSuits int
// the following variables are used for sizing and positioning specifications
- CardSize float32
- CardScaler float32
- TopPadding float32
- BottomPadding float32
- WindowSize *coords.Vec // windowSize is in Pt
- CardDim *coords.Vec
- TableCardDim *coords.Vec
- PlayerIconDim *coords.Vec
- PixelsPerPt float32
- Overlap *coords.Vec
- Padding float32
- CurView View // the screen currently being shown to the user
- CurTable *table.Table // the table of the current game
- Done bool // true if the app has been quit
- Texs map[string]sprite.SubTex // map of all loaded images
- CurPlayerIndex int // the player number of this player
- Ctx *context.T
- Service syncbase.Service
- Debug bool // true if debugging, adds extra functionality to switch between players
- Shutdown func() // used to shut down a v23.Init()
- GameID int // used to differentiate between concurrent games
- IsOwner bool // true if this player is the game creator
- UserData map[int]map[string]interface{} // user data indexed by user ID
- PlayerData map[int]int // key = player number, value = user id
- AnimChans []chan bool // keeps track of all 'quit' channels in animations so their goroutines can be stopped
- SGChan chan bool // pass in a bool to stop advertising the syncgroup
- ScanChan chan bool // pass in a bool to stop scanning for syncgroups
+ CardSize float32
+ CardScaler float32
+ TopPadding float32
+ BottomPadding float32
+ WindowSize *coords.Vec // windowSize is in Pt
+ CardDim *coords.Vec
+ TableCardDim *coords.Vec
+ PlayerIconDim *coords.Vec
+ PixelsPerPt float32
+ Overlap *coords.Vec
+ Padding float32
+ CurView View // the screen currently being shown to the user
+ CurTable *table.Table // the table of the current game
+ Done bool // true if the app has been quit
+ Texs map[string]sprite.SubTex // map of all loaded images
+ CurPlayerIndex int // the player number of this player
+ Ctx *context.T
+ Service syncbase.Service
+ Debug bool // true if debugging, adds extra functionality to switch between players
+ SequentialPhases bool // true if trying to match Croupier Flutter Pass -> Take -> Play phase system
+ Shutdown func() // used to shut down a v23.Init()
+ GameID int // used to differentiate between concurrent games
+ IsOwner bool // true if this player is the game creator
+ UserData map[int]map[string]interface{} // user data indexed by user ID
+ PlayerData map[int]int // key = player number, value = user id
+ AnimChans []chan bool // keeps track of all 'quit' channels in animations so their goroutines can be stopped
+ SGChan chan bool // pass in a bool to stop advertising the syncgroup
+ ScanChan chan bool // pass in a bool to stop scanning for syncgroups
}
func MakeUIState() *UIState {
return &UIState{
- StartTime: time.Now(),
- Cards: make([]*card.Card, 0),
- TableCards: make([]*card.Card, 0),
- BackgroundImgs: make([]*staticimg.StaticImg, 0),
- EmptySuitImgs: make([]*staticimg.StaticImg, 0),
- DropTargets: make([]*staticimg.StaticImg, 0),
- Buttons: make([]*staticimg.StaticImg, 0),
- Other: make([]*staticimg.StaticImg, 0),
- ModText: make([]*staticimg.StaticImg, 0),
- LastMouseXY: coords.MakeVec(-1, -1),
- NumPlayers: numPlayers,
- NumSuits: numSuits,
- CardSize: cardSize,
- CardScaler: cardScaler,
- TopPadding: topPadding,
- BottomPadding: bottomPadding,
- WindowSize: coords.MakeVec(-1, -1),
- CardDim: coords.MakeVec(cardSize, cardSize),
- TableCardDim: coords.MakeVec(cardSize*cardScaler, cardSize*cardScaler),
- PlayerIconDim: coords.MakeVec(2*cardSize/3, 2*cardSize/3),
- Overlap: coords.MakeVec(3*cardSize*cardScaler/4, 3*cardSize*cardScaler/4),
- Padding: float32(5),
- CurView: None,
- Done: false,
- Debug: true,
- UserData: make(map[int]map[string]interface{}),
- PlayerData: make(map[int]int),
- AnimChans: make([]chan bool, 0),
+ StartTime: time.Now(),
+ Cards: make([]*card.Card, 0),
+ TableCards: make([]*card.Card, 0),
+ BackgroundImgs: make([]*staticimg.StaticImg, 0),
+ EmptySuitImgs: make([]*staticimg.StaticImg, 0),
+ DropTargets: make([]*staticimg.StaticImg, 0),
+ Buttons: make([]*staticimg.StaticImg, 0),
+ Other: make([]*staticimg.StaticImg, 0),
+ ModText: make([]*staticimg.StaticImg, 0),
+ LastMouseXY: coords.MakeVec(-1, -1),
+ NumPlayers: numPlayers,
+ NumSuits: numSuits,
+ CardSize: cardSize,
+ CardScaler: cardScaler,
+ TopPadding: topPadding,
+ BottomPadding: bottomPadding,
+ WindowSize: coords.MakeVec(-1, -1),
+ CardDim: coords.MakeVec(cardSize, cardSize),
+ TableCardDim: coords.MakeVec(cardSize*cardScaler, cardSize*cardScaler),
+ PlayerIconDim: coords.MakeVec(2*cardSize/3, 2*cardSize/3),
+ Overlap: coords.MakeVec(3*cardSize*cardScaler/4, 3*cardSize*cardScaler/4),
+ Padding: float32(5),
+ CurView: None,
+ Done: false,
+ Debug: true,
+ SequentialPhases: true,
+ UserData: make(map[int]map[string]interface{}),
+ PlayerData: make(map[int]int),
+ AnimChans: make([]chan bool, 0),
}
}
diff --git a/go/src/hearts/img/view/view.go b/go/src/hearts/img/view/view.go
index 4781754..3977bcc 100644
--- a/go/src/hearts/img/view/view.go
+++ b/go/src/hearts/img/view/view.go
@@ -36,7 +36,7 @@
watchImg := u.Texs["WatchSpot.png"]
arrangeBlockLength := u.WindowSize.X - 4*u.Padding - u.CardDim.X
if u.WindowSize.Y < u.WindowSize.X {
- arrangeBlockLength = u.WindowSize.Y - 4*u.Padding - u.CardDim.Y
+ arrangeBlockLength = u.WindowSize.Y - u.CardDim.Y
}
arrangeDim := coords.MakeVec(arrangeBlockLength/3-4*u.Padding, arrangeBlockLength/3-4*u.Padding)
// player 0 seat
@@ -96,7 +96,7 @@
resetAnims(u)
resetImgs(u)
resetScene(u)
- scaler := float32(4)
+ scaler := float32(6)
maxWidth := 4 * u.TableCardDim.X
// adding four drop targets for trick
dropTargetImage := u.Texs["trickDrop.png"]
@@ -185,7 +185,7 @@
texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
}
// player 0's name
- center := coords.MakeVec(playerIconX+u.PlayerIconDim.X/2, playerIconY-30)
+ center := coords.MakeVec(playerIconX+u.PlayerIconDim.X/2, playerIconY-15)
name := uistate.GetName(0, u)
textImgs := texture.MakeStringImgCenterAlign(name, "", "", true, center, scaler, maxWidth, u)
for _, img := range textImgs {
@@ -213,7 +213,7 @@
texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
}
// player 1's name
- start := coords.MakeVec(playerIconX, playerIconY-30)
+ start := coords.MakeVec(playerIconX, playerIconY-15)
name = uistate.GetName(1, u)
textImgs = texture.MakeStringImgLeftAlign(name, "", "", true, start, scaler, maxWidth, u)
for _, img := range textImgs {
@@ -237,7 +237,7 @@
texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
}
// player 2's name
- center = coords.MakeVec(playerIconX+u.PlayerIconDim.X/2, playerIconY+u.PlayerIconDim.Y+5)
+ center = coords.MakeVec(playerIconX+u.PlayerIconDim.X/2, playerIconY+u.PlayerIconDim.Y)
name = uistate.GetName(2, u)
textImgs = texture.MakeStringImgCenterAlign(name, "", "", true, center, scaler, maxWidth, u)
for _, img := range textImgs {
@@ -264,7 +264,7 @@
texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
}
// player 3's name
- end := coords.MakeVec(playerIconX+u.PlayerIconDim.X, playerIconY-30)
+ end := coords.MakeVec(playerIconX+u.PlayerIconDim.X, playerIconY-15)
name = uistate.GetName(3, u)
textImgs = texture.MakeStringImgRightAlign(name, "", "", true, end, scaler, maxWidth, u)
for _, img := range textImgs {
@@ -387,8 +387,14 @@
addDebugBar(u)
}
// animate in play slot if relevant
- if u.CurTable.WhoseTurn() == u.CurPlayerIndex && u.CurTable.AllDonePassing() {
- reposition.AnimateInPlay(u)
+ if u.CurTable.WhoseTurn() == u.CurPlayerIndex {
+ if u.SequentialPhases {
+ if u.CurTable.AllDoneTaking() {
+ reposition.AnimateInPlay(u)
+ }
+ } else if u.CurTable.AllDonePassing() {
+ reposition.AnimateInPlay(u)
+ }
}
}
@@ -452,11 +458,11 @@
name := uistate.GetName(player, u)
var center *coords.Vec
if player == 2 {
- center = coords.MakeVec(sitPos.X+arrangeDim.X/2, sitPos.Y-u.Padding-20)
+ center = coords.MakeVec(sitPos.X+arrangeDim.X/2, sitPos.Y-u.Padding-10)
} else {
- center = coords.MakeVec(sitPos.X+arrangeDim.X/2, sitPos.Y+arrangeDim.Y+u.Padding)
+ center = coords.MakeVec(sitPos.X+arrangeDim.X/2, sitPos.Y+arrangeDim.Y)
}
- scaler := float32(4)
+ scaler := float32(6)
maxWidth := arrangeDim.X
textImgs := texture.MakeStringImgCenterAlign(name, "", "", true, center, scaler, maxWidth, u)
for _, text := range textImgs {
@@ -558,7 +564,7 @@
func getTurnText(u *uistate.UIState) string {
var turnText string
playerTurnNum := u.CurTable.WhoseTurn()
- if playerTurnNum == -1 || !u.CurTable.AllDonePassing() {
+ if playerTurnNum == -1 || !u.CurTable.AllDonePassing() || (u.SequentialPhases && !u.CurTable.AllDoneTaking()) {
turnText = "Waiting for other players"
} else if playerTurnNum == u.CurPlayerIndex {
turnText = "Your turn"
@@ -653,7 +659,12 @@
func addGrayTakeBar(u *uistate.UIState) {
passedCards := u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()
- display := len(passedCards) == 0
+ var display bool
+ if u.SequentialPhases {
+ display = !u.CurTable.AllDonePassing()
+ } else {
+ display = len(passedCards) == 0
+ }
// adding gray bar
grayBarImg := u.Texs["RoundedRectangle-Gray.png"]
grayBarAlt := u.Texs["RoundedRectangle-LBlue.png"]
@@ -698,7 +709,14 @@
}
func moveTakeCards(u *uistate.UIState) {
- passedCards := u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()
+ passedCards := make([]*card.Card, 0)
+ if u.SequentialPhases {
+ if u.CurTable.AllDonePassing() {
+ passedCards = append(passedCards, u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()...)
+ }
+ } else {
+ passedCards = append(passedCards, u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()...)
+ }
if len(passedCards) > 0 {
topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
numCards := float32(3)
@@ -724,7 +742,7 @@
}
u.Other = make([]*staticimg.StaticImg, 0)
// set new num tricks
- scaler := float32(4)
+ scaler := float32(7)
for i, d := range u.DropTargets {
dropTargetDimensions := d.GetDimensions()
dropTargetPos := d.GetCurrent()
@@ -738,16 +756,16 @@
var textImgs []*staticimg.StaticImg
switch i {
case 0:
- tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y+dropTargetDimensions.Y+u.Padding)
+ tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y+dropTargetDimensions.Y)
textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
case 1:
- tRight := coords.MakeVec(dropTargetPos.X-u.Padding, dropTargetPos.Y+dropTargetDimensions.Y/2-10)
+ tRight := coords.MakeVec(dropTargetPos.X-2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
textImgs = texture.MakeStringImgRightAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tRight, scaler, tMax, u)
case 2:
- tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y-u.Padding-20)
+ tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y-12)
textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
case 3:
- tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+u.Padding, dropTargetPos.Y+dropTargetDimensions.Y/2-10)
+ tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
}
for _, text := range textImgs {
@@ -785,6 +803,7 @@
}
}
if u.CurView == uistate.Split {
+ topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
for i, d := range u.DropTargets {
dropTargetDimensions := d.GetDimensions()
dropTargetPos := d.GetCurrent()
@@ -794,20 +813,30 @@
if numTricks == 1 {
trickText = " trick"
}
- tMax := dropTargetDimensions.Y
+ tMax := dropTargetDimensions.Y - u.Padding
var textImgs []*staticimg.StaticImg
switch i {
case 0:
- tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y+dropTargetDimensions.Y+u.Padding)
- textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
+ if topOfHand < u.TopPadding+4*u.CardDim.Y {
+ tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y+dropTargetDimensions.Y-15)
+ textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
+ } else {
+ tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y+dropTargetDimensions.Y+u.Padding)
+ textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
+ }
case 1:
- tRight := coords.MakeVec(dropTargetPos.X-u.Padding, dropTargetPos.Y+dropTargetDimensions.Y/2-10)
+ tRight := coords.MakeVec(dropTargetPos.X-2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
textImgs = texture.MakeStringImgRightAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tRight, scaler, tMax, u)
case 2:
- tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y-u.Padding-20)
- textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
+ if topOfHand < u.TopPadding+4*u.CardDim.Y {
+ tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y)
+ textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
+ } else {
+ tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y-u.Padding-10)
+ textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
+ }
case 3:
- tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+u.Padding, dropTargetPos.Y+dropTargetDimensions.Y/2-10)
+ tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
}
for _, text := range textImgs {
diff --git a/go/src/hearts/logic/table/table.go b/go/src/hearts/logic/table/table.go
index 017b9d4..7b156a1 100644
--- a/go/src/hearts/logic/table/table.go
+++ b/go/src/hearts/logic/table/table.go
@@ -37,7 +37,7 @@
heartsBroken: false,
firstTrick: true,
winCondition: 100,
- dir: direction.None,
+ dir: direction.Right,
}
}
@@ -193,7 +193,7 @@
return true
}
-// Returns true if all players have taken the cards passed to them
+// Returns true if all players have passed cards
func (t *Table) AllDonePassing() bool {
for _, p := range t.players {
if !p.GetDonePassing() {
@@ -203,6 +203,16 @@
return true
}
+// Returns true if all players have taken the cards passed to them
+func (t *Table) AllDoneTaking() bool {
+ for _, p := range t.players {
+ if !p.GetDoneTaking() {
+ return false
+ }
+ }
+ return true
+}
+
// Returns true if all players have finished looking at their scores
func (t *Table) AllReadyForNewRound() bool {
for _, p := range t.players {
diff --git a/go/src/hearts/syncbase/gamelog/logWriter.go b/go/src/hearts/syncbase/gamelog/logWriter.go
index e1fae35..92e51ab 100644
--- a/go/src/hearts/syncbase/gamelog/logWriter.go
+++ b/go/src/hearts/syncbase/gamelog/logWriter.go
@@ -8,6 +8,7 @@
package gamelog
import (
+ "fmt"
"strconv"
"time"
@@ -101,8 +102,8 @@
// Note: The syntax replicates the way Croupier in Dart/Flutter writes keys.
func getKey(playerId int, u *uistate.UIState) string {
- t := int(time.Now().UnixNano() / 1000000)
- key := strconv.Itoa(u.GameID) + "/log/" + strconv.Itoa(t) + Dash + strconv.Itoa(playerId)
+ t := time.Now().UnixNano() / 1000000
+ key := fmt.Sprintf("%d/log/%d%s%d", u.GameID, t, Dash, playerId)
return key
}
diff --git a/go/src/hearts/syncbase/util/util.go b/go/src/hearts/syncbase/util/util.go
index a146d80..bb4413e 100644
--- a/go/src/hearts/syncbase/util/util.go
+++ b/go/src/hearts/syncbase/util/util.go
@@ -10,14 +10,14 @@
// switch back to my mountpoint with the following code:
MountPoint = "users/emshack@google.com"
//MountPoint = "/192.168.86.254:8101"
- UserID = 12355
+ UserID = 23876
UserColor = 16777215
UserAvatar = "player0.jpeg"
- UserName = "Em"
+ UserName = "Ewen"
SBName = "syncbase"
AppName = "app"
DbName = "db"
LogName = "games"
SettingsName = "table_settings"
- CroupierInterface = "CroupierSettingsAndGameEmily"
+ CroupierInterface = "CroupierSettingsAndGame"
)
diff --git a/go/src/hearts/syncbase/watch/watch.go b/go/src/hearts/syncbase/watch/watch.go
index 91b4bb6..aacb706 100644
--- a/go/src/hearts/syncbase/watch/watch.go
+++ b/go/src/hearts/syncbase/watch/watch.go
@@ -154,8 +154,14 @@
u.AnimChans = append(u.AnimChans, quit)
reposition.AnimateTableCardPass(curCards, receivingPlayer, quit, u)
reposition.SetTableDropColors(u)
- } else if u.CurView == uistate.Take && u.CurPlayerIndex == receivingPlayer {
- view.LoadTakeView(u)
+ } else if u.CurView == uistate.Take {
+ if u.SequentialPhases {
+ if u.CurTable.AllDonePassing() {
+ view.LoadTakeView(u)
+ }
+ } else if u.CurPlayerIndex == receivingPlayer {
+ view.LoadTakeView(u)
+ }
} else if u.CurView == uistate.Play && u.CurTable.AllDonePassing() {
view.LoadPlayView(u)
}
@@ -170,7 +176,19 @@
p.AddToHand(c)
}
u.CurTable.GetPlayers()[playerInt].SetDoneTaking(true)
- if p.HasTwoOfClubs() {
+ if u.SequentialPhases {
+ if u.CurTable.AllDoneTaking() {
+ for _, player := range u.CurTable.GetPlayers() {
+ if player.HasTwoOfClubs() {
+ u.CurTable.SetFirstPlayer(player.GetPlayerIndex())
+ }
+ }
+ // UI
+ if u.CurView == uistate.Play {
+ view.LoadPlayView(u)
+ }
+ }
+ } else if p.HasTwoOfClubs() {
u.CurTable.SetFirstPlayer(p.GetPlayerIndex())
// UI
if u.CurView == uistate.Play && u.CurPlayerIndex != playerInt {
diff --git a/go/src/hearts/touchhandler/touchhandler.go b/go/src/hearts/touchhandler/touchhandler.go
index 2dc4f60..7f48b97 100644
--- a/go/src/hearts/touchhandler/touchhandler.go
+++ b/go/src/hearts/touchhandler/touchhandler.go
@@ -150,7 +150,8 @@
}
}
-//&& u.PlayerData[u.CurPlayerIndex] == 0
+// If players cannot sit in more than one spot, replace the line 5 ahead of this one with the following line:
+// if len(buttonList) > 0 && u.PlayerData[u.CurPlayerIndex] == 0 {
func beginClickArrange(t touch.Event, u *uistate.UIState) {
buttonList := findClickedButton(t, u)