Merge "Valid play logic, win condition, tests"
diff --git a/go/src/sprites/logic_test.go b/go/src/sprites/logic_test.go
index fb9decd..22f2465 100644
--- a/go/src/sprites/logic_test.go
+++ b/go/src/sprites/logic_test.go
@@ -21,7 +21,7 @@
 	p3 := player.NewPlayer(3)
 	players := []*player.Player{p0, p1, p2, p3}
 	t := table.NewTable(players)
-	t.SetFirst(1)
+	t.SetFirstPlayed(1)
 	t.PlayCard(card.NewCard(3, "H"), 1)
 	t.PlayCard(card.NewCard(7, "H"), 2)
 	t.PlayCard(card.NewCard(12, "S"), 3)
@@ -57,13 +57,13 @@
 	p3 := player.NewPlayer(3)
 	players := []*player.Player{p0, p1, p2, p3}
 	t := table.NewTable(players)
-	t.SetFirst(1)
+	t.SetFirstPlayed(1)
 	t.PlayCard(card.NewCard(3, "H"), 1)
 	t.PlayCard(card.NewCard(7, "H"), 2)
 	t.PlayCard(card.NewCard(12, "S"), 3)
 	t.PlayCard(card.NewCard(4, "D"), 0)
 	t.SendTrick()
-	t.SetFirst(2)
+	t.SetFirstPlayed(2)
 	t.PlayCard(card.NewCard(5, "D"), 2)
 	t.PlayCard(card.NewCard(2, "H"), 3)
 	t.PlayCard(card.NewCard(13, "D"), 0)
@@ -99,26 +99,26 @@
 	p3 := player.NewPlayer(3)
 	players := []*player.Player{p0, p1, p2, p3}
 	t := table.NewTable(players)
-	t.SetFirst(1)
+	t.SetFirstPlayed(1)
 	t.PlayCard(card.NewCard(8, "H"), 1)
 	t.PlayCard(card.NewCard(12, "S"), 2)
 	t.PlayCard(card.NewCard(13, "S"), 3)
 	t.PlayCard(card.NewCard(8, "C"), 0)
 	t.SendTrick()
-	t.SetFirst(2)
+	t.SetFirstPlayed(2)
 	t.PlayCard(card.NewCard(5, "C"), 2)
 	t.PlayCard(card.NewCard(2, "C"), 3)
 	t.PlayCard(card.NewCard(13, "H"), 0)
 	t.PlayCard(card.NewCard(11, "S"), 1)
 	t.SendTrick()
 	t.EndRound()
-	t.SetFirst(3)
+	t.SetFirstPlayed(3)
 	t.PlayCard(card.NewCard(5, "S"), 3)
 	t.PlayCard(card.NewCard(6, "S"), 0)
 	t.PlayCard(card.NewCard(7, "S"), 1)
 	t.PlayCard(card.NewCard(10, "H"), 2)
 	t.SendTrick()
-	t.SetFirst(1)
+	t.SetFirstPlayed(1)
 	t.PlayCard(card.NewCard(6, "D"), 1)
 	t.PlayCard(card.NewCard(2, "C"), 2)
 	t.PlayCard(card.NewCard(13, "H"), 3)
@@ -212,3 +212,137 @@
 		test.Errorf("False positive")
 	}
 }
