Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
160
Task/Tic-tac-toe/Go/tic-tac-toe.go
Normal file
160
Task/Tic-tac-toe/Go/tic-tac-toe.go
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var b []byte
|
||||
|
||||
func printBoard() {
|
||||
fmt.Printf("%s\n%s\n%s\n", b[0:3], b[3:6], b[6:9])
|
||||
}
|
||||
|
||||
var pScore, cScore int
|
||||
var pMark, cMark byte = 'X', 'O'
|
||||
var in = bufio.NewReader(os.Stdin)
|
||||
|
||||
func main() {
|
||||
b = make([]byte, 9)
|
||||
fmt.Println("Play by entering a digit.")
|
||||
for {
|
||||
// start of game
|
||||
for i := range b {
|
||||
b[i] = '1' + byte(i)
|
||||
}
|
||||
computerStart := cMark == 'X'
|
||||
if computerStart {
|
||||
fmt.Println("I go first, playing X's")
|
||||
} else {
|
||||
fmt.Println("You go first, playing X's")
|
||||
}
|
||||
TakeTurns:
|
||||
for {
|
||||
if !computerStart {
|
||||
if !playerTurn() {
|
||||
return
|
||||
}
|
||||
if gameOver() {
|
||||
break TakeTurns
|
||||
}
|
||||
|
||||
}
|
||||
computerStart = false
|
||||
computerTurn()
|
||||
if gameOver() {
|
||||
break TakeTurns
|
||||
}
|
||||
}
|
||||
fmt.Println("Score: you", pScore, "me", cScore)
|
||||
fmt.Println("\nLet's play again.")
|
||||
}
|
||||
}
|
||||
|
||||
func playerTurn() bool {
|
||||
var pm string
|
||||
var err error
|
||||
for i := 0; i < 3; i++ { // retry loop
|
||||
printBoard()
|
||||
fmt.Printf("%c's move? ", pMark)
|
||||
if pm, err = in.ReadString('\n'); err != nil {
|
||||
fmt.Println(err)
|
||||
return false
|
||||
}
|
||||
pm = strings.TrimSpace(pm)
|
||||
if pm >= "1" && pm <= "9" && b[pm[0]-'1'] == pm[0] {
|
||||
x := pm[0] - '1'
|
||||
b[x] = pMark
|
||||
return true
|
||||
}
|
||||
}
|
||||
fmt.Println("You're not playing right.")
|
||||
return false
|
||||
}
|
||||
|
||||
var choices = make([]int, 9)
|
||||
|
||||
func computerTurn() {
|
||||
printBoard()
|
||||
var x int
|
||||
defer func() {
|
||||
fmt.Println("My move:", x+1)
|
||||
b[x] = cMark
|
||||
}()
|
||||
// look for two in a row
|
||||
block := -1
|
||||
for _, l := range lines {
|
||||
var mine, yours int
|
||||
x = -1
|
||||
for _, sq := range l {
|
||||
switch b[sq] {
|
||||
case cMark:
|
||||
mine++
|
||||
case pMark:
|
||||
yours++
|
||||
default:
|
||||
x = sq
|
||||
}
|
||||
}
|
||||
if mine == 2 && x >= 0 {
|
||||
return // strategy 1: make winning move
|
||||
}
|
||||
if yours == 2 && x >= 0 {
|
||||
block = x
|
||||
}
|
||||
}
|
||||
if block >= 0 {
|
||||
x = block // strategy 2: make blocking move
|
||||
return
|
||||
}
|
||||
// default strategy: random move
|
||||
choices = choices[:0]
|
||||
for i, sq := range b {
|
||||
if sq == '1'+byte(i) {
|
||||
choices = append(choices, i)
|
||||
}
|
||||
}
|
||||
x = choices[rand.Intn(len(choices))]
|
||||
}
|
||||
|
||||
func gameOver() bool {
|
||||
// check for win
|
||||
for _, l := range lines {
|
||||
if b[l[0]] == b[l[1]] && b[l[1]] == b[l[2]] {
|
||||
printBoard()
|
||||
if b[l[0]] == cMark {
|
||||
fmt.Println("I win!")
|
||||
cScore++
|
||||
pMark, cMark = 'X', 'O'
|
||||
} else {
|
||||
fmt.Println("You win!")
|
||||
pScore++
|
||||
pMark, cMark = 'O', 'X'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
// check for empty squares
|
||||
for i, sq := range b {
|
||||
if sq == '1'+byte(i) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
fmt.Println("Cat game.")
|
||||
pMark, cMark = cMark, pMark
|
||||
return true
|
||||
}
|
||||
|
||||
var lines = [][]int{
|
||||
{0, 1, 2}, // rows
|
||||
{3, 4, 5},
|
||||
{6, 7, 8},
|
||||
{0, 3, 6}, // columns
|
||||
{1, 4, 7},
|
||||
{2, 5, 8},
|
||||
{0, 4, 8}, // diagonals
|
||||
{2, 4, 6},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue