Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 25 additions & 20 deletions hw5/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import (
"errors"
)

type game struct{ grid *grid }
type game struct {
playerX *player
playerO *player
grid *grid
}

// Game constructor.
func NewGame() *game {
return &game{grid: NewGrid()}
func NewGame(playerX *player, playerO *player, grid *grid) *game {
return &game{playerX: playerX, playerO: playerO, grid: grid}
}

// Game constructor.

// Game methods.
func (g *game) Set(player *player, row int, col int) error {
if err := g.validateCoords(row, col); err != nil {
Expand Down Expand Up @@ -62,11 +67,11 @@ func (g *game) WhoWon() *player {
for _, cell := range row {
rowSum += cell.value
}
if rowSum == playerX.winningSumCols {
return playerX
if rowSum == g.playerX.winningSumCols {
return g.playerX
}
if rowSum == playerO.winningSumCols {
return playerO
if rowSum == g.playerO.winningSumCols {
return g.playerO
}
rowSum = 0
}
Expand All @@ -79,11 +84,11 @@ func (g *game) WhoWon() *player {
for r := 0; r < rows; r++ {
colSum += g.grid[r][c].value
}
if colSum == playerX.winningSumCols {
return playerX
if colSum == g.playerX.winningSumCols {
return g.playerX
}
if colSum == playerO.winningSumCols {
return playerO
if colSum == g.playerO.winningSumCols {
return g.playerO
}
colSum = 0
}
Expand All @@ -95,11 +100,11 @@ func (g *game) WhoWon() *player {
for c := 0; c < cols; c++ {
diag1Sum += g.grid[c][c].value
}
if diag1Sum == playerX.winningSumCols {
return playerX
if diag1Sum == g.playerX.winningSumCols {
return g.playerX
}
if diag1Sum == playerO.winningSumCols {
return playerO
if diag1Sum == g.playerO.winningSumCols {
return g.playerO
}

// Calculate win over second horizontal (right - left).
Expand All @@ -111,11 +116,11 @@ func (g *game) WhoWon() *player {
diag2Sum += g.grid[r][c].value
c++
}
if diag2Sum == playerX.winningSumCols {
return playerX
if diag2Sum == g.playerX.winningSumCols {
return g.playerX
}
if diag2Sum == playerO.winningSumCols {
return playerO
if diag2Sum == g.playerO.winningSumCols {
return g.playerO
}

return nil
Expand Down
95 changes: 53 additions & 42 deletions hw5/gameLoop.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ import (

type gameLoop struct {
game *game
score *map[string]int
player1 *player
player2 *player
currentTurnPlayer *player
}

func NewGameLoop(g *game) *gameLoop {
return &gameLoop{game: g}
func NewGameLoop(g *game, score *map[string]int) *gameLoop {
return &gameLoop{
game: g,
score: score,
}
}

func (l *gameLoop) run() {
Expand All @@ -26,61 +30,68 @@ func (l *gameLoop) run() {
}

func (l *gameLoop) makeMoves() {
var error string
scanner := bufio.NewScanner(os.Stdin)
for l.game.hasEmptyCells() {
// Clear screen.
l.clearScreen()

// Draw game grid.
l.drawGrid()

// Check if we have a winner.
if winner := l.game.WhoWon(); winner != nil {
// Exit loop if we have a winner.
if winner := l.weHaveAWinner(); winner != nil {
fmt.Println("The winner is player " + winner.name)

// Record the score.
_, ok := score[winner.name]
if !ok {
score[winner.name] = 1
} else {
score[winner.name]++
}

break
}

// Print error, if any.
if error != "" {
fmt.Println("Error: " + error)
// Get user input.
l.userInput()

// Pass turn to the other player.
if l.currentTurnPlayer == l.player1 {
l.currentTurnPlayer = l.player2
} else if l.currentTurnPlayer == l.player2 {
l.currentTurnPlayer = l.player1
}
}

}

fmt.Print("Player " + l.currentTurnPlayer.name + " choose your cell (row,col): ")
func (l *gameLoop) userInput() {
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("Player " + l.currentTurnPlayer.name + " choose your cell (row,col): ")
for {
scanner.Scan()

// Validate coordinates input.
row, col, isValid := l.validateCoordInput(scanner.Text())
if !isValid {
error = "Incorrect coordinates."
fmt.Println("Error: Incorrect coordinates.")
continue
} else {
error = ""
}

// Check that coordinates are valid (in bounds).
err := l.game.Set(l.currentTurnPlayer, row, col)
if err != nil {
error = err.Error()
fmt.Println("Error: " + err.Error())
continue
} else {
error = ""
}
break
}

// Pass turn to the other player.
if l.currentTurnPlayer == l.player1 {
l.currentTurnPlayer = l.player2
} else if l.currentTurnPlayer == l.player2 {
l.currentTurnPlayer = l.player1
}
func (l *gameLoop) weHaveAWinner() *player {

if winner := l.game.WhoWon(); winner != nil {
// Record the score.
_, ok := (*l.score)[winner.name]
if !ok {
(*l.score)[winner.name] = 1
} else {
(*l.score)[winner.name]++
}
return winner
}

return nil
}

func (l *gameLoop) gridHeader() string {
Expand All @@ -98,10 +109,10 @@ func (l *gameLoop) drawGrid() {
fmt.Printf(" %s |", strconv.Itoa(rowIndex))
for _, cell := range row {
switch cell.value {
case playerX.value:
fmt.Printf(" %s |", playerX.name)
case playerO.value:
fmt.Printf(" %s |", playerO.name)
case l.game.playerX.value:
fmt.Printf(" %s |", l.game.playerX.name)
case l.game.playerO.value:
fmt.Printf(" %s |", l.game.playerO.name)
default:
fmt.Printf(" %s |", " ")
}
Expand All @@ -115,16 +126,16 @@ func (l *gameLoop) choosePlayer1Side() {
name:
for {
l.clearScreen()
fmt.Printf("Player1 (%s) or (%s) ? ", playerX.name, playerO.name)
fmt.Printf("Player1 (%s) or (%s) ? ", l.game.playerX.name, l.game.playerO.name)
scanner.Scan()
switch scanner.Text() {
case playerX.name:
l.player1 = playerX
l.player2 = playerO
case l.game.playerX.name:
l.player1 = l.game.playerX
l.player2 = l.game.playerO
break name
case playerO.name:
l.player1 = playerO
l.player2 = playerX
case l.game.playerO.name:
l.player1 = l.game.playerO
l.player2 = l.game.playerX
break name
default:
continue
Expand Down
19 changes: 9 additions & 10 deletions hw5/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@ import (
"os"
)

var playerX *player
var playerO *player
var score map[string]int

func main() {
// Game sore and players.
score = make(map[string]int)
playerX = &player{value: 10, name: "X", winningSumCols: Edge * 10}
playerO = &player{value: 100, name: "O", winningSumCols: Edge * 100}
// Game sore.
score := make(map[string]int)

scanner := bufio.NewScanner(os.Stdin)

// Outer game loop.
for {
game := NewGame()
loop := NewGameLoop(game)
game := NewGame(
&player{value: 10, name: "X", winningSumCols: Edge * 10},
&player{value: 100, name: "O", winningSumCols: Edge * 100},
NewGrid(),
)
loop := NewGameLoop(game, &score)
loop.run()

// Print score and continue?
Expand Down