-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
153 lines (132 loc) · 3.55 KB
/
main.go
File metadata and controls
153 lines (132 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"./def"
"./player"
"./ticTacToe"
)
func main() {
consolereader := bufio.NewReader(os.Stdin)
board := ticTacToe.NewBoard(3)
for {
mode := showMenu(consolereader)
if mode == def.ModeQuit {
break
}
player1, player2 := generatePlayers(mode, board)
//game should never come here, if it comes here, there is a problem
if player1 == nil || player2 == nil {
fmt.Println("invalid players, please choose mode again..")
continue
}
for {
playGame(board, consolereader, player1, player2)
if checkPlayAgain(consolereader) {
//if player wants to play again, re-initialize the board, wiping it of its previous status
board.ReInit()
continue
}
break
}
board.ReInit()
}
fmt.Print("Thank you for playing!")
}
func generatePlayers(mode def.Mode, board *ticTacToe.Board) (player.Player, player.Player) {
var player1 player.Player
var player2 player.Player
switch mode {
case def.ModePlayerVsPlayer:
player1 = player.NewHumanPlayer("Player 1", def.Player1, board)
player2 = player.NewHumanPlayer("Player 2", def.Player2, board)
case def.ModePlayerVsAI:
player1 = player.NewHumanPlayer("Player", def.Player1, board)
player2 = player.NewAIPlayer("AI", def.Player2, board)
case def.ModeAIVsAI:
player1 = player.NewAIPlayer("AI1", def.Player1, board)
player2 = player.NewAIPlayer("AI2", def.Player2, board)
default:
player1 = nil
player2 = nil
}
return player1, player2
}
func playGame(board *ticTacToe.Board, consolereader *bufio.Reader, player1 player.Player, player2 player.Player) {
currentPlayer := player1
for !board.IsEndGame() {
//read the input from player.
// while the input is invalid, keep reading input and attempting to put that move
for {
input := currentPlayer.GetNextMove()
if !board.PlayerMove(currentPlayer.GetPlayerID(), input) {
fmt.Print("This slot is already taken..: ")
continue
}
break
}
//switch player
if currentPlayer == player1 {
currentPlayer = player2
} else {
currentPlayer = player1
}
}
fmt.Println(board)
if board.IsPlayer1Win() {
fmt.Println("Player 1 wins!")
} else if board.IsPlayer2Win() {
fmt.Println("Player 2 wins!")
} else if board.IsDraw() {
fmt.Println("Draw..")
}
}
func showMenu(consolereader *bufio.Reader) def.Mode {
fmt.Println(def.ModePlayerVsPlayer, "- Player vs Player")
fmt.Println(def.ModePlayerVsAI, "- Player vs AI")
fmt.Println(def.ModeAIVsAI, "- AI vs AI")
fmt.Println(def.ModeQuit, "- Quit Game")
fmt.Print("Please choose an option: ")
for {
inputString, err := consolereader.ReadString('\n')
if err != nil {
fmt.Print("Please enter a correct value1: ")
continue
}
inputString = strings.TrimSuffix(inputString, "\r\n")
inputInt, err := strconv.ParseInt(inputString, 10, 8)
if err != nil {
fmt.Print("Please enter a correct value2: ")
continue
}
inputUint8 := uint8(inputInt)
inputMode := def.Mode(inputUint8)
if inputMode <= def.ModeMin || inputMode > def.ModeMax {
fmt.Print("Invalid option, please input again: ")
continue
}
return inputMode
}
}
// Check if player wants to play again.
// Returns true if player wants to play again
func checkPlayAgain(consolereader *bufio.Reader) bool {
for {
fmt.Print("Play again? (Y/N): ")
input, err := consolereader.ReadString('\n')
if err != nil {
fmt.Print("Please enter a correct value: ")
continue
}
input = strings.TrimSuffix(input, "\r\n")
if input == "Y" || input == "y" {
return true
}
if input == "N" || input == "n" {
return false
}
}
}