+
+//Testing playing a card-- HasAllPoints()
+func TestSeven(test *testing.T) {
+	p1 := player.NewPlayer(0)
+	p2 := player.NewPlayer(1)
+	p1.AddToHand(card.NewCard(6, "H"))
+	p1.AddToHand(card.NewCard(12, "S"))
+	p2.AddToHand(card.NewCard(2, "D"))
+	p2.AddToHand(card.NewCard(5, "H"))
+	if p1.HasAllPoints() == false {
+		test.Errorf("False negative")
+	}
+	if p2.HasAllPoints() == true {
+		test.Errorf("False positive")
+	}
+}
+
+//Testing playing a card-- ValidPlay() testing 2 of Clubs rule
+func TestEight(test *testing.T) {
+	p0 := player.NewPlayer(0)
+	players := []*player.Player{p0}
+	t := table.NewTable(players)
+	t.SetFirstPlayed(0)
+	if t.ValidPlay(card.NewCard(8, "C"), 0) == true {
+		test.Errorf("Expected invalid play for starting round with card other than 2 of Clubs")
+	} else if t.ValidPlay(card.NewCard(2, "C"), 0) == false {
+		test.Errorf("Expected valid play for starting round with 2 of Clubs")
+	}
+}
+
+//Testing playing a card-- ValidPlay() testing first round points rule
+func TestNine(test *testing.T) {
+	p0 := player.NewPlayer(0)
+	p1 := player.NewPlayer(1)
+	p1.AddToHand(card.NewCard(12, "S"))
+	p1.AddToHand(card.NewCard(3, "D"))
+	players := []*player.Player{p0, p1}
+	t := table.NewTable(players)
+	t.SetFirstPlayed(0)
+	t.PlayCard(card.NewCard(2, "C"), 0)
+	if t.ValidPlay(card.NewCard(12, "S"), 1) == true {
+		test.Errorf("Expected invalid play for points on the first round")
+	}
+}
+
+//Testing playing a card-- ValidPlay() testing breaking Hearts rule
+func TestTen(test *testing.T) {
+	p0 := player.NewPlayer(0)
+	p1 := player.NewPlayer(1)
+	p0.AddToHand(card.NewCard(5, "H"))
+	p1.AddToHand(card.NewCard(2, "H"))
+	p1.AddToHand(card.NewCard(3, "D"))
+	players := []*player.Player{p0, p1}
+	t := table.NewTable(players)
+	t.SetFirstPlayed(0)
+	t.PlayCard(card.NewCard(2, "C"), 0)
+	t.PlayCard(card.NewCard(3, "C"), 1)
+	t.SendTrick()
+	t.SetFirstPlayed(0)
+	if t.ValidPlay(card.NewCard(5, "H"), 0) == false {
+		test.Errorf("Expected valid play for opener rightfully breaking Hearts")
+	}
+	t.SetFirstPlayed(1)
+	if t.ValidPlay(card.NewCard(2, "H"), 1) == true {
+		test.Errorf("Expected invalid play for opener wrongfully breaking Hearts")
+	}
+	t.PlayCard(card.NewCard(3, "D"), 1)
+	if t.ValidPlay(card.NewCard(5, "H"), 0) == false {
+		test.Errorf("Expected valid play for follower rightfully breaking Hearts")
+	}
+	p0.AddToHand(card.NewCard(7, "D"))
+	if t.ValidPlay(card.NewCard(5, "H"), 0) == true {
+		test.Errorf("Expected invalid play for follower wrongfully breaking Hearts")
+	}
+}
+
+//Testing playing a card-- ValidPlay() testing following suit rule
+func TestEleven(test *testing.T) {
+	p0 := player.NewPlayer(0)
+	p1 := player.NewPlayer(1)
+	p0.AddToHand(card.NewCard(2, "C"))
+	p1.AddToHand(card.NewCard(3, "D"))
+	players := []*player.Player{p0, p1}
+	t := table.NewTable(players)
+	t.SetFirstPlayed(0)
+	t.PlayCard(card.NewCard(2, "C"), 0)
+	if t.ValidPlay(card.NewCard(3, "D"), 1) == false {
+		test.Errorf("Expected valid play for not following suit when player doesn't have suit")
+	}
+	p1.AddToHand(card.NewCard(5, "C"))
+	if t.ValidPlay(card.NewCard(5, "C"), 1) == false {
+		test.Errorf("Expected valid play for following suit")
+	}
+	if t.ValidPlay(card.NewCard(3, "D"), 1) == true {
+		test.Errorf("Expected invalid play for not following suit when player has suit")
+	}
+}
+
+//Testing win condition
+func TestTwelve(test *testing.T) {
+	p0 := player.NewPlayer(0)
+	players := []*player.Player{p0}
+	t := table.NewTable(players)
+	t.SetFirstPlayed(0)
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	winner := t.EndRound()
+	expect := -1
+	if winner != expect {
+		test.Errorf("Expected %d, got %d", expect, winner)
+	}
+	t.NewRound()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	t.PlayCard(card.NewCard(12, "S"), 0)
+	t.SendTrick()
+	winner = t.EndRound()
+	expect = 0
+	if winner != expect {
+		test.Errorf("Expected %d, got %d", expect, winner)
+	}
+}
diff --git a/go/src/sprites/player/player.go b/go/src/sprites/player/player.go
index 68d47fa..dee1739 100644
--- a/go/src/sprites/player/player.go
+++ b/go/src/sprites/player/player.go
@@ -32,6 +32,10 @@
 	return p.score
 }
 
+func (p *Player) GetPlayerIndex() int {
+	return p.playerIndex
+}
+
 func (p *Player) AddToHand(card *card.Card) {
 	p.hand = append(p.hand, card)
 }
@@ -68,3 +72,14 @@
 	}
 	return false
 }
+
+func (p *Player) HasAllPoints() bool {
+	for _, card := range p.hand {
+		if card.GetSuit() == "D" || card.GetSuit() == "C" {
+			return false
+		} else if card.GetSuit() == "S" && card.GetNum() != 12 {
+			return false
+		}
+	}
+	return true
+}
diff --git a/go/src/sprites/table/table.go b/go/src/sprites/table/table.go
index 62484bf..8816922 100644
--- a/go/src/sprites/table/table.go
+++ b/go/src/sprites/table/table.go
@@ -12,10 +12,13 @@
 
 func NewTable(p []*player.Player) *Table {
 	return &Table{
-		players:     p,
-		trick:       []*card.Card{nil, nil, nil, nil},
-		firstPlayed: -1,
-		allCards:    nil,
+		players:      p,
+		trick:        make([]*card.Card, len(p)),
+		firstPlayed:  -1,
+		allCards:     nil,
+		heartsBroken: false,
+		firstTrick:   true,
+		winCondition: 100,
 	}
 }
 
@@ -24,15 +27,18 @@
 	players []*player.Player
 	trick   []*card.Card
 	//firstPlayed is the index in trick of the card played first
-	firstPlayed int
-	allCards    []*card.Card
+	firstPlayed  int
+	allCards     []*card.Card
+	heartsBroken bool
+	firstTrick   bool
+	winCondition int
 }
 
 func (t *Table) GetPlayers() []*player.Player {
 	return t.players
 }
 
-func (t *Table) SetFirst(index int) {
+func (t *Table) SetFirstPlayed(index int) {
 	t.firstPlayed = index
 }
 
@@ -48,6 +54,36 @@
 
 func (t *Table) PlayCard(c *card.Card, playerIndex int) {
 	t.trick[playerIndex] = c
+	if c.GetSuit() == "H" && t.heartsBroken == false {
+		t.heartsBroken = true
+	}
+}
+
+func (t *Table) ValidPlay(c *card.Card, playerIndex int) bool {
+	player := t.players[playerIndex]
+	if t.firstPlayed == playerIndex {
+		if t.firstTrick == false {
+			if c.GetSuit() != "H" || t.heartsBroken == true {
+				return true
+			} else if player.HasSuit("C") == false && player.HasSuit("D") == false && player.HasSuit("S") == false {
+				return true
+			}
+		} else if c.GetSuit() == "C" && c.GetNum() == 2 {
+			return true
+		}
+	} else {
+		firstPlayedSuit := t.trick[t.firstPlayed].GetSuit()
+		if c.GetSuit() == firstPlayedSuit || player.HasSuit(firstPlayedSuit) == false {
+			if t.firstTrick == false {
+				return true
+			} else if c.GetSuit() == "D" || c.GetSuit() == "C" || (c.GetSuit() == "S" && c.GetNum() != 12) {
+				return true
+			} else if player.HasAllPoints() == true {
+				return true
+			}
+		}
+	}
+	return false
 }
 
 func (t *Table) SendTrick() {
@@ -63,9 +99,12 @@
 	}
 	//clear trick
 	t.players[highestIndex].TakeTrick(t.trick)
-	for i := 0; i < 4; i++ {
+	for i := 0; i < len(t.trick); i++ {
 		t.trick[i] = nil
 	}
+	if t.firstTrick == true {
+		t.firstTrick = false
+	}
 }
 
 func (t *Table) ScoreRound() {
@@ -106,9 +145,20 @@
 	}
 }
 
-func (t *Table) EndRound() {
+//returns -1 if the game hasn't been won, playerIndex of the winner if it has
+func (t *Table) EndRound() int {
 	t.ScoreRound()
 	for _, p := range t.players {
 		p.ResetTricks()
+		if p.GetScore() >= 100 {
+			return p.GetPlayerIndex()
+		}
 	}
+	return -1
+}
+
+func (t *Table) NewRound() {
+	t.heartsBroken = false
+	t.firstTrick = true
+	t.Deal()
 }